feat: surgery pipeline API, video inference, voice confirm, and tests

- Add FastAPI routes for surgery start/end, results, pending confirmation (WAV upload), and health checks.
- Implement RTSP/Hikvision capture, consumable classification, session manager, MinIO/Baidu voice resolution, and DB persistence.
- Add documentation (client API, video backends, staging checklist) and sample camera/RTSP config.
- Add pytest suite (API contract, session manager, voice, repositories, pipeline persistence) and httpx dev dependency.
- Replace deprecated HTTP_422_UNPROCESSABLE_ENTITY with HTTP_422_UNPROCESSABLE_CONTENT.
- Fix SurgeryPipeline DB reads to use an explicit transaction with autobegin disabled.

Made-with: Cursor
This commit is contained in:
Kevin
2026-04-21 18:33:54 +08:00
parent d1a3d029ec
commit 04866559db
56 changed files with 7196 additions and 43 deletions

37
main.py
View File

@@ -3,11 +3,11 @@ from contextlib import asynccontextmanager
import uvicorn
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from loguru import logger
from sqlalchemy.exc import SQLAlchemyError
from app.database import check_database, engine
from app.api import router as api_router
from app.database import check_database, engine, init_db_schema
from app.dependencies import camera_session_manager
logger.remove()
logger.add(
@@ -19,37 +19,32 @@ logger.add(
@asynccontextmanager
async def lifespan(app: FastAPI):
await check_database()
logger.info("Database connection verified")
await init_db_schema()
logger.info("Database connection verified and schema ensured")
await camera_session_manager.start_archive_retry_loop()
yield
await camera_session_manager.shutdown()
await engine.dispose()
logger.info("Database engine disposed")
app = FastAPI(
title="Operation Room Monitor",
lifespan=lifespan,
)
def create_app() -> FastAPI:
application = FastAPI(
title="Operation Room Monitor",
lifespan=lifespan,
)
application.include_router(api_router)
return application
@app.get("/health")
async def health():
logger.debug("Health check")
try:
await check_database()
except SQLAlchemyError as exc:
logger.warning("Health check: database unavailable: {}", exc)
return JSONResponse(
status_code=503,
content={"status": "degraded", "database": "unavailable"},
)
return {"status": "ok", "database": "connected"}
app = create_app()
def main() -> None:
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8000,
port=38080,
reload=True,
)