from __future__ import annotations from collections.abc import AsyncGenerator from contextlib import asynccontextmanager from fastapi import FastAPI from app.core.config import settings from app.core.logging_config import setup_logging @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # ── Startup ────────────────────────────────────── setup_logging() from app.db.mariadb import init_mariadb from app.db.mongodb import init_mongodb from app.db.redis import init_redis await init_mariadb() await init_mongodb() await init_redis() yield # ── Shutdown ───────────────────────────────────── from app.communication.external.http_client import close_http_client from app.db.mariadb import close_mariadb from app.db.mongodb import close_mongodb from app.db.redis import close_redis await close_http_client() await close_redis() await close_mongodb() await close_mariadb() def create_app() -> FastAPI: app = FastAPI( title=settings.APP_NAME, version="0.1.0", docs_url="/docs", redoc_url="/redoc", lifespan=lifespan, ) # ── Middleware (order matters: last added = first executed) ─── from app.middleware.cors import add_cors_middleware from app.middleware.request_id import RequestIDMiddleware from app.middleware.request_logging import RequestLoggingMiddleware add_cors_middleware(app) app.add_middleware(RequestLoggingMiddleware) app.add_middleware(RequestIDMiddleware) # ── Error handlers ─────────────────────────────── from app.core.error_handlers import register_error_handlers register_error_handlers(app) # ── Routers ────────────────────────────────────── from app.api.v1.router import v1_router app.include_router(v1_router, prefix=settings.API_V1_PREFIX) return app