| """FastAPI entrypoint. |
| |
| Run locally: `make api` |
| Health: http://localhost:8000/health |
| OpenAPI: http://localhost:8000/docs |
| """ |
|
|
| from __future__ import annotations |
|
|
| import os |
| from typing import Any |
|
|
| import structlog |
| from fastapi import FastAPI |
| from fastapi.middleware.cors import CORSMiddleware |
|
|
| from app.api.middleware.audit import AuditMiddleware |
| from app.api.routers import appointment, clerical, discharge, documentation, handover, roster |
|
|
| log = structlog.get_logger(__name__) |
|
|
| app = FastAPI( |
| title="CliniqAI Backend", |
| description="Clinical operations AI for Indian hospitals — multi-agent backend.", |
| version="0.0.1", |
| ) |
|
|
| |
| app.add_middleware( |
| CORSMiddleware, |
| allow_origins=["*"], |
| allow_credentials=False, |
| allow_methods=["*"], |
| allow_headers=["*"], |
| ) |
|
|
| app.add_middleware(AuditMiddleware) |
|
|
| |
| app.include_router(documentation.router, prefix="/documentation", tags=["documentation"]) |
| app.include_router(appointment.router, prefix="/appointment", tags=["appointment"]) |
| app.include_router(clerical.router, prefix="/clerical", tags=["clerical"]) |
| app.include_router(discharge.router, prefix="/discharge", tags=["discharge"]) |
| app.include_router(roster.router, prefix="/roster", tags=["roster"]) |
| app.include_router(handover.router, prefix="/handover", tags=["handover"]) |
|
|
|
|
| @app.get("/health") |
| def health() -> dict[str, Any]: |
| return { |
| "status": "ok", |
| "env": os.getenv("CLINIQ_ENV", "dev"), |
| "service": "cliniqai-backend", |
| } |
|
|
|
|
| @app.post("/orchestrate") |
| def orchestrate(payload: dict[str, str]) -> dict[str, Any]: |
| """One-shot orchestrator endpoint — used by the Gradio UI.""" |
| from app.orchestrator import run |
|
|
| utterance = payload.get("utterance", "") |
| session_id = payload.get("session_id", "demo") |
| out = run(utterance, session_id=session_id) |
| |
| serial: dict[str, Any] = {} |
| for k, v in out.items(): |
| if v is None: |
| serial[k] = None |
| elif hasattr(v, "model_dump"): |
| serial[k] = v.model_dump(mode="json") |
| else: |
| serial[k] = str(v) |
| return serial |
|
|