79 lines
2.6 KiB
Python
79 lines
2.6 KiB
Python
from contextlib import asynccontextmanager
|
|
from collections.abc import AsyncGenerator
|
|
|
|
from fastapi import FastAPI, Request
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.responses import JSONResponse
|
|
from prometheus_client import make_asgi_app
|
|
|
|
from src.core.exceptions import PIPException
|
|
from src.core.logging import configure_logging
|
|
from src.core.metrics import metrics_middleware
|
|
from src.core.tracing import setup_tracing
|
|
from src.infrastructure.cache.redis_cache import redis_cache
|
|
from src.infrastructure.config.settings import settings
|
|
from src.infrastructure.messaging.rabbitmq import rabbitmq_client
|
|
from src.api.middleware.audit import AuditMiddleware
|
|
from src.api.middleware.logging import RequestLoggingMiddleware
|
|
from src.api.middleware.rate_limit import RateLimitMiddleware
|
|
from src.api.v1.router import v1_router
|
|
from src.infrastructure.database.session import engine
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
|
|
configure_logging()
|
|
setup_tracing(app, engine=engine)
|
|
|
|
await redis_cache.connect()
|
|
await rabbitmq_client.connect()
|
|
|
|
yield
|
|
|
|
await rabbitmq_client.disconnect()
|
|
await redis_cache.disconnect()
|
|
await engine.dispose()
|
|
|
|
|
|
def create_app() -> FastAPI:
|
|
application = FastAPI(
|
|
title=settings.APP_NAME,
|
|
version=settings.APP_VERSION,
|
|
description="Pharmacy Integration Platform — unified API between pharmacy ERPs and external applications",
|
|
docs_url="/docs",
|
|
redoc_url="/redoc",
|
|
openapi_url="/openapi.json",
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
application.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=settings.CORS_ORIGINS,
|
|
allow_credentials=settings.CORS_ALLOW_CREDENTIALS,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
application.add_middleware(RateLimitMiddleware)
|
|
application.add_middleware(AuditMiddleware)
|
|
application.add_middleware(RequestLoggingMiddleware)
|
|
application.middleware("http")(metrics_middleware)
|
|
|
|
application.include_router(v1_router)
|
|
|
|
metrics_app = make_asgi_app()
|
|
application.mount("/metrics", metrics_app)
|
|
|
|
@application.exception_handler(PIPException)
|
|
async def pip_exception_handler(request: Request, exc: PIPException) -> JSONResponse:
|
|
return JSONResponse(status_code=exc.status_code, content=exc.to_dict())
|
|
|
|
@application.exception_handler(Exception)
|
|
async def generic_exception_handler(request: Request, exc: Exception) -> JSONResponse:
|
|
return JSONResponse(status_code=500, content={"error": {"code": "INTERNAL_ERROR", "message": "Internal server error"}})
|
|
|
|
return application
|
|
|
|
|
|
app = create_app()
|