95 lines
2.1 KiB
Python
95 lines
2.1 KiB
Python
from contextlib import asynccontextmanager
|
|
|
|
from fastapi import FastAPI
|
|
|
|
from core.api.kafka_publisher import KafkaPublisher
|
|
from core.api.observability.metrics import ApiMetrics
|
|
from core.api.observability.routes import create_observability_router
|
|
from core.api.observability.stats import (
|
|
ApiRuntimeStats,
|
|
HttpWorkerStatsClient,
|
|
WorkerStatsProvider,
|
|
)
|
|
from core.api.publisher import Publisher
|
|
from core.api.routes import router
|
|
from core.config import get_settings
|
|
|
|
|
|
def create_app(
|
|
publisher: Publisher | None = None,
|
|
worker_stats_client: WorkerStatsProvider | None = None,
|
|
) -> FastAPI:
|
|
settings = get_settings()
|
|
|
|
api_metrics = ApiMetrics()
|
|
api_stats = ApiRuntimeStats()
|
|
|
|
active_worker_stats_client = (
|
|
worker_stats_client
|
|
if worker_stats_client is not None
|
|
else HttpWorkerStatsClient(
|
|
url=settings.worker_stats_url,
|
|
timeout_seconds=settings.worker_stats_timeout_seconds,
|
|
)
|
|
)
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
active_publisher = publisher
|
|
|
|
if active_publisher is None:
|
|
active_publisher = KafkaPublisher(
|
|
settings
|
|
)
|
|
|
|
app.state.publisher = active_publisher
|
|
|
|
app.state.worker_stats_client = (
|
|
active_worker_stats_client
|
|
)
|
|
|
|
await active_publisher.start()
|
|
|
|
try:
|
|
yield
|
|
|
|
finally:
|
|
await active_publisher.stop()
|
|
|
|
await active_worker_stats_client.close()
|
|
|
|
app = FastAPI(
|
|
title="Telecom CDR Ingestion API",
|
|
version="0.1.0",
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
app.state.api_metrics = api_metrics
|
|
app.state.api_stats = api_stats
|
|
|
|
observability_router = create_observability_router(
|
|
metrics=api_metrics,
|
|
stats=api_stats,
|
|
worker_stats_provider=active_worker_stats_client,
|
|
)
|
|
|
|
app.include_router(
|
|
router,
|
|
prefix="/api/v1",
|
|
)
|
|
|
|
app.include_router(
|
|
observability_router,
|
|
)
|
|
|
|
@app.get("/health")
|
|
async def health() -> dict[str, str]:
|
|
return {
|
|
"status": "ok",
|
|
}
|
|
|
|
return app
|
|
|
|
|
|
app = create_app()
|