feat: 配置写死与 baked 模块,Alembic 建表,百度仅 BAIDU_*
- 新增 app/baked/algorithm|pipeline,非部署参数不再走 env;Settings 保留 DB/HTTP/RTSP/海康/百度/MinIO/Demo - 移除 init_db_schema 与 reload 配置;main 仅 check_database;start*.sh 在 uvicorn 前执行 alembic upgrade head - 依赖 psycopg[binary] 供 Alembic 同步 URL;alembic/env 注释与预发清单更新 - 撕段门控消费管线、各视频/语音/归档调用改为 baked - 百度环境变量仅 BAIDU_APP_ID、BAIDU_API_KEY、BAIDU_SECRET_KEY 与 BAIDU_* 超时/ASR;人脸脚本与 baidu_speech 文案同步 - 全量单测与 .env.example 更新;.gitignore 忽略 refs/(本地权重/视频不入库) Made-with: Cursor
This commit is contained in:
@@ -10,7 +10,7 @@ from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from app.config import Settings
|
||||
from app.baked import pipeline as bp
|
||||
|
||||
_lock = threading.Lock()
|
||||
|
||||
@@ -28,8 +28,8 @@ def _encode_cell(value: str) -> str:
|
||||
return (value or "").replace("\r", " ").replace("\n", " ").replace("\t", " ")
|
||||
|
||||
|
||||
def _log_tz_info(settings: Settings) -> object:
|
||||
raw = (settings.consumption_log_timezone or "").strip()
|
||||
def _log_tz_info() -> object:
|
||||
raw = (bp.CONSUMPTION_LOG_TIMEZONE or "").strip()
|
||||
if not raw:
|
||||
lt = datetime.now().astimezone().tzinfo
|
||||
return lt if lt is not None else timezone.utc
|
||||
@@ -39,8 +39,8 @@ def _log_tz_info(settings: Settings) -> object:
|
||||
return timezone.utc
|
||||
|
||||
|
||||
def _ts_local_for_display(settings: Settings) -> str:
|
||||
tz = _log_tz_info(settings)
|
||||
def _ts_local_for_display() -> str:
|
||||
tz = _log_tz_info()
|
||||
return datetime.now(tz).isoformat(timespec="milliseconds")
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ def _safe_surgery_path_segment(surgery_id: str) -> str:
|
||||
return s[:200] if len(s) > 200 else s
|
||||
|
||||
|
||||
def resolved_voice_log_path(surgery_id: str, settings: Settings) -> Path:
|
||||
raw = (settings.voice_file_log_path or "logs/voice_{surgery_id}.txt").strip()
|
||||
def resolved_voice_log_path(surgery_id: str) -> Path:
|
||||
raw = (bp.VOICE_FILE_LOG_PATH or "logs/voice_{surgery_id}.txt").strip()
|
||||
safe = _safe_surgery_path_segment(surgery_id)
|
||||
if "{surgery_id}" in raw:
|
||||
raw = raw.replace("{surgery_id}", safe)
|
||||
@@ -67,21 +67,21 @@ def resolved_voice_log_path(surgery_id: str, settings: Settings) -> Path:
|
||||
return p
|
||||
|
||||
|
||||
def init_voice_log_file(surgery_id: str, settings: Settings) -> None:
|
||||
def init_voice_log_file(surgery_id: str) -> None:
|
||||
"""与 `init_consumption_log_file` 同生命周期:`start_surgery` 时截断并写表头。"""
|
||||
if not settings.voice_file_log_enabled:
|
||||
if not bp.VOICE_FILE_LOG_ENABLED:
|
||||
return
|
||||
path = resolved_voice_log_path(surgery_id, settings)
|
||||
path = resolved_voice_log_path(surgery_id)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with _lock:
|
||||
with path.open("w", encoding="utf-8") as f:
|
||||
f.write(HEADER)
|
||||
|
||||
|
||||
def append_voice_tsv_line(surgery_id: str, line: str, settings: Settings) -> None:
|
||||
if not settings.voice_file_log_enabled:
|
||||
def append_voice_tsv_line(surgery_id: str, line: str) -> None:
|
||||
if not bp.VOICE_FILE_LOG_ENABLED:
|
||||
return
|
||||
path = resolved_voice_log_path(surgery_id, settings)
|
||||
path = resolved_voice_log_path(surgery_id)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with _lock:
|
||||
with path.open("a", encoding="utf-8") as f:
|
||||
@@ -89,16 +89,13 @@ def append_voice_tsv_line(surgery_id: str, line: str, settings: Settings) -> Non
|
||||
|
||||
|
||||
class VoiceTextLogWriter:
|
||||
"""注入式 voice 日志写入器,封装 `init_file` / `emit_event`。
|
||||
"""注入式 voice 日志写入器,封装 `init_file` / `emit_event`。"""
|
||||
|
||||
行为等价于模块级函数;保留模块级函数以兼容既有调用点。
|
||||
"""
|
||||
|
||||
def __init__(self, app_settings: Settings) -> None:
|
||||
self._s = app_settings
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
|
||||
def init_file(self, surgery_id: str) -> None:
|
||||
init_voice_log_file(surgery_id, self._s)
|
||||
init_voice_log_file(surgery_id)
|
||||
|
||||
def emit_event(
|
||||
self,
|
||||
@@ -114,7 +111,6 @@ class VoiceTextLogWriter:
|
||||
audio_object_key: str | None = None,
|
||||
) -> None:
|
||||
emit_voice_event(
|
||||
self._s,
|
||||
surgery_id=surgery_id,
|
||||
source=source,
|
||||
status=status,
|
||||
@@ -128,7 +124,6 @@ class VoiceTextLogWriter:
|
||||
|
||||
|
||||
def emit_voice_event(
|
||||
settings: Settings,
|
||||
*,
|
||||
surgery_id: str,
|
||||
source: str,
|
||||
@@ -140,12 +135,6 @@ def emit_voice_event(
|
||||
error_message: str | None = None,
|
||||
audio_object_key: str | None = None,
|
||||
) -> None:
|
||||
"""
|
||||
终端:单条可 grep 的 VoiceConfirm 行;文件:TSV 一行(与启用的 `voice_file_log_enabled` 一致)。
|
||||
|
||||
:param source: `wav` | `text` | `n/a`
|
||||
:param status: 与审计 `status` 或 `minio_not_configured` 等说明型状态一致
|
||||
"""
|
||||
rj: str
|
||||
if rejected is None:
|
||||
rj = ""
|
||||
@@ -155,7 +144,7 @@ def emit_voice_event(
|
||||
rj = str(rejected)
|
||||
|
||||
ts_utc = _ts_iso_utc()
|
||||
local_hint = _ts_local_for_display(settings)
|
||||
local_hint = _ts_local_for_display()
|
||||
if status in ("recognized", "rejected"):
|
||||
logger.info(
|
||||
"VoiceConfirm local_ts={!r} surgery_id={} source={} status={} "
|
||||
@@ -189,7 +178,7 @@ def emit_voice_event(
|
||||
audio_object_key,
|
||||
)
|
||||
|
||||
if not settings.voice_file_log_enabled:
|
||||
if not bp.VOICE_FILE_LOG_ENABLED:
|
||||
return
|
||||
row = [
|
||||
_encode_cell(ts_utc),
|
||||
@@ -203,4 +192,4 @@ def emit_voice_event(
|
||||
_encode_cell("" if audio_object_key is None else audio_object_key),
|
||||
]
|
||||
line = "\t".join(row) + "\n"
|
||||
append_voice_tsv_line(surgery_id, line, settings)
|
||||
append_voice_tsv_line(surgery_id, line)
|
||||
|
||||
Reference in New Issue
Block a user