xiangqinxiaochengxu/backend/app/main.py
2026-05-18 14:24:55 +08:00

101 lines
3.0 KiB
Python

from pathlib import Path
from fastapi import FastAPI, HTTPException, Request
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from app.config import settings
from app.routers import api_router
from app.routers.activities import activity_share_landing
def create_app() -> FastAPI:
app = FastAPI(title=settings.app_name, debug=settings.app_debug)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/health", tags=["health"])
async def health_check() -> dict[str, str]:
return {"status": "ok"}
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
_ = request
code_map = {
400: 1005,
401: 1001,
403: 1002,
404: 1003,
}
return JSONResponse(
status_code=exc.status_code,
content={
"code": code_map.get(exc.status_code, 1005),
"message": exc.detail,
"data": None,
},
)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(
request: Request, exc: RequestValidationError
) -> JSONResponse:
_ = request
field_errors = []
for error in exc.errors():
location = error.get("loc", [])
field_name = location[-1] if location else "unknown"
field_errors.append(
{
"field": field_name,
"message": error.get("msg", "参数校验失败"),
"type": error.get("type"),
}
)
return JSONResponse(
status_code=422,
content={
"code": 1004,
"message": "参数校验失败",
"data": {"field_errors": field_errors},
},
)
@app.exception_handler(Exception)
async def generic_exception_handler(request: Request, exc: Exception) -> JSONResponse:
_ = request
return JSONResponse(
status_code=500,
content={
"code": 1005,
"message": str(exc) if settings.app_debug else "服务器内部错误",
"data": None,
},
)
static_dir = Path(__file__).resolve().parent / "static"
static_dir.mkdir(parents=True, exist_ok=True)
app.mount("/static", StaticFiles(directory=static_dir), name="static")
app.add_api_route(
"/share/activity/{share_token}",
activity_share_landing,
methods=["GET"],
response_class=HTMLResponse,
include_in_schema=False,
)
app.include_router(api_router, prefix=settings.api_v1_prefix)
return app
app = create_app()