""" FastAPI 应用主文件 """ import time from fastapi import FastAPI, Request, status from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from fastapi.exceptions import RequestValidationError from contextlib import asynccontextmanager from app.core.config import settings from app.core.response import error_response from app.core.exceptions import BaseAPIException from app.utils.logger import logger from app.utils.monitor import api_monitor from app.api.common.routes import router as common_router from app.api.v1.inventory.routes import router as inventory_router from app.api.v1.value.routes import router as value_router from app.api.v1.delivery.routes import router as delivery_router @asynccontextmanager async def lifespan(app: FastAPI): """应用生命周期管理""" # 启动时执行 logger.info("=" * 50) logger.info(f"{settings.APP_NAME} 启动中...") logger.info(f"版本: {settings.APP_VERSION}") logger.info(f"调试模式: {settings.DEBUG}") logger.info(f"环境变量: HOST={settings.HOST}, PORT={settings.PORT}") logger.info("=" * 50) yield # 关闭时执行 logger.info(f"{settings.APP_NAME} 关闭中...") # 创建 FastAPI 应用 app = FastAPI( title=settings.APP_NAME, version=settings.APP_VERSION, description="数据资产盘点系统后端 API 服务", docs_url="/docs", redoc_url="/redoc", openapi_url="/openapi.json", lifespan=lifespan, ) # 配置 CORS app.add_middleware( CORSMiddleware, allow_origins=settings.CORS_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # 添加监控中间件 @app.middleware("http") async def monitoring_middleware(request: Request, call_next): """ 监控中间件 - 记录所有 API 调用 Args: request: 请求对象 call_next: 下一个中间件/路由处理器 Returns: 响应对象 """ start_time = time.time() endpoint = request.url.path method = request.method try: # 调用下一个中间件/路由处理器 response = await call_next(request) # 计算响应时间 response_time = (time.time() - start_time) * 1000 # 转换为毫秒 # 记录调用 api_monitor.record_call( endpoint=endpoint, method=method, status_code=response.status_code, response_time=response_time, error=None ) return response except Exception as e: # 计算响应时间 response_time = (time.time() - start_time) * 1000 # 记录调用(异常) api_monitor.record_call( endpoint=endpoint, method=method, status_code=500, response_time=response_time, error=str(e) ) # 重新抛出异常,让全局异常处理器处理 raise # 注册路由 app.include_router(common_router, prefix=settings.API_V1_PREFIX) app.include_router(inventory_router, prefix=settings.API_V1_PREFIX) app.include_router(value_router, prefix=settings.API_V1_PREFIX) app.include_router(delivery_router, prefix=settings.API_V1_PREFIX) # 异常处理器 @app.exception_handler(BaseAPIException) async def base_api_exception_handler(request: Request, exc: BaseAPIException): """自定义 API 异常处理""" logger.error(f"API 异常: {exc.message} | {exc.error_code}") return JSONResponse( status_code=exc.status_code, content=error_response( message=exc.message, code=exc.status_code, error_code=exc.error_code, error_detail=exc.error_detail, ).dict(), ) @app.exception_handler(RequestValidationError) async def validation_exception_handler(request: Request, exc: RequestValidationError): """请求验证异常处理""" logger.error(f"请求验证失败: {exc.errors()}") return JSONResponse( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content=error_response( message="请求参数验证失败", code=status.HTTP_422_UNPROCESSABLE_ENTITY, error_code="VALIDATION_ERROR", error_detail=exc.errors(), ).dict(), ) @app.exception_handler(Exception) async def general_exception_handler(request: Request, exc: Exception): """通用异常处理""" logger.exception(f"未处理的异常: {str(exc)}") return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content=error_response( message="服务器内部错误", code=status.HTTP_500_INTERNAL_SERVER_ERROR, error_code="INTERNAL_SERVER_ERROR", error_detail=str(exc) if settings.DEBUG else None, ).dict(), ) if __name__ == "__main__": import uvicorn uvicorn.run( "app.main:app", host=settings.HOST, port=settings.PORT, reload=settings.DEBUG, log_level=settings.LOG_LEVEL.lower(), )