|
|
"""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, |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__all__: list[str] = [ |
|
|
"create_app", |
|
|
|
|
|
"TokenEvent", |
|
|
"DoneEvent", |
|
|
"ErrorEvent", |
|
|
"SourceInfo", |
|
|
"stream_sse_response", |
|
|
"format_sse_event", |
|
|
|
|
|
"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. |
|
|
|
|
|
""" |
|
|
|
|
|
if name == "create_app": |
|
|
from .main import create_app |
|
|
|
|
|
return create_app |
|
|
|
|
|
|
|
|
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_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}" |
|
|
raise AttributeError(msg) |
|
|
|