"""FastAPI entrypoint for the KORA AI backend.""" from __future__ import annotations import logging from contextlib import asynccontextmanager from fastapi import FastAPI from app.routes.chat import router as chat_router from app.services.model_service import ModelService from app.services.prompt_service import PromptService from app.utils.config import settings def configure_logging() -> None: """Configure centralized application logging.""" logging.basicConfig( level=getattr(logging, settings.log_level.upper(), logging.INFO), format="%(asctime)s | %(levelname)s | %(name)s | %(message)s", ) @asynccontextmanager async def lifespan(app: FastAPI): """Initialize shared services for app lifecycle.""" configure_logging() prompt_service = PromptService(settings=settings) model_service = ModelService(settings=settings) app.state.prompt_service = prompt_service app.state.model_service = model_service await model_service.startup() logging.getLogger(__name__).info("KORA backend initialized") try: yield finally: await model_service.shutdown() app = FastAPI( title=settings.app_name, version="1.0.0", lifespan=lifespan, ) app.include_router(chat_router) @app.get("/healthz", tags=["health"]) async def healthz() -> dict[str, str]: """Liveness/readiness probe for orchestrators and HF Spaces.""" return {"status": "ok", "service": settings.app_name} @app.get("/", tags=["root"]) async def root() -> dict[str, str]: """Simple root route so HF Space URL does not return 404.""" return { "service": settings.app_name, "status": "ok", "health": "/healthz", "chat": "/v1/chat/completions", }