import os from app.api.router import api_router, health_router from app.config import settings from app.middleware.exceptions import ( APIException, api_exception_handler, general_exception_handler, http_exception_handler, validation_exception_handler, ) from app.middleware.logging import RequestLoggingMiddleware from fastapi import FastAPI from fastapi.exceptions import RequestValidationError from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.gzip import GZipMiddleware from starlette.exceptions import HTTPException as StarletteHTTPException from starlette.staticfiles import StaticFiles app = FastAPI( title="小虾 SaaS API", description="自动化剪辑 SaaS 平台 API", version=settings.APP_VERSION, docs_url="/docs", redoc_url="/redoc", ) app.add_exception_handler(APIException, api_exception_handler) app.add_exception_handler(StarletteHTTPException, http_exception_handler) app.add_exception_handler(RequestValidationError, validation_exception_handler) app.add_exception_handler(Exception, general_exception_handler) # CORS 配置:根据 DEBUG 模式区分 # 生产环境:allow_credentials=True 时不能使用通配符 "*" if settings.DEBUG: # 开发环境:允许所有来源(方便本地调试) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) else: # 生产环境:严格限制来源和方法 app.add_middleware( CORSMiddleware, allow_origins=settings.CORS_ORIGINS, allow_credentials=True, allow_methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"], allow_headers=[ "Authorization", "Content-Type", "X-Request-ID", "X-Correlation-ID", ], ) app.add_middleware(GZipMiddleware, minimum_size=1000) app.add_middleware(RequestLoggingMiddleware) app.include_router(health_router) app.include_router(api_router) _generated_files_dir = os.getenv("GENERATED_FILES_DIR", "/app/generated") os.makedirs(_generated_files_dir, exist_ok=True) app.mount( os.getenv("GENERATED_FILES_URL_PREFIX", "/generated-files"), StaticFiles(directory=_generated_files_dir), name="generated-files", ) def create_app() -> FastAPI: return app @app.get("/") async def root(): return { "service": settings.APP_NAME, "status": "running", "version": settings.APP_VERSION, } if __name__ == "__main__": import uvicorn uvicorn.run(app, host=settings.API_HOST, port=settings.API_PORT)