"""FastAPI 入口:健康检查 + 只读 API + 静态看板。""" from __future__ import annotations from pathlib import Path from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse, HTMLResponse, Response from fastapi.staticfiles import StaticFiles from apps.api.routes import auth, health, meta, notify, samples, stats app = FastAPI( title="比特骆驼行情采集分析", description="market_intel — 只读行情采集与统计", version="0.1.0", ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(health.router) app.include_router(auth.router, prefix="/api") app.include_router(meta.router, prefix="/api") app.include_router(samples.router, prefix="/api") app.include_router(stats.router, prefix="/api") app.include_router(notify.router, prefix="/api") _WEB_DIST = Path(__file__).resolve().parents[2] / "web" / "dist" _FALLBACK_HTML = """ 比特骆驼行情采集分析

比特骆驼行情采集分析

API 已就绪。/health · /api/meta/latest

构建前端:cd web && npm i && npm run build

""" def _index_response() -> Response: index_html = _WEB_DIST / "index.html" if index_html.is_file(): return FileResponse(index_html) return HTMLResponse(_FALLBACK_HTML) @app.get("/") def index() -> Response: return _index_response() @app.get("/ops-map") def ops_map_page() -> Response: """SPA / 静态看板入口(hash 或 React Router)。""" return _index_response() if _WEB_DIST.is_dir(): assets = _WEB_DIST / "assets" if assets.is_dir(): app.mount("/assets", StaticFiles(directory=str(assets)), name="assets")