"""# Summary FastAPI application bootstrap — uses OpenAPIFirstApp for spec-driven routing. Handlers are looked up by operationId in interfaces.openapi, so no router tables are declared here; the lifespan initializes and shuts down app resources. """ import logging from contextlib import asynccontextmanager from dotenv import load_dotenv from openapi_first.app import OpenAPIFirstApp from starlette.middleware.cors import CORSMiddleware from init import init, shutdown load_dotenv() logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(name)s] %(levelname)s: %(message)s", ) import interfaces.openapi as openapi_routes logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: OpenAPIFirstApp): """Initialize resource wiring on startup and shut it down on exit. Args: app (OpenAPIFirstApp): The ASGI application exposing app.state. Yields: None: The application runs while the context is open. """ resources = await init() app.state.db_resources = resources yield await shutdown() app = OpenAPIFirstApp( openapi_path="openapi.yaml", routes_module=openapi_routes, title="Item API", version="0.1.0", lifespan=lifespan, ) app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])