"""Application entry point with DDD architecture.""" from contextlib import asynccontextmanager from typing import AsyncGenerator import uvicorn from dishka import make_async_container from dishka.integrations.fastapi import setup_dishka from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from app.infrastructure import close_db, init_db, register_exception_handlers, settings from app.infrastructure.di.providers import ( DatabaseProvider, RepositoryProvider, TransactionManagerProvider, UseCaseProvider, ) from app.presentation import router @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: """Application lifespan manager.""" # Startup await init_db() yield # Shutdown await close_db() def app_factory() -> FastAPI: """Create and configure FastAPI application.""" app = FastAPI( title=settings.app_name, debug=settings.debug, lifespan=lifespan, docs_url="/docs" if settings.debug else None, redoc_url="/redoc" if settings.debug else None, ) # Setup Dishka DI container container = make_async_container( DatabaseProvider(), RepositoryProvider(), TransactionManagerProvider(), UseCaseProvider(), ) setup_dishka(container, app) # Register exception handlers register_exception_handlers(app) # CORS middleware app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Include API routes app.include_router(router, prefix="/api") # Health check endpoint @app.get("/health", tags=["health"]) async def health_check() -> dict[str, str]: return {"status": "ok", "app": settings.app_name} return app def main() -> None: """Run the application.""" uvicorn.run( app_factory, factory=True, host=settings.host, port=settings.port, ) if __name__ == "__main__": main()