| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- from __future__ import annotations
- from contextlib import asynccontextmanager
- from pathlib import Path
- from fastapi import FastAPI
- from fastapi.middleware.cors import CORSMiddleware
- from fastapi.staticfiles import StaticFiles
- from sqlalchemy import text
- from app import __version__
- from app.agents.runtime import get_agent_runtime
- from app.api.v1.router import api_router
- from app.core.config import settings
- from app.core.errors import install_exception_handlers
- from app.core.logging import setup_logging
- from app.core.middleware import RequestContextMiddleware
- from app.db.init_db import init_db
- from app.db.session import SessionLocal
- PROJECT_ROOT = Path(__file__).resolve().parents[1]
- FRONTEND_DIR = PROJECT_ROOT / "frontend"
- class FrontendStaticFiles(StaticFiles):
- async def get_response(self, path: str, scope):
- response = await super().get_response(path, scope)
- response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
- response.headers["Pragma"] = "no-cache"
- response.headers["Expires"] = "0"
- return response
- @asynccontextmanager
- async def lifespan(_: FastAPI):
- setup_logging()
- init_db()
- if settings.seed_demo_data:
- from app.db.seed import seed_demo_data
- with SessionLocal() as db:
- seed_demo_data(db)
- yield
- app = FastAPI(
- title=settings.app_name,
- version=__version__,
- description=(
- "基于 FastAPI 与 DeepAgent 的矿山通防业务智能管控平台后端。"
- "普通业务数据通过 REST API 管理,诊断、评价和知识问答通过 DeepAgent 工作流增强。"
- ),
- lifespan=lifespan,
- docs_url="/docs",
- redoc_url="/redoc",
- openapi_url="/openapi.json",
- )
- app.add_middleware(
- CORSMiddleware,
- allow_origins=settings.cors_origin_list,
- allow_credentials=True,
- allow_methods=["*"],
- allow_headers=["*"],
- )
- app.add_middleware(RequestContextMiddleware)
- install_exception_handlers(app)
- app.include_router(api_router, prefix=settings.api_v1_prefix)
- if FRONTEND_DIR.is_dir():
- app.mount(
- "/app",
- FrontendStaticFiles(directory=FRONTEND_DIR, html=True),
- name="frontend",
- )
- @app.get("/", tags=["系统"], summary="服务入口")
- def root() -> dict:
- return {
- "name": settings.app_name,
- "version": __version__,
- "docs": "/docs",
- "api": settings.api_v1_prefix,
- "app": "/app/",
- }
- @app.get("/health", tags=["系统"], summary="服务健康检查")
- def health() -> dict:
- database_status = "ok"
- database_error = ""
- try:
- with SessionLocal() as db:
- db.execute(text("SELECT 1"))
- except Exception as exc: # pragma: no cover - depends on external DB
- database_status = "error"
- database_error = f"{type(exc).__name__}: {exc}"
- return {
- "status": "ok" if database_status == "ok" else "down",
- "version": __version__,
- "environment": settings.app_env,
- "database": {
- "dialect": settings.database_dialect,
- "status": database_status,
- "error": database_error,
- },
- "agent": get_agent_runtime().describe(),
- }
- if __name__ == "__main__":
- import uvicorn
- uvicorn.run(
- "app.main:app",
- host=settings.host,
- port=settings.port,
- reload=settings.debug,
- )
|