第一次提交
This commit is contained in:
+78
@@ -0,0 +1,78 @@
|
||||
"""FastAPI 应用入口。"""
|
||||
import logging
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from slowapi import _rate_limit_exceeded_handler
|
||||
from slowapi.errors import RateLimitExceeded
|
||||
from slowapi.middleware import SlowAPIMiddleware
|
||||
|
||||
from app.api import (
|
||||
ai,
|
||||
auth,
|
||||
images,
|
||||
jobs,
|
||||
notebook,
|
||||
questions,
|
||||
settings as settings_api,
|
||||
tags,
|
||||
)
|
||||
from app.config import settings
|
||||
from app.db import Base, engine
|
||||
from app.ratelimit import limiter
|
||||
from app.services.startup import fail_stale_jobs
|
||||
|
||||
# 确保所有模型被导入注册到 metadata
|
||||
import app.models # noqa: F401
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
# 公网暴露,配置有问题就别启动了,免得带着弱密钥上线
|
||||
problems = settings.check_production_secrets()
|
||||
if problems:
|
||||
for p in problems:
|
||||
logger.error("配置错误:%s", p)
|
||||
raise RuntimeError("生产配置校验失败:" + ";".join(problems))
|
||||
|
||||
# 仅开发环境自动建表,方便快速迭代;生产用 Alembic 迁移(见 deploy/)
|
||||
if settings.debug:
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
# BackgroundTasks 不跨重启,把残留的进行中任务标记为失败,
|
||||
# 否则前端会对着永不完成的任务无限轮询
|
||||
await fail_stale_jobs()
|
||||
yield
|
||||
|
||||
|
||||
app = FastAPI(title=settings.app_name, lifespan=lifespan)
|
||||
|
||||
# 限流:超限返回 429
|
||||
app.state.limiter = limiter
|
||||
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=settings.cors_origin_list,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
app.include_router(auth.router)
|
||||
app.include_router(questions.router)
|
||||
app.include_router(tags.router)
|
||||
app.include_router(images.router)
|
||||
app.include_router(jobs.router)
|
||||
app.include_router(settings_api.router)
|
||||
app.include_router(ai.router)
|
||||
app.include_router(notebook.router)
|
||||
|
||||
|
||||
@app.get("/api/health")
|
||||
async def health():
|
||||
return {"status": "ok"}
|
||||
Reference in New Issue
Block a user