- 新增 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
94 lines
2.6 KiB
Python
94 lines
2.6 KiB
Python
import sys
|
||
from contextlib import asynccontextmanager
|
||
|
||
import uvicorn
|
||
from fastapi import FastAPI
|
||
from fastapi.middleware.cors import CORSMiddleware
|
||
from loguru import logger
|
||
|
||
from app.api import router as api_router
|
||
from app.config import settings
|
||
from app.database import check_database, engine
|
||
from app.dependencies import build_container
|
||
|
||
|
||
def configure_logging() -> None:
|
||
"""集中配置 loguru sink;由 create_app 显式调用,避免 import-time 副作用。"""
|
||
logger.remove()
|
||
logger.add(
|
||
sys.stderr,
|
||
format=(
|
||
"<green>{time:YYYY-MM-DD HH:mm:ss}</green> | "
|
||
"<level>{level: <8}</level> | "
|
||
"<cyan>{name}</cyan>:<cyan>{function}</cyan> - <level>{message}</level>"
|
||
),
|
||
)
|
||
|
||
|
||
@asynccontextmanager
|
||
async def lifespan(app: FastAPI):
|
||
await check_database()
|
||
logger.info(
|
||
"Database connection verified; ensure schema is applied with "
|
||
"`alembic upgrade head` before serving traffic"
|
||
)
|
||
container = build_container(settings)
|
||
app.state.container = container
|
||
await container.start()
|
||
try:
|
||
yield
|
||
finally:
|
||
await container.shutdown()
|
||
await engine.dispose()
|
||
logger.info("Database engine disposed")
|
||
|
||
|
||
def create_app() -> FastAPI:
|
||
configure_logging()
|
||
application = FastAPI(
|
||
title="Operation Room Monitor",
|
||
lifespan=lifespan,
|
||
)
|
||
if settings.demo_cors_enabled:
|
||
origins = settings.parsed_demo_cors_origins()
|
||
if origins:
|
||
application.add_middleware(
|
||
CORSMiddleware,
|
||
allow_origins=origins,
|
||
allow_credentials=origins != ["*"],
|
||
allow_methods=["*"],
|
||
allow_headers=["*"],
|
||
)
|
||
logger.info("CORS enabled for demo client; origins={}", origins)
|
||
application.include_router(api_router)
|
||
if settings.demo_orchestrator_enabled:
|
||
from app.routers import demo_orch
|
||
|
||
application.include_router(demo_orch.router)
|
||
logger.info(
|
||
"Demo orchestrator enabled: POST /internal/demo/orchestrate-and-start",
|
||
)
|
||
else:
|
||
logger.info(
|
||
"Demo orchestrator disabled (DEMO_ORCHESTRATOR_ENABLED=false): "
|
||
"GET /internal/demo/orchestrator-status for status; "
|
||
"POST /internal/demo/orchestrate-and-start is not registered",
|
||
)
|
||
return application
|
||
|
||
|
||
app = create_app()
|
||
|
||
|
||
def main() -> None:
|
||
uvicorn.run(
|
||
"main:app",
|
||
host=settings.server_host,
|
||
port=settings.server_port,
|
||
reload=False,
|
||
)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|