import json import logging from typing import AsyncGenerator from contextlib import asynccontextmanager from fastapi import FastAPI, HTTPException, Depends from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import StreamingResponse from google.adk.runners import Runner from google.adk.agents.run_config import RunConfig, StreamingMode from google.genai import types from app.config import settings from app.services import ( get_session_service, init_session_service, close_session_service ) from app.agent_factory import create_agent # Routers from app.routers.agents import router as agents_router from app.routers.sessions import router as sessions_router from app.routers.tools import router as tools_router # --- Logging Configuration --- # --- Logging Configuration --- logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" ) logger = logging.getLogger(__name__) # --- Application Lifespan --- @asynccontextmanager async def lifespan(app: FastAPI): """Application lifespan manager for startup/shutdown events.""" logger.info("Starting up ADK Chat Backend...") await init_session_service() logger.info("Application started successfully") yield logger.info("Shutting down ADK Chat Backend...") await close_session_service() logger.info("Application shutdown complete") app = FastAPI( title="ADK Enterprise Chat Backend", description="LLM Chat backend powered by Google ADK with PostgreSQL persistence", version="2.0.0", lifespan=lifespan ) # --- CORS Configuration --- app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # --- Register Routers --- app.include_router(agents_router) app.include_router(sessions_router) app.include_router(tools_router) # --- Helper --- def get_streaming_mode(mode_str: str) -> StreamingMode: return StreamingMode.SSE if mode_str.lower() == "sse" else StreamingMode.NONE