""" Main FastAPI application entry point for the Virtual Board Member AI System. """ import logging from contextlib import asynccontextmanager from typing import Any from fastapi import FastAPI, Request, status from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.trustedhost import TrustedHostMiddleware from fastapi.responses import JSONResponse from prometheus_client import Counter, Histogram import structlog from app.core.config import settings from app.core.database import init_db from app.core.logging import setup_logging from app.api.v1.api import api_router from app.core.middleware import ( RequestLoggingMiddleware, PrometheusMiddleware, SecurityHeadersMiddleware, ) # Setup structured logging setup_logging() logger = structlog.get_logger() # Prometheus metrics are defined in middleware.py @asynccontextmanager async def lifespan(app: FastAPI) -> Any: """Application lifespan manager.""" # Startup logger.info("Starting Virtual Board Member AI System", version=settings.APP_VERSION) # Initialize database await init_db() logger.info("Database initialized successfully") # Initialize other services (Redis, Qdrant, etc.) # TODO: Add service initialization yield # Shutdown logger.info("Shutting down Virtual Board Member AI System") def create_application() -> FastAPI: """Create and configure the FastAPI application.""" app = FastAPI( title=settings.APP_NAME, description="Enterprise-grade AI assistant for board members and executives", version=settings.APP_VERSION, docs_url="/docs" if settings.DEBUG else None, redoc_url="/redoc" if settings.DEBUG else None, openapi_url="/openapi.json" if settings.DEBUG else None, lifespan=lifespan, ) # Add middleware app.add_middleware( CORSMiddleware, allow_origins=settings.ALLOWED_HOSTS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.add_middleware(TrustedHostMiddleware, allowed_hosts=settings.ALLOWED_HOSTS) app.add_middleware(RequestLoggingMiddleware) app.add_middleware(PrometheusMiddleware) app.add_middleware(SecurityHeadersMiddleware) # Include API routes app.include_router(api_router, prefix="/api/v1") # Health check endpoint @app.get("/health", tags=["Health"]) async def health_check() -> dict[str, Any]: """Health check endpoint.""" return { "status": "healthy", "version": settings.APP_VERSION, "environment": settings.ENVIRONMENT, } # Root endpoint @app.get("/", tags=["Root"]) async def root() -> dict[str, Any]: """Root endpoint with API information.""" return { "message": "Virtual Board Member AI System", "version": settings.APP_VERSION, "docs": "/docs" if settings.DEBUG else None, "health": "/health", } # Exception handlers @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception) -> JSONResponse: """Global exception handler.""" logger.error( "Unhandled exception", exc_info=exc, path=request.url.path, method=request.method, ) return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={ "detail": "Internal server error", "type": "internal_error", }, ) return app # Create the application instance app = create_application() if __name__ == "__main__": import uvicorn uvicorn.run( "app.main:app", host=settings.HOST, port=settings.PORT, reload=settings.RELOAD, log_level=settings.LOG_LEVEL.lower(), )