"""FastAPI application entrypoint.""" from contextlib import asynccontextmanager from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from loguru import logger from app.api.models import ErrorResponse from app.api.routes import api_router from app.config.logging import setup_logging from app.config.settings import settings from app.shared.bootstrap import cleanup_runtime_dependencies, preload_runtime_dependencies # Keep module behavior explicit so the backend flow stays easy to audit. setup_logging(level="INFO" if not settings.debug else "DEBUG") @asynccontextmanager async def lifespan(app: FastAPI): """Application lifecycle hooks.""" logger.info(f"启动 {settings.app_name} v{settings.app_version}") logger.info(f"调试模式: {settings.debug}") logger.info("预加载LLM客户端...") preload_runtime_dependencies() yield logger.info("应用关闭,执行清理...") cleanup_runtime_dependencies() app = FastAPI( title=settings.app_name, description=( "AI+合规智能中枢 - 法律法规文档解析入库功能\n\n" "支持PDF/DOCX文档解析、智能分块、向量嵌入、Milvus存储" ), version=settings.app_version, lifespan=lifespan, docs_url="/docs", redoc_url="/redoc", ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(api_router, prefix="/api/v1") @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): """Global exception handler.""" logger.error(f"未处理的异常: {exc}") return JSONResponse( status_code=500, content=ErrorResponse( error="InternalServerError", message=str(exc), ).model_dump(), ) @app.get("/health", tags=["health"]) async def health_check(): """Health check endpoint.""" return { "status": "healthy", "app": settings.app_name, "version": settings.app_version, } @app.get("/", tags=["root"]) async def root(): """Root endpoint.""" return { "message": f"Welcome to {settings.app_name}", "version": settings.app_version, "docs": "/docs", "health": "/health", } if __name__ == "__main__": import uvicorn uvicorn.run( "app.api.main:app", host=settings.api_host, port=settings.api_port, reload=settings.debug, log_level="info", )