Files
planet/backend/app/main.py
2026-03-25 17:19:10 +08:00

87 lines
2.6 KiB
Python

from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
from app.api.main import api_router
from app.api.v1 import websocket
from app.core.config import settings
from app.core.websocket.broadcaster import broadcaster
from app.db.session import init_db
from app.services.scheduler import (
cleanup_stale_running_tasks,
start_scheduler,
stop_scheduler,
sync_scheduler_with_datasources,
)
class WebSocketCORSMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
if request.url.path.startswith("/ws") and request.method == "GET":
response = await call_next(request)
response.headers["Access-Control-Allow-Origin"] = "*"
response.headers["Access-Control-Allow-Methods"] = "GET, OPTIONS"
response.headers["Access-Control-Allow-Headers"] = "*"
return response
return await call_next(request)
@asynccontextmanager
async def lifespan(app: FastAPI):
await init_db()
await cleanup_stale_running_tasks()
start_scheduler()
await sync_scheduler_with_datasources()
broadcaster.start()
yield
broadcaster.stop()
stop_scheduler()
app = FastAPI(
title=settings.PROJECT_NAME,
version=settings.VERSION,
description="智能星球计划 - 态势感知系统\n\n## 功能模块\n\n- **用户认证**: JWT-based authentication\n- **数据源管理**: 多源数据采集器管理\n- **任务调度**: 定时任务调度与监控\n- **实时更新**: WebSocket实时数据推送\n- **告警系统**: 多级告警管理\n\n## 数据层级\n\n- **L1**: 核心数据 (TOP500, Epoch AI GPU)\n- **L2**: 扩展数据 (HuggingFace, PeeringDB, 海缆)\n- **L3**: 分析数据\n- **L4**: 决策支持",
lifespan=lifespan,
docs_url=None,
redoc_url="/docs",
openapi_url="/openapi.json",
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.add_middleware(WebSocketCORSMiddleware)
app.include_router(api_router, prefix="/api/v1")
app.include_router(websocket.router)
@app.get("/health")
async def health_check():
return {"status": "healthy", "version": settings.VERSION}
@app.get("/")
async def root():
return {
"name": settings.PROJECT_NAME,
"version": settings.VERSION,
"docs": "/docs",
"redoc": "/redoc",
}
@app.get("/api/v1/scheduler/jobs")
async def get_scheduler_jobs():
from app.services.scheduler import get_scheduler_jobs
return {"jobs": get_scheduler_jobs()}