""" Main FastAPI application """ import logging from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from app.config import get_settings from app.database import init_db from app.api.routes import router from app.scheduler.tasks import start_scheduler, stop_scheduler # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('logs/app.log'), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) settings = get_settings() @asynccontextmanager async def lifespan(app: FastAPI): """ Application lifespan manager Handles startup and shutdown events """ # Startup logger.info("Starting Nairobi Information Collector") # Initialize database try: init_db() logger.info("Database initialized") except Exception as e: logger.error(f"Database initialization failed: {e}") # Start scheduler try: start_scheduler() logger.info("Scheduler started") except Exception as e: logger.error(f"Scheduler failed to start: {e}") yield # Shutdown logger.info("Shutting down Nairobi Information Collector") try: stop_scheduler() logger.info("Scheduler stopped") except Exception as e: logger.error(f"Error stopping scheduler: {e}") # Create FastAPI app app = FastAPI( title=settings.app_name, version=settings.app_version, description="Advanced Intelligence Retrieval System for Nairobi, Kenya", lifespan=lifespan ) # CORS middleware app.add_middleware( CORSMiddleware, allow_origins=settings.allowed_origins_list, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Include API routes app.include_router(router) @app.get("/") async def root(): """Root endpoint""" return { "name": settings.app_name, "version": settings.app_version, "description": "Advanced Intelligence Retrieval System for Nairobi, Kenya", "docs": "/docs", "api": "/api/v1" } @app.exception_handler(Exception) async def global_exception_handler(request, exc): """Global exception handler""" logger.error(f"Unhandled exception: {exc}", exc_info=True) return JSONResponse( status_code=500, content={ "detail": "Internal server error", "error": str(exc) if settings.debug else "An error occurred" } ) if __name__ == "__main__": import uvicorn uvicorn.run( "app.main:app", host=settings.host, port=settings.port, reload=settings.debug )