from fastapi import FastAPI from contextlib import asynccontextmanager from fastapi.middleware.gzip import GZipMiddleware from fastapi.middleware.cors import CORSMiddleware import logging from datetime import datetime import app.services.project_info as project_info from app.api.v1.router import api_router from app.infra.db.timescaledb.database import db as tsdb from app.infra.db.postgresql.database import db as pgdb from app.infra.db.dynamic_manager import project_connection_manager from app.infra.db.metadata.database import close_metadata_engine from app.services.tjnetwork import open_project from app.core.config import settings # 导入审计中间件 from app.infra.audit.middleware import AuditMiddleware logger = logging.getLogger() logger.setLevel(logging.INFO) @asynccontextmanager async def lifespan(app: FastAPI): logger.info("**********************************************************") logger.info(str(datetime.now())) logger.info("TJWater CloudService is starting...") logger.info("**********************************************************") # 初始化数据库连接池 tsdb.init_pool() pgdb.init_pool() await tsdb.open() await pgdb.open() # 将数据库实例存储到 app.state,供依赖项使用 app.state.db = pgdb logger.info("Database connection pool initialized and stored in app.state") if project_info.name: print(project_info.name) open_project(project_info.name) yield # 清理资源 await tsdb.close() await pgdb.close() await project_connection_manager.close_all() await close_metadata_engine() logger.info("Database connections closed") app = FastAPI( lifespan=lifespan, title=settings.PROJECT_NAME, description="TJWater Server - 供水管网智能管理系统", version="1.0.0", docs_url="/docs", redoc_url="/redoc", ) # 配置 CORS 中间件 app.add_middleware( CORSMiddleware, allow_origins=["*"], # 允许所有来源 allow_credentials=True, # 允许传递凭证(Cookie、HTTP 头等) allow_methods=["*"], # 允许所有 HTTP 方法 allow_headers=["*"], # 允许所有 HTTP 头 ) app.add_middleware(GZipMiddleware, minimum_size=1000) # 添加审计中间件(可选,记录关键操作) # 如果需要启用审计日志,取消下面的注释 app.add_middleware(AuditMiddleware) # Include Routers app.include_router(api_router, prefix="/api/v1") # Legcy Routers without version prefix app.include_router(api_router)