from dotenv import load_dotenv from fastapi import FastAPI from app.bootstrap import bootstrap_kernel from app.config import setup_middleware, setup_routers from app.constants import DESCRIPTION, PROJECT_NAME, VERSION from app.lifespan import lifespan from core.api_documentation import setup_api_documentation from core.logging import logger # Load environment variables load_dotenv() def create_app() -> FastAPI: """Application Factory Pattern""" # Initialize Kernel Registry bootstrap_kernel() app = FastAPI( title=PROJECT_NAME, description=DESCRIPTION, version=VERSION, docs_url="/docs", redoc_url="/redoc", lifespan=lifespan, ) # 1. Setup Middleware (including Exception Handlers) setup_middleware(app) # Debug: Log all registered middleware for i, m in enumerate(app.user_middleware): logger.info(f"Registered Middleware {i}: {m.cls.__module__}.{m.cls.__name__}") # 2. Setup Routers setup_routers(app) # 3. Setup API Documentation (from core) app = setup_api_documentation(app) # 4. Phase 21: OpenTelemetry Distributed Tracing try: from app.services.infrastructure.tracing import setup_opentelemetry setup_opentelemetry(app) except ImportError: logger.warning("OpenTelemetry dependencies not found, skipping tracing setup") except Exception as e: logger.warning(f"Failed to initialize OpenTelemetry: {e}") # 5. Prometheus Metrics with Custom Business Metrics try: from fastapi import Response from prometheus_fastapi_instrumentator import Instrumentator from app.services.infrastructure.metrics import get_metrics # Setup basic instrumentation Instrumentator().instrument(app).expose(app, endpoint="/metrics", include_in_schema=False) # Add custom metrics endpoint with business metrics @app.get("/metrics/custom", include_in_schema=False) async def custom_metrics(): """Expose custom business metrics""" metrics_data, content_type = get_metrics() return Response(content=metrics_data, media_type=content_type) logger.info("✅ Prometheus metrics enabled at /metrics and /metrics/custom") except ImportError as e: logger.warning(f"Prometheus dependencies not found, skipping metrics setup: {e}") except Exception as e: logger.warning(f"Failed to setup Prometheus metrics: {e}") return app # Create the FastAPI app instance for uvicorn app = create_app()