""" Main FastAPI application for Core Code API """ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from contextlib import asynccontextmanager from src.config import get_settings from src.logging_config import setup_logging, get_logger from src.models.ollama_client import get_ollama_client, close_ollama_client from src.db import get_database from src.controllers.infrastructure_controller import infrastructure_controller from src.controllers.tools_controller import tools_controller from src.controllers.health_controller import health_controller from src.controllers.static_controller import static_controller from src.controllers.housekeeping_controller import housekeeping_controller from src.auth.controller import auth_controller from src.security import initialize_oidc # Initialize settings settings = get_settings() # Setup logging setup_logging(settings.log_level) logger = get_logger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): """ Application lifespan manager for startup/shutdown events Args: app: FastAPI application instance """ # Startup logger.info("=" * 60) logger.info(f"Starting {settings.app_name} v{settings.app_version}") logger.info(f"Debug mode: {settings.debug}") logger.info(f"Log level: {settings.log_level}") logger.info(f"Ollama URL: {settings.ollama_base_url}") logger.info("=" * 60) # Check Ollama connectivity ollama_client = get_ollama_client() ollama_healthy = await ollama_client.health_check() if ollama_healthy: logger.info("✓ Ollama connection successful") else: logger.warning("✗ Ollama connection failed - AI features may not work") # Check database connectivity database = get_database() db_healthy = await database.health_check() if db_healthy: logger.info("✓ Database connection successful") else: logger.warning("✗ Database connection failed - auth features may not work") # Initialize security (OIDC authentication) initialize_oidc(settings) yield # Shutdown logger.info("Shutting down application") await close_ollama_client() await database.close() # Create FastAPI application app = FastAPI( title=settings.app_name, version=settings.app_version, description=""" Core Code API - Infrastructure management and home automation API. ## Features - **Infrastructure Management** - Container and stack management via Portainer - **Home Automation** - Device control via Home Assistant - **Tools** - DNS lookup and utilities See `/docs` for the full API reference. """, docs_url="/docs", redoc_url=None, openapi_url="/openapi.json", lifespan=lifespan, debug=settings.debug, swagger_ui_init_oauth={ "clientId": settings.oidc_audience, "usePkceWithAuthorizationCodeGrant": True, } if settings.oidc_enabled else None ) # Add CORS middleware app.add_middleware( CORSMiddleware, allow_origins=settings.cors_origins, allow_credentials=settings.cors_credentials, allow_methods=settings.cors_methods, allow_headers=settings.cors_headers, ) # Include controller routers app.include_router(health_controller.router) # / and /health app.include_router(auth_controller.router) # /auth/* app.include_router(tools_controller.router) # /tools/* app.include_router(infrastructure_controller.router) # /infrastructure/* app.include_router(housekeeping_controller.router) # /housekeeping/* app.include_router(static_controller.router) # /static/* # Global exception handler @app.exception_handler(Exception) async def global_exception_handler(request, exc): """ Catch-all exception handler for unhandled errors Args: request: The request that caused the exception exc: The exception instance Returns: JSON error response """ logger.error(f"Unhandled exception: {str(exc)}", exc_info=True) return JSONResponse( status_code=500, content={ "detail": "Internal server error", "type": type(exc).__name__ } )