""" # Summary OpenAPI-driven route binding for FastAPI. This module is responsible for translating an OpenAPI 3.x specification into concrete FastAPI routes. It enforces a strict one-to-one mapping between OpenAPI operations and Python handler functions using `operationId`. Notes: **Core Responsibility:** - Read path + method definitions from an OpenAPI specification. - Resolve each `operationId` to a Python callable. - Register routes with FastAPI using `APIRoute`. - Fail fast when contract violations are detected. **Design Constraints:** - All routes MUST be declared in the OpenAPI specification. - All OpenAPI operations MUST define an `operationId`. - Every `operationId` MUST resolve to a handler function. - Handlers are plain Python callables (no decorators required). - No implicit route creation or inference is allowed. **Constraints:** - This module intentionally does NOT: - Perform request or response validation. - Generate Pydantic models. - Modify FastAPI dependency injection. - Interpret OpenAPI semantics beyond routing metadata. """ from fastapi.routing import APIRoute from .errors import MissingOperationHandler def bind_routes(app, spec: dict, routes_module) -> None: """ Bind OpenAPI operations to FastAPI routes. Args: app (fastapi.FastAPI): The FastAPI application instance to which routes will be added. spec (dict): Parsed OpenAPI 3.x specification dictionary. routes_module (module): Python module containing handler functions. Each handler's name MUST exactly match an OpenAPI `operationId`. Raises: MissingOperationHandler: If an `operationId` is missing from the spec or if no corresponding handler function exists in the routes module. Notes: **Responsibilities:** - Iterates through the OpenAPI specification paths and methods. - Resolves each `operationId` to a handler function, and registers a corresponding `APIRoute` on the FastAPI application. **Guarantees:** - Route registration is deterministic and spec-driven. No route decorators are required or supported. Handler resolution errors surface at application startup. """ paths = spec.get("paths", {}) for path, methods in paths.items(): for http_method, operation in methods.items(): operation_id = operation.get("operationId") if not operation_id: raise MissingOperationHandler( path=path, method=http_method, ) try: endpoint = getattr(routes_module, operation_id) except AttributeError: raise MissingOperationHandler( path=path, method=http_method, operation_id=operation_id, ) route = APIRoute( path=path, endpoint=endpoint, methods=[http_method.upper()], name=operation_id, ) app.router.routes.append(route)