Files
xiaoxia-saas/apps/api/main.py
T

84 lines
2.6 KiB
Python

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)
# P1-1: Fix CORS configuration security issue
# - allow_credentials=True is incompatible with allow_origins=["*"]
# - In production, only allow configured domains, not "*"
if settings.DEBUG:
allow_origins = settings.CORS_ORIGINS # Allow localhost in debug mode
else:
# In production, filter out any wildcard "*" origins
allow_origins = [origin for origin in settings.CORS_ORIGINS if origin != "*"]
if not allow_origins:
# Default to production domain if no valid origins configured
allow_origins = ["https://xiaoxiajianji.com"]
app.add_middleware(
CORSMiddleware,
allow_origins=allow_origins,
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allow_headers=["Authorization", "Content-Type"],
)
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)