from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import RedirectResponse from config.firebase import initialize_firebase from config.database import client, database from routers import kittykat_agent_api_router from kittykat_agent.ask_kittykat.tasklist_service import TasklistDatabaseService from logger import logger @asynccontextmanager async def lifespan_handler(app: FastAPI): # Startup — verify connectivity using the same client all routes use ping_response = await database.command("ping") if int(ping_response["ok"]) != 1: raise RuntimeError("Failed to connect to MongoDB cluster") logger.info("Connected to MongoDB cluster.") initialize_firebase() # Ensure task categories exist in database db_service = TasklistDatabaseService() await db_service.ensure_task_categories_exist() yield # Shutdown — close the single client client.close() logger.info("MongoDB client closed. Shutting down.") app = FastAPI(lifespan=lifespan_handler) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/", response_class=RedirectResponse, status_code=302) async def kittkat_api_docs(): return "/docs" app.include_router(kittykat_agent_api_router)