ruslanmv
Deploy: metrics + docs (Batch 12)
22b729d
Raw
History Blame Contribute Delete
2.7 kB
from __future__ import annotations
from typing import Any
from fastapi import FastAPI, Request, Response
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse
from starlette.middleware.trustedhost import TrustedHostMiddleware
from app.api.router import api_router
from app.landing import landing_html
from app.core.config import get_settings
from app.core.logging import configure_logging, get_logger
from app.core.rate_limits import RateLimitMiddleware
from app.core.request_id import RequestIdMiddleware
from app.core.security_headers import SecurityHeadersMiddleware
from app.observability.metrics import metrics_registry
from app.services.audit_service import audit_service
logger=get_logger(__name__)
def create_app() -> FastAPI:
settings=get_settings(); configure_logging(settings.log_level, settings.json_logs)
app=FastAPI(title='Matrix Builder API', version=settings.app_version, description='Public orchestration API for controlled Matrix Bundle generation.')
app.add_middleware(TrustedHostMiddleware, allowed_hosts=settings.allowed_hosts)
if settings.enable_security_headers: app.add_middleware(SecurityHeadersMiddleware, settings=settings)
app.add_middleware(RequestIdMiddleware); app.add_middleware(RateLimitMiddleware, settings=settings)
app.add_middleware(CORSMiddleware, allow_origins=settings.cors_origins, allow_credentials=True, allow_methods=['GET','POST','PUT','PATCH','DELETE','OPTIONS'], allow_headers=['*'])
app.include_router(api_router, prefix='/api/v1')
@app.middleware('http')
async def count_requests(request: Request, call_next: Any) -> Response:
metrics_registry.inc('http_requests_total'); response=await call_next(request); return response
@app.on_event('startup')
async def startup() -> None:
from app.runtime import get_run_worker
await get_run_worker().start()
audit_service.record('service.startup', resource_type='service', resource_id=settings.app_name); logger.info('Matrix Builder API started')
@app.on_event('shutdown')
async def shutdown() -> None:
from app.runtime import get_run_worker
await get_run_worker().stop()
@app.get('/', include_in_schema=False)
def landing() -> HTMLResponse: return HTMLResponse(landing_html(settings.app_version))
@app.get('/health', tags=['health'])
def root_health() -> dict[str, str]: return {'status':'ok','service':settings.app_name,'version':settings.app_version}
@app.get('/metrics', include_in_schema=False)
def root_metrics() -> Response: return Response(content=metrics_registry.render_prometheus(), media_type='text/plain')
return app
app=create_app()