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:
160
.env.example
160
.env.example
@@ -1,5 +1,7 @@
|
||||
# Copy to `.env` and adjust. Loaded by pydantic-settings (field names → UPPER_SNAKE_CASE env vars).
|
||||
# Used by local `start.sh` and Docker Compose. See also docs/video-backends.md.
|
||||
# 复制为 `.env` 并按环境填写。pydantic-settings 将字段名映射为大写下划线环境变量。
|
||||
# 启动前须执行 `alembic upgrade head`(`start.sh` / `start_fresh.sh` 已包含)。
|
||||
# 算法、管线、归档路径、视觉/语音日志等非部署项见 `app/baked/algorithm.py` 与 `app/baked/pipeline.py`。
|
||||
# 详细说明见 docs/video-backends.md。
|
||||
|
||||
# --- PostgreSQL ---
|
||||
POSTGRES_USER=postgres
|
||||
@@ -7,165 +9,53 @@ POSTGRES_PASSWORD=postgres
|
||||
POSTGRES_DB=operation_room
|
||||
POSTGRES_HOST=localhost
|
||||
POSTGRES_PORT=35432
|
||||
|
||||
# Optional: full async SQLAlchemy URL (overrides POSTGRES_* when set and matches defaults logic — see Settings).
|
||||
# 可选:整串 async DSN(会覆盖与默认一致的 POSTGRES_* 组合时的逻辑,见 Settings)
|
||||
# DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:35432/operation_room
|
||||
|
||||
# 开发/首次部署:启动时执行 Base.metadata.create_all 确保表存在(默认 true)。
|
||||
# 生产请置 false,并通过 `alembic upgrade head` 应用迁移(见 alembic/ 目录)。
|
||||
# AUTO_CREATE_SCHEMA=true
|
||||
|
||||
# --- Uvicorn / API server ---
|
||||
# --- HTTP(python -m main / 容器等入口)---
|
||||
# SERVER_HOST=0.0.0.0
|
||||
# SERVER_PORT=38080
|
||||
# 生产必须 false;本地开发调试可改 true(等价于旧版 reload=True)。
|
||||
# SERVER_RELOAD=false
|
||||
|
||||
# --- YOLO 视觉推理(内部调用,无独立 HTTP)---
|
||||
# 耗材分类权重默认 app/resources/consumable_classifier.pt;手部检测为空时退化为全帧分类。
|
||||
# CONSUMABLE_CLASSIFIER_WEIGHTS=/absolute/path/to/consumable_classifier.pt
|
||||
CONSUMABLE_CLASSIFIER_IMGSZ=224
|
||||
CONSUMABLE_CLASSIFIER_DEVICE=
|
||||
# 视觉待确认 options 最多为模型 top3 与 candidate_consumables 的交集(非本变量)。
|
||||
CONSUMABLE_CLASSIFIER_TOPK=5
|
||||
# CONSUMABLE_MIN_CLS_CONFIDENCE=0.5
|
||||
# 时间窗(秒):窗内多次推理取众数后再走自动记账 / 待确认。
|
||||
# CONSUMABLE_VISION_WINDOW_SEC=15
|
||||
# 业务物品 id 与开录时「空 candidate」的类名全表:app/resources/consumable_classifier_labels.yaml(names + label_id;同名多规格为 id1/id2/...)。未设或空则默认该包内文件。
|
||||
# CONSUMABLE_CLASSIFIER_LABELS_YAML_PATH=/app/app/resources/consumable_classifier_labels.yaml
|
||||
# HAND_DETECTION_WEIGHTS=/absolute/path/to/hand_detect.pt
|
||||
# HAND_DETECTION_IMGSZ=640
|
||||
# HAND_DETECTION_CONF=0.25
|
||||
# HAND_DETECTION_PAD_RATIO=0.30
|
||||
# HAND_DETECTION_MIN_CROP_PX=64
|
||||
# HAND_DETECTION_DEVICE=
|
||||
# Device: empty → auto (macOS MPS if available; Linux CUDA if available). Docker image uses CPU torch unless you change it.
|
||||
|
||||
# --- Surgery recording API retries ---
|
||||
# SURGERY_RECORDING_MAX_ATTEMPTS=3
|
||||
# SURGERY_RECORDING_RETRY_DELAY_SECONDS=1.0
|
||||
|
||||
# --- Video: RTSP + optional Hikvision HCNetSDK (Linux x86_64 + glibc recommended) ---
|
||||
# Client `camera_ids` must match keys in your RTSP map (sample IDs: or-cam-01, or-cam-02).
|
||||
#
|
||||
# --- Video:RTSP 与按路后端(须与客户端 camera_ids 一致)---
|
||||
# VIDEO_DEFAULT_BACKEND=rtsp
|
||||
# Values: rtsp | hikvision_sdk | auto (auto: SDK .so loaded and HIKVISION_SDK_ENABLED=true → prefer SDK)
|
||||
#
|
||||
# Per-camera backend override (JSON object):
|
||||
# VIDEO_CAMERA_BACKEND_OVERRIDES_JSON={"or-cam-01":"rtsp","or-cam-02":"hikvision_sdk"}
|
||||
#
|
||||
# RTSP URL resolution (first match wins per camera_id):
|
||||
# 1) VIDEO_RTSP_URLS_JSON_FILE — JSON file: {"or-cam-01":"rtsp://...","or-cam-02":"rtsp://..."}
|
||||
# 2) merged with VIDEO_RTSP_URLS_JSON (inline JSON string; overrides same keys from file)
|
||||
# 3) else VIDEO_RTSP_URL_TEMPLATE with {camera_id}
|
||||
# Example file (committed): app/resources/camera_rtsp_urls.sample.json
|
||||
# VIDEO_RTSP_URLS_JSON_FILE=app/resources/camera_rtsp_urls.sample.json
|
||||
# In Docker (WORKDIR /app): VIDEO_RTSP_URLS_JSON_FILE=/app/app/resources/camera_rtsp_urls.sample.json
|
||||
# WARNING: if VIDEO_RTSP_URLS_JSON_FILE is set but the path is missing, the app will fail to start.
|
||||
#
|
||||
# VIDEO_RTSP_URL_TEMPLATE=rtsp://user:pass@192.168.1.64:554/Streaming/Channels/101
|
||||
# VIDEO_RTSP_URLS_JSON={"or-cam-01":"rtsp://user:pass@192.168.1.101:554/Streaming/Channels/101","or-cam-02":"rtsp://user:pass@192.168.1.102:554/Streaming/Channels/101"}
|
||||
#
|
||||
# VIDEO_OPEN_TIMEOUT_SEC=15
|
||||
# 连续读帧失败次数达到阈值后释放 RTSP 并重连。
|
||||
# VIDEO_READ_FAILURE_RECONNECT_THRESHOLD=15
|
||||
# VIDEO_RECONNECT_BACKOFF_SECONDS=1.0
|
||||
# VIDEO_INFERENCE_INTERVAL_SEC=2
|
||||
# VIDEO_INFERENCE_CONFIDENCE_THRESHOLD=0.35
|
||||
# 置信度 >= 此值且命中候选清单时自动 vision 记账。提高到 0.9 可减少自动记账、更多走待确认。
|
||||
# 默认 0.9:Top1 置信度不足该值时入队待确认;达到且标签在 candidate_consumables 内则直接记 vision。
|
||||
# VIDEO_AUTO_CONFIRM_CONFIDENCE=0.9
|
||||
# 与 VIDEO_VOICE_CONFIRM_MIN_CONFIDENCE 共同决定何时自动 / 待确认(见 app/config 注释)。
|
||||
# VIDEO_VOICE_CONFIRM_MIN_CONFIDENCE=0.35
|
||||
# 待确认话术由服务端生成(prompt_text),TTS 一般在客户端播放;医生 WAV 上传后服务端 ASR 解析。
|
||||
# 解析顺序:① pending 里展示的 topk(序号/名称);② 仍不匹配时,对「开始手术」请求体中的 candidate_consumables 全文做名称子串匹配——医生报清单内其它耗材也以医生为准入账。
|
||||
# 是否启用低置信度人工确认(客户端播报 + resolve 回传;服务端无麦克风/扬声器要求)。
|
||||
# VOICE_CONFIRMATION_ENABLED=true
|
||||
# 同一条待确认在语音/文本「解析失败」时累计的允许失败轮次(默认 2:首败后再给 1 次重试提示;见 422 的 detail.retry_remaining)。
|
||||
# VOICE_CONFIRM_MAX_FAILED_PARSE_ROUNDS=2
|
||||
# VIDEO_VOICE_CONFIRM_DOCTOR_ID=voice
|
||||
# (已弃用)服务端本机录音 / ffmpeg 音频输入;当前闭环不依赖。
|
||||
# VOICE_RECORD_SECONDS=5
|
||||
# VOICE_FFMPEG_INPUT=
|
||||
# 停录后写库失败时,后台重试落库间隔(秒)。
|
||||
# ARCHIVE_PERSIST_RETRY_INTERVAL_SECONDS=30
|
||||
# VIDEO_DETAIL_COOLDOWN_SEC=15
|
||||
# VIDEO_JPEG_QUALITY=85
|
||||
# VIDEO_RESULT_DOCTOR_ID=vision
|
||||
# 每次单帧分类得到 top1~3 时打一条 INFO(联调开;生产建议 false)
|
||||
# VIDEO_LOG_INFERENCE_RESULTS=true
|
||||
# 时间窗级消耗文本日志(制表符列;每例手术 start 时截断+表头,窗内结果追加;终端 Rich 为可读时间戳,文件内为 ISO 时间戳列)
|
||||
# CONSUMPTION_TSV_LOG_ENABLED=true
|
||||
# 须含 {surgery_id},如 logs/consumption_{surgery_id}.txt
|
||||
# CONSUMPTION_TSV_LOG_PATH=logs/consumption_{surgery_id}.txt
|
||||
# 同一时间窗结果在终端以 Markdown 表格打印(Top1~3 分列 id / 名称 / 置信度)
|
||||
# CONSUMPTION_LOG_MARKDOWN_TERMINAL=true
|
||||
# 消耗日志时间戳列的时区(IANA,如 Asia/Shanghai);不设置则用运行环境的系统时区
|
||||
# CONSUMPTION_LOG_TIMEZONE=Asia/Shanghai
|
||||
#
|
||||
# 语音确认:stderr 中可 grep 的 `VoiceConfirm ...` 行 + 每例手术 TSV(与 `start_surgery` 同次截断写表头;成功/ASR/解析失败均追加一行)
|
||||
# VOICE_FILE_LOG_ENABLED=true
|
||||
# 须含 {surgery_id},如 logs/voice_{surgery_id}.txt
|
||||
# VOICE_FILE_LOG_PATH=logs/voice_{surgery_id}.txt
|
||||
# VIDEO_RTSP_URLS_JSON={"or-cam-01":"rtsp://..."}
|
||||
# VIDEO_RTSP_URL_TEMPLATE=rtsp://user:pass@host:554/path/{camera_id}
|
||||
|
||||
# --- Hikvision: mount vendor Linux x86_64 .so at runtime (do not commit proprietary binaries) ---
|
||||
# --- 海康 SDK(Linux x86_64;二进制勿提交仓库)---
|
||||
# HIKVISION_LIB_DIR=/opt/hikvision/lib
|
||||
# Optional: single library path (overrides directory search in code)
|
||||
# 可选:单一路径,见 app/services/video/hikvision_runtime.py 直读 HIKVISION_LIB_PATH
|
||||
# HIKVISION_LIB_PATH=
|
||||
# HIKVISION_SDK_ENABLED=false
|
||||
# HIKVISION_DEVICE_IP=
|
||||
# HIKVISION_DEVICE_PORT=8000
|
||||
# HIKVISION_USER=
|
||||
# HIKVISION_PASSWORD=
|
||||
# HIKVISION_CHANNEL=1
|
||||
# After SDK login, OpenCV still pulls frames via RTSP; template placeholders: {ip} {user} {password} {channel} {camera_id}
|
||||
# HIKVISION_PREVIEW_RTSP_TEMPLATE=rtsp://{user}:{password}@{ip}:554/Streaming/Channels/101
|
||||
# Per-camera RTSP when using SDK path (same shape as VIDEO_RTSP_URLS_JSON):
|
||||
# HIKVISION_CAMERA_RTSP_URLS_JSON={"or-cam-01":"rtsp://...","or-cam-02":"rtsp://..."}
|
||||
# HIKVISION_CAMERA_RTSP_URLS_JSON={}
|
||||
# HIKVISION_SDK_FALLBACK_TO_RTSP=true
|
||||
|
||||
# --- Baidu Speech(可选,遗留;当前手术闭环由客户端完成 TTS/ASR,服务端可不配置)---
|
||||
# BAIDU_SPEECH_APP_ID=
|
||||
# BAIDU_SPEECH_API_KEY=
|
||||
# BAIDU_SPEECH_SECRET_KEY=
|
||||
# BAIDU_SPEECH_CONNECTION_TIMEOUT_MS=
|
||||
# BAIDU_SPEECH_SOCKET_TIMEOUT_MS=
|
||||
# 短语音识别模型:固定普通话(默认 1537;勿用 1737 英语等)。代码会始终带上此 dev_pid。
|
||||
# BAIDU_SPEECH_ASR_DEV_PID=1537
|
||||
# --- 百度(语音:短语音识别 AipSpeech + 在线合成;控制台开通对应能力)---
|
||||
# BAIDU_APP_ID=
|
||||
# BAIDU_API_KEY=
|
||||
# BAIDU_SECRET_KEY=
|
||||
# 可选
|
||||
# BAIDU_CONNECTION_TIMEOUT_MS=
|
||||
# BAIDU_SOCKET_TIMEOUT_MS=
|
||||
# BAIDU_ASR_DEV_PID=1537
|
||||
|
||||
# --- Baidu Face(可选;仅 `scripts/baidu_face_1n_search.py` 批量人脸 1:N 搜索;需在控制台创建应用并开通人脸识别)---
|
||||
# BAIDU_FACE_APP_ID=
|
||||
# BAIDU_FACE_API_KEY=
|
||||
# BAIDU_FACE_SECRET_KEY=
|
||||
# 搜索的人脸组 id,逗号分隔,最多 10 个;未传命令行 --groups 时使用此项
|
||||
# 仅允许英文/数字/下划线(与控制台「用户组 id」一致),不能中文;否则 API 会报 222005
|
||||
# BAIDU_FACE_GROUP_ID_LIST=my_group_1
|
||||
# BAIDU_FACE_MAX_USER_NUM=1
|
||||
# BAIDU_FACE_MATCH_THRESHOLD=80
|
||||
# BAIDU_FACE_QUALITY_CONTROL=NONE
|
||||
# BAIDU_FACE_LIVENESS_CONTROL=NONE
|
||||
# BAIDU_FACE_CONNECTION_TIMEOUT_MS=
|
||||
# BAIDU_FACE_SOCKET_TIMEOUT_MS=
|
||||
|
||||
# --- MinIO(语音 WAV 存桶;`docker-compose.dev.yml` 内已含 `minio` 服务;本机只跑 API 时填 127.0.0.1:9000)---
|
||||
# docker compose -f docker-compose.dev.yml up -d minio
|
||||
# --- MinIO(语音 WAV)---
|
||||
# MINIO_ENDPOINT=127.0.0.1:9000
|
||||
# MINIO_ACCESS_KEY=minioadmin
|
||||
# MINIO_SECRET_KEY=minioadmin
|
||||
# MINIO_ACCESS_KEY=
|
||||
# MINIO_SECRET_KEY=
|
||||
# MINIO_BUCKET=operation-room-voice
|
||||
# MINIO_SECURE=false
|
||||
# optional: MINIO_REGION=
|
||||
# MINIO_REGION=
|
||||
|
||||
# --- Demo 浏览器客户端 / 一键联调假 RTSP(仅开发;生产关)---
|
||||
# demo_client/index.html 跨源访问本服务 / 一键开录
|
||||
# --- Demo 客户端 / 一键联调(生产关闭)---
|
||||
# DEMO_CORS_ENABLED=true
|
||||
# DEMO_CORS_ORIGINS=*
|
||||
# 为 true 时提供 POST /internal/demo/orchestrate-and-start;需能执行 docker+ffmpeg 的**同一进程**内起 MediaMTX(通常=在宿主机直接跑 main.py,或容器挂载 /var/run/docker.sock)
|
||||
# DEMO_ORCHESTRATOR_ENABLED=false
|
||||
# VIDEO_RTSP_URLS_JSON_FILE 必须设成**可写**的 JSON 文件;Docker 中请 bind-mount 宿主机文件,与一键覆盖写入的映射一致
|
||||
# DEMO_ORCHESTRATOR_RTSP_PORT=18554
|
||||
# 手配假流、只改 JSON 给「另一进程」用时:可把 127.0.0.1 换成 host.docker.internal 等。
|
||||
# 一键联调 orchestrate-and-start 在本进程起流+拉流,固定写 127.0.0.1,不读此项。
|
||||
# DEMO_ORCHESTRATOR_RTSP_JSON_HOST=host.docker.internal
|
||||
# 一键起 MediaMTX 后,等待本机 RTSP 端口可连接的最长时间(秒)
|
||||
# MEDIAMTX_TCP_READY_SEC=30
|
||||
|
||||
Reference in New Issue
Block a user