2026-03-31 15:50:42 +08:00
|
|
|
"""FastAPI 应用入口"""
|
|
|
|
|
|
|
|
|
|
from contextlib import asynccontextmanager
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
from fastapi import FastAPI
|
|
|
|
|
from fastapi.responses import FileResponse
|
|
|
|
|
from fastapi.staticfiles import StaticFiles
|
|
|
|
|
|
|
|
|
|
from app.config import settings
|
|
|
|
|
from app.database import get_db, close_db, seed_from_config
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@asynccontextmanager
|
|
|
|
|
async def lifespan(app: FastAPI):
|
|
|
|
|
await get_db()
|
|
|
|
|
await seed_from_config()
|
|
|
|
|
|
|
|
|
|
from app.services.scheduler import start_scheduler
|
|
|
|
|
await start_scheduler()
|
|
|
|
|
|
|
|
|
|
Path(settings.storage.path).mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
|
|
|
|
yield
|
|
|
|
|
|
|
|
|
|
from app.services.scheduler import stop_scheduler
|
|
|
|
|
await stop_scheduler()
|
|
|
|
|
await close_db()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app = FastAPI(
|
|
|
|
|
title="Plan Manager",
|
|
|
|
|
description="多平台 Coding Plan 统一管理系统",
|
|
|
|
|
version="0.1.0",
|
|
|
|
|
lifespan=lifespan,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# 挂载 API / 代理路由
|
|
|
|
|
from app.routers import plans, quota, queue, proxy # noqa: E402
|
|
|
|
|
|
|
|
|
|
app.include_router(plans.router, prefix="/api/plans", tags=["Plans"])
|
|
|
|
|
app.include_router(quota.router, prefix="/api/quota", tags=["Quota"])
|
|
|
|
|
app.include_router(queue.router, prefix="/api/queue", tags=["Queue"])
|
|
|
|
|
app.include_router(proxy.router, tags=["Proxy"])
|
|
|
|
|
|
|
|
|
|
# 前端: 用显式路由而非 mount("/") 以避免遮盖 /docs, /api, /v1
|
|
|
|
|
_static_dir = Path(__file__).parent / "static"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/", include_in_schema=False)
|
|
|
|
|
async def serve_index():
|
|
|
|
|
return FileResponse(_static_dir / "index.html")
|
2026-03-31 22:36:18 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/health", tags=["Health"])
|
|
|
|
|
async def health_check():
|
|
|
|
|
"""健康检查端点,用于容器健康检查"""
|
|
|
|
|
return {"status": "healthy", "service": "plan-manager"}
|