"""FastAPI application module for the RAG chatbot. This module provides the FastAPI application and routing for the RAG chatbot API. The API supports: - Query endpoint with SSE streaming - Health check endpoint - Error handling middleware Components: - create_app: Factory function for FastAPI application - query router: Handles chat queries - health router: Provides health checks - SSE utilities: Server-Sent Events streaming support Lazy Loading: FastAPI and related dependencies are loaded on first access using __getattr__. This ensures fast import times when the API module is not immediately needed. Example: ------- >>> from rag_chatbot.api import create_app >>> app = create_app() >>> # Run with: uvicorn rag_chatbot.api:app SSE Streaming Example: ------- >>> from rag_chatbot.api import stream_sse_response, SourceInfo >>> from rag_chatbot.llm.base import LLMRequest >>> >>> # Stream LLM response as SSE events >>> async for event in stream_sse_response(registry, request, sources): ... yield event """ from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: from .artifact_downloader import ArtifactDownloader, ArtifactDownloadError from .main import create_app from .sse import ( DoneEvent, ErrorEvent, SourceInfo, TokenEvent, format_sse_event, stream_sse_response, ) # ============================================================================= # Module Exports # ============================================================================= __all__: list[str] = [ "create_app", # SSE utilities "TokenEvent", "DoneEvent", "ErrorEvent", "SourceInfo", "stream_sse_response", "format_sse_event", # Artifact downloader "ArtifactDownloader", "ArtifactDownloadError", ] def __getattr__(name: str) -> object: """Lazy load module exports on first access. This function is called when an attribute is not found in the module's namespace. It enables lazy loading of FastAPI and related dependencies. Args: ---- name: The name of the attribute being accessed. Returns: ------- The requested attribute if it exists in __all__. Raises: ------ AttributeError: If the attribute is not a valid export. """ # Main app factory if name == "create_app": from .main import create_app return create_app # SSE utilities - use a mapping to reduce return statements sse_exports = { "TokenEvent", "DoneEvent", "ErrorEvent", "SourceInfo", "stream_sse_response", "format_sse_event", } if name in sse_exports: from . import sse return getattr(sse, name) # Artifact downloader exports artifact_exports = { "ArtifactDownloader", "ArtifactDownloadError", } if name in artifact_exports: from . import artifact_downloader return getattr(artifact_downloader, name) msg = f"module {__name__!r} has no attribute {name!r}" # pragma: no cover raise AttributeError(msg) # pragma: no cover