from fastapi import FastAPI, Depends, Request from fastapi.responses import JSONResponse from fastapi.middleware.cors import CORSMiddleware from fastapi.openapi.utils import get_openapi from fastapi.security import HTTPBearer from app.api import router from app.core.auth import RoleLevel, require_min_role from app.core.config import settings from app.core.payment import init_stripe from app.core.biz_exception import BizException from app.core.logger import logger app = FastAPI(title=settings.app_name) @app.on_event("startup") def startup(): init_stripe() @app.exception_handler(BizException) async def biz_exception_handler(request: Request, exc: BizException): return JSONResponse( status_code=exc.http_status, content={ "code": exc.code, "message": exc.message, "data": exc.extra, }, ) @app.exception_handler(Exception) async def unhandled_exception_handler(request: Request, exc: Exception): # ⚠️ 一定要打日志 logger.error("Unhandled exception") return JSONResponse( status_code=500, content={ "code": 50000, "message": "Internal Server Error", "data": None, }, ) # ----------------------- # CORS(可选) # ----------------------- app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) # ----------------------- # 路由注册 # ----------------------- # 公共路由,不鉴权 app.include_router( router.public_router, prefix="/api" ) # 需要鉴权的路由 app.include_router( router.protected_router, prefix="/api", dependencies=[Depends(require_min_role(RoleLevel.user))] ) # 需要管理员权限的路由 app.include_router( router.admin_required_router, prefix="/api", dependencies=[Depends(require_min_role(RoleLevel.admin))] ) # ----------------------- # Swagger 支持 Bearer Token # ----------------------- def custom_openapi(): if app.openapi_schema: return app.openapi_schema openapi_schema = get_openapi( title=app.title, version="1.0.0", description="API documentation", routes=app.routes, ) # 添加全局 Bearer openapi_schema["components"]["securitySchemes"] = { "BearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" } } for path in openapi_schema["paths"].values(): for method in path.values(): method["security"] = [{"BearerAuth": []}] app.openapi_schema = openapi_schema return app.openapi_schema app.openapi = custom_openapi