Renumber the 15 reference docs into pillar groups (recipe -> anatomy): - 01 Build Recipe (entry), 02 Composition Root - domains: 10 Layering Rules - contract: 20 Spec-First Routing, 21 CRUD Template, 22 Auth Integration - interfaces/infra: 30 Infra Adapters - UI: 40 UI: Auto-Rendered Admin & Custom Pages (new; @aetoskia packages, client template, x- catalog via react-openapi MCP module) - pipelines: 50 Pipeline Scaffold, 51 Worker & Progress, 52 Human-in-the-Loop - delivery/meta: 90 Drone Pipelines, 91 Versioning & Changelog, 92 Genericity Matrix, 93 Library Registry, 94 Repository Inventory MCP module names are unchanged (NN_ prefix stripped); all cross-references (wiki, templates, hooks, registry) updated; lib index rewritten pillar-first; build recipe bootstraps the client template. Bundle + HTML sites regenerated.
61 lines
1.6 KiB
Python
61 lines
1.6 KiB
Python
"""# 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.
|
|
|
|
---
|
|
|
|
``load_dotenv()`` runs before the app is constructed so ``{AUTH_SERVER}`` in
|
|
``openapi.yaml``'s bearer-JWT security scheme resolves from ``.env`` at build
|
|
time (openapi_first resolves env placeholders when the spec is loaded).
|
|
"""
|
|
# ruff: noqa: E402
|
|
import logging
|
|
from contextlib import asynccontextmanager
|
|
|
|
from dotenv import load_dotenv
|
|
from openapi_first.app import OpenAPIFirstApp
|
|
from starlette.middleware.cors import CORSMiddleware
|
|
|
|
load_dotenv()
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
|
|
)
|
|
|
|
import interfaces.openapi as openapi_routes
|
|
from init import init, shutdown
|
|
|
|
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="App Template API",
|
|
version="0.1.0",
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
|