Spaces:
Runtime error
Runtime error
| # File Objective : Main FastAPI entry point with lifespan management. | |
| # Scope : apps/api β read-side API server (BFF). | |
| # What this file does: | |
| # 1. Sets up the FastAPI application with title and CORS middleware. | |
| # 2. Instantiates the LangGraph agent once during the lifespan startup. | |
| # 3. Exposes the agent reference via app state to avoid circular imports. | |
| # 4. Mounts the routers for chat, gaps, graph, and signals. | |
| # 5. Serves the built React frontend (apps/web/dist) as static files when present, | |
| # so a single container can host both API and UI. | |
| # What it does not do: | |
| # 1. Maintain DB connections directly (delegated to core adapters). | |
| 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 vantage_core.agent.graph import build_agent | |
| from vantage_core.log import get_logger, timed | |
| from apps.api.routers import chat, gaps, graph, signals | |
| log = get_logger(__name__) | |
| async def lifespan(app: FastAPI): | |
| # Build the agent singleton with its in-memory checkpointer. | |
| # Wires heavy adapters (Qdrant, Neo4j, OpenAI) once at startup. | |
| log.info("API startup β building agent (models + adapters)") | |
| with timed("build_agent startup", log): | |
| app.state.agent = build_agent() | |
| log.info("API ready") | |
| yield | |
| # No explicit teardown required for memory saver checkpointer | |
| app = FastAPI( | |
| title="Vantage API", | |
| description="Agentic Market Intelligence Read-side API Layer", | |
| version="1.0.0", | |
| lifespan=lifespan, | |
| ) | |
| # Allow all origins for the local dashboard integration | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # Register endpoints | |
| app.include_router(chat.router, prefix="/api") | |
| app.include_router(gaps.router, prefix="/api") | |
| app.include_router(graph.router, prefix="/api") | |
| app.include_router(signals.router, prefix="/api") | |
| def health() -> dict[str, str]: | |
| """Lightweight liveness probe for uptime monitors and platform healthchecks.""" | |
| return {"status": "ok"} | |
| # Serve the built React app (apps/web/dist) as static files. Mounted LAST so it | |
| # never shadows the /api routes above. html=True serves index.html at "/". | |
| # Skipped gracefully in dev when the frontend hasn't been built yet. | |
| _WEB_DIST = Path(__file__).resolve().parents[2] / "apps" / "web" / "dist" | |
| if _WEB_DIST.is_dir(): | |
| app.mount("/", StaticFiles(directory=str(_WEB_DIST), html=True), name="web") | |
| log.info("Serving frontend from %s", _WEB_DIST) | |
| else: | |
| log.info("No frontend build at %s β API-only mode", _WEB_DIST) | |