102 lines
3.1 KiB
Python
102 lines
3.1 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.mount(f"{settings.api_v1_prefix}/static", StaticFiles(directory=static_dir), name="api-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()
|