Files
simple-chat-api/app.py
T
2026-07-03 21:31:25 +08:00

55 lines
1.7 KiB
Python

from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager
from fastapi import FastAPI
from openai import AsyncOpenAI
from auth import ApiKeyAuthenticator
from config import Settings
from routes import router
from service import ChatService
from storage import JsonSessionStorage
from tools import ToolRegistry
def create_app(
settings: Settings | None = None,
client: AsyncOpenAI | None = None,
) -> FastAPI:
resolved_settings = settings or Settings.from_env()
@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
resolved_client = client
if resolved_client is None:
if not resolved_settings.api_key:
raise RuntimeError("DEEPSEEK_API_KEY is required")
resolved_client = AsyncOpenAI(
api_key=resolved_settings.api_key,
base_url=resolved_settings.base_url,
)
app.state.chat_service = ChatService(
storage=JsonSessionStorage(resolved_settings.data_dir),
client=resolved_client,
model=resolved_settings.model,
default_system_prompt=resolved_settings.default_system_prompt,
tool_registry=ToolRegistry(resolved_settings.tool_timeout_seconds),
max_tool_rounds=resolved_settings.max_tool_rounds,
max_tool_calls_per_turn=resolved_settings.max_tool_calls_per_turn,
)
app.state.authenticator = ApiKeyAuthenticator(
resolved_settings.api_key_whitelist
)
yield
if client is None:
await resolved_client.close()
app = FastAPI(title="Simple Chat API", version="0.1.0", lifespan=lifespan)
app.include_router(router)
return app
app = create_app()