File size: 2,579 Bytes
4a2ab42
 
 
62e9f27
4a2ab42
 
 
 
 
 
 
 
 
 
 
 
62e9f27
 
 
4a2ab42
 
 
 
 
 
 
 
 
 
 
 
62e9f27
 
 
 
4a2ab42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62e9f27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4a2ab42
62e9f27
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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()