"""FastAPI 应用工厂。""" from __future__ import annotations import logging from collections.abc import AsyncIterator from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from src.core.config import settings @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncIterator[None]: from src.db.base import init_db from src.core.http_client import close_client await init_db() # 验证连接,不建表 yield await close_client() def create_app() -> FastAPI: app = FastAPI( title="Profeto API", description="足球数据 + LLM 预测服务", version="0.1.0", lifespan=lifespan, ) origins = [o.strip() for o in settings.CORS_ORIGINS.split(",") if o.strip()] methods = [m.strip() for m in settings.CORS_METHODS.split(",") if m.strip()] headers = [h.strip() for h in settings.CORS_HEADERS.split(",") if h.strip()] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=methods, allow_headers=headers, ) from src.api.routes.matches import router as matches_router from src.api.routes.predict import router as predict_router from src.api.routes.ingest import router as ingest_router from src.api.routes.eval import router as eval_router from src.api.routes.backtest import router as backtest_router app.include_router(matches_router) app.include_router(predict_router) app.include_router(ingest_router) app.include_router(eval_router) app.include_router(backtest_router) @app.get("/health") async def health(): return {"status": "healthy", "service": "profeto"} @app.get("/health/ready") async def health_ready(): """就绪检查: 验证数据库连接。""" from src.db.base import engine try: async with engine.begin() as conn: await conn.run_sync(lambda conn: None) return {"status": "ready"} except Exception: return {"status": "not_ready"} return app app = create_app()