2026-04-28 10:41:48 +08:00
|
|
|
|
import logging
|
2026-04-20 17:58:03 +08:00
|
|
|
|
import sys
|
|
|
|
|
|
from contextlib import asynccontextmanager
|
2026-04-28 10:41:48 +08:00
|
|
|
|
from pathlib import Path
|
2026-04-20 17:58:03 +08:00
|
|
|
|
|
|
|
|
|
|
import uvicorn
|
|
|
|
|
|
from fastapi import FastAPI
|
2026-04-22 17:00:56 +08:00
|
|
|
|
from fastapi.middleware.cors import CORSMiddleware
|
2026-04-20 17:58:03 +08:00
|
|
|
|
from loguru import logger
|
|
|
|
|
|
|
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
2026-04-21 18:33:54 +08:00
|
|
|
|
from app.api import router as api_router
|
2026-04-22 17:00:56 +08:00
|
|
|
|
from app.config import settings
|
2026-04-24 15:33:22 +08:00
|
|
|
|
from app.database import check_database, engine
|
2026-04-23 20:42:21 +08:00
|
|
|
|
from app.dependencies import build_container
|
2026-04-20 17:58:03 +08:00
|
|
|
|
|
2026-04-23 20:42:21 +08:00
|
|
|
|
|
2026-04-28 10:41:48 +08:00
|
|
|
|
def _configure_uvicorn_access_log_filters() -> None:
|
|
|
|
|
|
"""第三方或 Demo 若轮询 pending-confirmation,无条目时 404 为常态;压低 uvicorn access 刷屏。"""
|
|
|
|
|
|
|
|
|
|
|
|
class _SuppressPendingPoll404(logging.Filter):
|
|
|
|
|
|
def filter(self, record: logging.LogRecord) -> bool:
|
|
|
|
|
|
try:
|
|
|
|
|
|
msg = record.getMessage()
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
return True
|
|
|
|
|
|
if "/pending-confirmation" in msg and "GET" in msg and " 404 " in msg:
|
|
|
|
|
|
return False
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
logging.getLogger("uvicorn.access").addFilter(_SuppressPendingPoll404())
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-04-23 20:42:21 +08:00
|
|
|
|
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>"
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
2026-04-20 17:58:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@asynccontextmanager
|
|
|
|
|
|
async def lifespan(app: FastAPI):
|
|
|
|
|
|
await check_database()
|
2026-04-24 15:33:22 +08:00
|
|
|
|
logger.info(
|
|
|
|
|
|
"Database connection verified; ensure schema is applied with "
|
|
|
|
|
|
"`alembic upgrade head` before serving traffic"
|
|
|
|
|
|
)
|
2026-04-23 20:42:21 +08:00
|
|
|
|
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")
|
2026-04-20 17:58:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
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
2026-04-21 18:33:54 +08:00
|
|
|
|
def create_app() -> FastAPI:
|
2026-04-23 20:42:21 +08:00
|
|
|
|
configure_logging()
|
2026-04-28 10:41:48 +08:00
|
|
|
|
_configure_uvicorn_access_log_filters()
|
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
2026-04-21 18:33:54 +08:00
|
|
|
|
application = FastAPI(
|
|
|
|
|
|
title="Operation Room Monitor",
|
|
|
|
|
|
lifespan=lifespan,
|
|
|
|
|
|
)
|
2026-04-22 17:00:56 +08:00
|
|
|
|
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)
|
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
2026-04-21 18:33:54 +08:00
|
|
|
|
application.include_router(api_router)
|
2026-04-23 14:24:20 +08:00
|
|
|
|
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",
|
|
|
|
|
|
)
|
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
2026-04-21 18:33:54 +08:00
|
|
|
|
return application
|
2026-04-20 17:58:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
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
2026-04-21 18:33:54 +08:00
|
|
|
|
app = create_app()
|
2026-04-20 17:58:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main() -> None:
|
2026-04-28 10:41:48 +08:00
|
|
|
|
root = Path(__file__).resolve().parent
|
|
|
|
|
|
kwargs: dict = {
|
|
|
|
|
|
"host": settings.server_host,
|
|
|
|
|
|
"port": settings.server_port,
|
|
|
|
|
|
}
|
|
|
|
|
|
if settings.server_reload:
|
|
|
|
|
|
kwargs["reload"] = True
|
|
|
|
|
|
kwargs["reload_dirs"] = [str(root)]
|
|
|
|
|
|
kwargs["reload_includes"] = ["*.py"]
|
|
|
|
|
|
kwargs["reload_excludes"] = [
|
|
|
|
|
|
"**/.venv/**",
|
|
|
|
|
|
"**/__pycache__/**",
|
|
|
|
|
|
"**/web/**",
|
|
|
|
|
|
"**/scripts/demo_client/**",
|
|
|
|
|
|
"**/.git/**",
|
|
|
|
|
|
]
|
|
|
|
|
|
uvicorn.run("main:app", **kwargs)
|
2026-04-20 17:58:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
main()
|