56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from fastapi import FastAPI, Response
|
|
|
|
from adapters.postgres import PostgresTraceRepository
|
|
from bootstrap import build_runtime
|
|
from config import Settings, get_settings
|
|
from rag.answer import GroundedAnswerService
|
|
from routers.rag import router as rag_router
|
|
|
|
|
|
def create_app(
|
|
*,
|
|
settings: Settings | None = None,
|
|
answer_service: GroundedAnswerService | None = None,
|
|
conversational: Any | None = None,
|
|
trace_writer: PostgresTraceRepository | None = None,
|
|
metrics: Any | None = None,
|
|
) -> FastAPI:
|
|
configured = settings or get_settings()
|
|
app = FastAPI(title=configured.app_name, version="0.1.0")
|
|
app.state.answer_service = answer_service
|
|
app.state.conversational = conversational
|
|
app.state.trace_writer = trace_writer
|
|
app.state.metrics = metrics
|
|
|
|
@app.get("/health")
|
|
def health() -> dict[str, str]:
|
|
return {"status": "ok"}
|
|
|
|
@app.get("/metrics")
|
|
def prometheus_metrics() -> Response:
|
|
exporter = getattr(app.state, "metrics", None)
|
|
if exporter is None or not hasattr(exporter, "render"):
|
|
# 404 rather than an empty 200: a scrape that silently succeeds
|
|
# with no samples looks identical to a service answering nothing.
|
|
return Response(status_code=404)
|
|
body, content_type = exporter.render()
|
|
return Response(content=body, media_type=content_type)
|
|
|
|
app.include_router(rag_router)
|
|
return app
|
|
|
|
|
|
_settings = get_settings()
|
|
_answer_service, _conversational, _trace_writer, _metrics = build_runtime(_settings)
|
|
app = create_app(
|
|
settings=_settings,
|
|
answer_service=_answer_service,
|
|
conversational=_conversational,
|
|
trace_writer=_trace_writer,
|
|
metrics=_metrics,
|
|
)
|