All checks were successful
continuous-integration/drone/push Build is passing
1 line
22 KiB
JSON
1 line
22 KiB
JSON
{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"openapi_first","text":""},{"location":"#openapi_first","title":"openapi_first","text":"<p>FastAPI OpenAPI First \u2014 strict OpenAPI-first application bootstrap for FastAPI.</p> <p>FastAPI OpenAPI First is a contract-first infrastructure library that enforces OpenAPI as the single source of truth for FastAPI services.</p> <p>The library removes decorator-driven routing and replaces it with deterministic, spec-driven application assembly. Every HTTP route, method, and operation is defined in OpenAPI first and bound to Python handlers explicitly via operationId.</p> <p>The package is intentionally minimal and layered. Each module has a single responsibility and exposes explicit contracts rather than convenience facades.</p>"},{"location":"#openapi_first--architecture-overview","title":"Architecture Overview","text":"<p>The library is structured around four core responsibilities:</p> <ul> <li>loader: load and validate OpenAPI 3.x specifications (JSON/YAML)</li> <li>binder: bind OpenAPI operations to FastAPI routes via operationId</li> <li>app: OpenAPI-first FastAPI application bootstrap</li> <li>client: OpenAPI-first HTTP client driven by the same specification</li> <li>errors: explicit error hierarchy for contract violations</li> </ul> <p>The package root acts as a namespace, not a facade. Consumers are expected to import functionality explicitly from the appropriate module.</p>"},{"location":"#openapi_first--installation","title":"Installation","text":"<p>Install using pip:</p> <pre><code>pip install openapi-first\n</code></pre> <p>Or with Poetry:</p> <pre><code>poetry add openapi-first\n</code></pre> <p>Runtime dependencies are intentionally minimal: - fastapi (server-side) - httpx (client-side) - openapi-spec-validator - pyyaml (optional, for YAML specs)</p> <p>The ASGI server (e.g., uvicorn) is an application-level dependency and is not bundled with this library.</p>"},{"location":"#openapi_first--command-line-interface-scaffolding-templates","title":"Command-Line Interface (Scaffolding, Templates)","text":"<p>FastAPI OpenAPI First ships with a small CLI for bootstrapping OpenAPI-first FastAPI applications from bundled templates.</p> <p>List available application templates:</p> <pre><code>openapi-first --list\n</code></pre> <p>Create a new application using the default template:</p> <pre><code>openapi-first\n</code></pre> <p>Create a new application using a specific template:</p> <pre><code>openapi-first health_app\n</code></pre> <p>Create a new application in a custom directory:</p> <pre><code>openapi-first health_app my-service\n</code></pre> <p>The CLI copies template files verbatim into the target directory. No code is generated or modified beyond the copied scaffold.</p>"},{"location":"#openapi_first--server-side-usage-openapi-fastapi","title":"Server-Side Usage (OpenAPI \u2192 FastAPI)","text":"<p>Minimal OpenAPI-first FastAPI application:</p> <pre><code>from openapi_first import app\nimport my_service.routes as routes\n\napi = app.OpenAPIFirstApp(\n openapi_path=\"openapi.yaml\",\n routes_module=routes,\n title=\"My Service\",\n version=\"1.0.0\",\n)\n\n# Run with:\n# uvicorn my_service.main:api\n</code></pre> <p>Handler definitions (no decorators):</p> <pre><code>def get_health():\n return {\"status\": \"ok\"}\n</code></pre> <p>OpenAPI snippet:</p> <pre><code>paths:\n /health:\n get:\n operationId: get_health\n responses:\n \"200\":\n description: OK\n</code></pre> <p>The binder guarantees: - Every OpenAPI operationId has exactly one handler - No undocumented routes exist - All mismatches fail at application startup</p>"},{"location":"#openapi_first--client-side-usage-openapi-http-client","title":"Client-Side Usage (OpenAPI \u2192 HTTP Client)","text":"<p>The same OpenAPI specification can be used to construct a strict, operationId-driven HTTP client.</p> <p>Client construction:</p> <pre><code>from openapi_first.loader import load_openapi\nfrom openapi_first.client import OpenAPIClient\n\nspec = load_openapi(\"openapi.yaml\")\n\nclient = OpenAPIClient(spec)\n</code></pre> <p>Calling operations (operationId is the API):</p> <pre><code>response = client.get_health()\nassert response.status_code == 200\nassert response.json() == {\"status\": \"ok\"}\n</code></pre> <p>Path parameters must match the OpenAPI specification exactly:</p> <pre><code>response = client.get_item(\n path_params={\"item_id\": 1}\n)\n</code></pre> <p>Request bodies are passed explicitly:</p> <pre><code>response = client.create_item(\n body={\"name\": \"Orange\", \"price\": 0.8}\n)\n</code></pre> <p>Client guarantees: - One callable per OpenAPI operationId - No hardcoded URLs or HTTP methods in user code - Path and body parameters must match the spec exactly - Invalid or incomplete OpenAPI specs fail at client construction time - No schema inference or mutation is performed</p> <p>The client is transport-level only and returns <code>httpx.Response</code> objects directly. Response interpretation and validation are left to the consumer or higher-level layers.</p>"},{"location":"#openapi_first--extensibility-model","title":"Extensibility Model","text":"<p>FastAPI OpenAPI First is designed to be extended via explicit contracts:</p> <ul> <li>Users MAY extend OpenAPI loading behavior (e.g. multi-file specs) by wrapping or replacing <code>loader.load_openapi</code></li> <li>Users MAY extend route binding behavior by building on top of <code>binder.bind_routes</code></li> <li>Users MAY layer additional validation (e.g. signature checks) without modifying core modules</li> </ul> <p>Users SHOULD NOT rely on FastAPI decorators for routing when using this library. Mixing decorator-driven routes with OpenAPI-first routing defeats the contract guarantees and is explicitly unsupported.</p>"},{"location":"#openapi_first--public-api-surface","title":"Public API Surface","text":"<p>The supported public API consists of the following top-level modules:</p> <ul> <li>openapi_first.app</li> <li>openapi_first.binder</li> <li>openapi_first.loader</li> <li>openapi_first.client</li> <li>openapi_first.errors</li> </ul> <p>Classes and functions should be imported explicitly from these modules. No individual symbols are re-exported at the package root.</p>"},{"location":"#openapi_first--design-guarantees","title":"Design Guarantees","text":"<ul> <li>OpenAPI is the single source of truth</li> <li>No undocumented routes can exist</li> <li>No OpenAPI operation can exist without a handler or client callable</li> <li>All contract violations fail at application startup or client creation</li> <li>No hidden FastAPI magic or implicit behavior</li> <li>Deterministic, testable application assembly</li> <li>CI-friendly failure modes</li> </ul> <p>FastAPI OpenAPI First favors correctness, explicitness, and contract enforcement over convenience shortcuts.</p>"},{"location":"#openapi_first--core-philosophy","title":"Core Philosophy","text":"<p><code>FastAPI OpenAPI First</code> operates on the Contract-as-Code principle:</p> <ol> <li>Spec-Driven Routing: The OpenAPI document is the router. Code only exists to fulfill established contracts.</li> <li>Startup Fail-Fast: Binding mismatches (missing handlers or extra operations) are detected during app initialization, not at runtime.</li> <li>Decoupled Symmetry: The same specification drives both the FastAPI server and the <code>httpx</code>-based client, ensuring type-safe communication.</li> </ol>"},{"location":"#openapi_first--documentation-design","title":"Documentation Design","text":"<p>Follow these \"AI-Native\" docstring principles to maximize developer and agent productivity:</p>"},{"location":"#openapi_first--for-humans","title":"For Humans","text":"<ul> <li>Logical Grouping: Document the Loader, Binder, and Client as distinct infrastructure layers.</li> <li>Spec Snippets: Always include the corresponding OpenAPI YAML/JSON snippet alongside Python examples.</li> </ul>"},{"location":"#openapi_first--for-llms","title":"For LLMs","text":"<ul> <li>Full Path Linking: Refer to cross-module dependencies using their full dotted paths (e.g., <code>openapi_first.loader.load_openapi</code>).</li> <li>Complete Stubs: Maintain high-fidelity <code>.pyi</code> stubs for all public interfaces to provide an optimized machine-context.</li> <li>Traceable Errors: Use specific <code>: description</code> pairs in <code>Raises</code> blocks to allow agents to accurately map errors to spec violations.</li> </ul>"},{"location":"app/","title":"App","text":""},{"location":"app/#openapi_first.app","title":"openapi_first.app","text":""},{"location":"app/#openapi_first.app--openapi_firstapp","title":"openapi_first.app","text":"<p>OpenAPI-first application bootstrap for FastAPI.</p> <p>This module provides <code>OpenAPIFirstApp</code>, a thin but strict abstraction that enforces OpenAPI as the single source of truth for a FastAPI service.</p>"},{"location":"app/#openapi_first.app--core-principles","title":"Core principles","text":"<ul> <li>The OpenAPI specification (JSON or YAML) defines the entire API surface.</li> <li>Every operationId in the OpenAPI spec must have a corresponding Python handler function.</li> <li>Handlers are plain Python callables (no FastAPI decorators).</li> <li>FastAPI route registration is derived exclusively from the spec.</li> <li>FastAPI's autogenerated OpenAPI schema is fully overridden.</li> </ul>"},{"location":"app/#openapi_first.app--what-this-module-does","title":"What this module does","text":"<ul> <li>Loads and validates an OpenAPI 3.x specification.</li> <li>Dynamically binds HTTP routes to handler functions using operationId.</li> <li>Registers routes with FastAPI at application startup.</li> <li>Ensures runtime behavior matches the OpenAPI contract exactly.</li> </ul>"},{"location":"app/#openapi_first.app--what-this-module-does-not-do","title":"What this module does NOT do","text":"<ul> <li>It does not generate OpenAPI specs.</li> <li>It does not generate client code.</li> <li>It does not introduce a new framework or lifecycle.</li> <li>It does not alter FastAPI dependency injection semantics.</li> </ul>"},{"location":"app/#openapi_first.app--intended-usage","title":"Intended usage","text":"<p>This module is intended for teams that want:</p> <ul> <li>OpenAPI-first API development</li> <li>Strong contract enforcement</li> <li>Minimal FastAPI boilerplate</li> <li>Predictable, CI-friendly failures for spec/implementation drift</li> </ul>"},{"location":"app/#openapi_first.app.OpenAPIFirstApp","title":"OpenAPIFirstApp","text":"<pre><code>OpenAPIFirstApp(*, openapi_path: str, routes_module: Any, **fastapi_kwargs: Any)\n</code></pre> <p> Bases: <code>FastAPI</code></p> <p>FastAPI application enforcing OpenAPI-first design.</p> <p><code>OpenAPIFirstApp</code> subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding. All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module.</p>"},{"location":"app/#openapi_first.app.OpenAPIFirstApp--parameters","title":"Parameters","text":"<p>openapi_path : str Filesystem path to the OpenAPI 3.x specification file. This specification is treated as the authoritative API contract.</p> module <p>Python module containing handler functions whose names correspond exactly to OpenAPI operationId values.</p> <p>**fastapi_kwargs Additional keyword arguments passed directly to <code>fastapi.FastAPI</code> (e.g., title, version, middleware, lifespan handlers).</p>"},{"location":"app/#openapi_first.app.OpenAPIFirstApp--raises","title":"Raises","text":"<p>OpenAPIFirstError If the OpenAPI specification is invalid, or if any declared operationId does not have a corresponding handler function.</p>"},{"location":"app/#openapi_first.app.OpenAPIFirstApp--behavior-guarantees","title":"Behavior guarantees","text":"<ul> <li>No route can exist without an OpenAPI declaration.</li> <li>No OpenAPI operation can exist without a handler.</li> <li>Swagger UI and <code>/openapi.json</code> always reflect the provided spec.</li> <li>Handler functions remain framework-agnostic and testable.</li> </ul>"},{"location":"app/#openapi_first.app.OpenAPIFirstApp--example","title":"Example","text":"<p>from openapi_first import OpenAPIFirstApp import app.routes as routes</p> <p>app = OpenAPIFirstApp( ... openapi_path=\"app/openapi.json\", ... routes_module=routes, ... title=\"Example Service\" ... )</p>"},{"location":"binder/","title":"Binder","text":""},{"location":"binder/#openapi_first.binder","title":"openapi_first.binder","text":""},{"location":"binder/#openapi_first.binder--openapi_firstbinder","title":"openapi_first.binder","text":"<p>OpenAPI-driven route binding for FastAPI.</p> <p>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.</p>"},{"location":"binder/#openapi_first.binder--core-responsibility","title":"Core responsibility","text":"<ul> <li>Read path + method definitions from an OpenAPI specification</li> <li>Resolve each operationId to a Python callable</li> <li>Register routes with FastAPI using APIRoute</li> <li>Fail fast when contract violations are detected</li> </ul>"},{"location":"binder/#openapi_first.binder--design-constraints","title":"Design constraints","text":"<ul> <li>All routes MUST be declared in the OpenAPI specification.</li> <li>All OpenAPI operations MUST define an operationId.</li> <li>Every operationId MUST resolve to a handler function.</li> <li>Handlers are plain Python callables (no decorators required).</li> <li>No implicit route creation or inference is allowed.</li> </ul>"},{"location":"binder/#openapi_first.binder--this-module-intentionally-does-not","title":"This module intentionally does NOT:","text":"<ul> <li>Perform request or response validation</li> <li>Generate Pydantic models</li> <li>Modify FastAPI dependency injection</li> <li>Interpret OpenAPI semantics beyond routing metadata</li> </ul> <p>Those concerns belong to other layers or tooling.</p>"},{"location":"binder/#openapi_first.binder.bind_routes","title":"bind_routes","text":"<pre><code>bind_routes(app: FastAPI, spec: Dict[str, Any], routes_module: Any) -> None\n</code></pre> <p>Bind OpenAPI operations to FastAPI routes.</p> <p>Iterates through the OpenAPI specification paths and methods, resolves each operationId to a handler function, and registers a corresponding APIRoute on the FastAPI application.</p>"},{"location":"binder/#openapi_first.binder.bind_routes--parameters","title":"Parameters","text":"<p>app : fastapi.FastAPI The FastAPI application instance to which routes will be added.</p> dict <p>Parsed OpenAPI 3.x specification dictionary.</p> module <p>Python module containing handler functions. Each handler's name MUST exactly match an OpenAPI operationId.</p>"},{"location":"binder/#openapi_first.binder.bind_routes--raises","title":"Raises","text":"<p>MissingOperationHandler If an operationId is missing from the spec or if no corresponding handler function exists in the routes module.</p>"},{"location":"binder/#openapi_first.binder.bind_routes--behavior-guarantees","title":"Behavior guarantees","text":"<ul> <li>Route registration is deterministic and spec-driven.</li> <li>No route decorators are required or supported.</li> <li>Handler resolution errors surface at application startup.</li> </ul>"},{"location":"cli/","title":"Cli","text":""},{"location":"cli/#openapi_first.cli","title":"openapi_first.cli","text":""},{"location":"cli/#openapi_first.cli--openapi_firstcli","title":"openapi_first.cli","text":"<p>Command-line interface for FastAPI OpenAPI-first scaffolding utilities.</p> <p>This CLI bootstraps OpenAPI-first FastAPI applications from versioned, bundled templates packaged with the library.</p>"},{"location":"cli/#openapi_first.cli.available_templates","title":"available_templates","text":"<pre><code>available_templates() -> list[str]\n</code></pre> <p>Return a list of available application templates.</p>"},{"location":"cli/#openapi_first.cli.copy_template","title":"copy_template","text":"<pre><code>copy_template(template: str, target_dir: Path) -> None\n</code></pre> <p>Copy a bundled OpenAPI-first application template into a directory.</p>"},{"location":"client/","title":"Client","text":""},{"location":"client/#openapi_first.client","title":"openapi_first.client","text":""},{"location":"client/#openapi_first.client.OpenAPIClient","title":"OpenAPIClient","text":"<pre><code>OpenAPIClient(spec: Dict[str, Any], base_url: Optional[str] = None, client: Optional[httpx.Client] = None)\n</code></pre> <p>OpenAPI-first HTTP client (httpx-based).</p> <ul> <li>One callable per operationId</li> <li>Explicit parameters (path, query, headers, body)</li> <li>No implicit schema inference or mutation</li> </ul>"},{"location":"client/#openapi_first.client.OpenAPIClientError","title":"OpenAPIClientError","text":"<p> Bases: <code>OpenAPIFirstError</code></p> <p>Raised when an OpenAPI client operation fails.</p>"},{"location":"errors/","title":"Errors","text":""},{"location":"errors/#openapi_first.errors","title":"openapi_first.errors","text":""},{"location":"errors/#openapi_first.errors--openapi_firsterrors","title":"openapi_first.errors","text":"<p>Custom exceptions for OpenAPI-first FastAPI applications.</p> <p>This module defines a small hierarchy of explicit, intention-revealing exceptions used to signal contract violations between an OpenAPI specification and its Python implementation.</p>"},{"location":"errors/#openapi_first.errors--design-principles","title":"Design principles","text":"<ul> <li>Errors represent programmer mistakes, not runtime conditions.</li> <li>All errors are raised during application startup.</li> <li>Messages are actionable and suitable for CI/CD output.</li> <li>Exceptions are explicit rather than reused from generic built-ins.</li> </ul> <p>These errors should normally cause immediate application failure.</p>"},{"location":"errors/#openapi_first.errors.MissingOperationHandler","title":"MissingOperationHandler","text":"<pre><code>MissingOperationHandler(*, path: str, method: str, operation_id: Optional[str] = None)\n</code></pre> <p> Bases: <code>OpenAPIFirstError</code></p> <p>Raised when an OpenAPI operation cannot be resolved to a handler.</p> <p>This error occurs when: - An OpenAPI operation does not define an operationId, or - An operationId is defined but no matching function exists in the provided routes module.</p> <p>This represents a violation of the OpenAPI-first contract and indicates that the specification and implementation are out of sync.</p>"},{"location":"errors/#openapi_first.errors.MissingOperationHandler--parameters","title":"Parameters","text":"<p>path : str The HTTP path declared in the OpenAPI specification.</p> str <p>The HTTP method (as declared in the OpenAPI spec).</p> str, optional <p>The operationId declared in the OpenAPI spec, if present.</p>"},{"location":"errors/#openapi_first.errors.OpenAPIFirstError","title":"OpenAPIFirstError","text":"<p> Bases: <code>Exception</code></p> <p>Base exception for all OpenAPI-first enforcement errors.</p> <p>This exception exists to allow callers, test suites, and CI pipelines to catch and distinguish OpenAPI contract violations from unrelated runtime errors.</p> <p>All exceptions raised by the OpenAPI-first core should inherit from this type.</p>"},{"location":"loader/","title":"Loader","text":""},{"location":"loader/#openapi_first.loader","title":"openapi_first.loader","text":""},{"location":"loader/#openapi_first.loader--openapi_firstloaders","title":"openapi_first.loaders","text":"<p>OpenAPI specification loading and validation utilities.</p> <p>This module is responsible for loading an OpenAPI 3.x specification from disk and validating it before it is used by the application.</p> <p>It enforces the principle that an invalid or malformed OpenAPI document must never reach the routing or runtime layers.</p>"},{"location":"loader/#openapi_first.loader--design-principles","title":"Design principles","text":"<ul> <li>OpenAPI is treated as an authoritative contract.</li> <li>Invalid specifications fail fast at application startup.</li> <li>Supported formats are JSON and YAML.</li> <li>Validation errors are surfaced clearly and early.</li> </ul>"},{"location":"loader/#openapi_first.loader--this-module-intentionally-does-not","title":"This module intentionally does NOT:","text":"<ul> <li>Modify the OpenAPI document</li> <li>Infer missing fields</li> <li>Generate models or code</li> <li>Perform request/response validation at runtime</li> </ul>"},{"location":"loader/#openapi_first.loader.OpenAPISpecLoadError","title":"OpenAPISpecLoadError","text":"<p> Bases: <code>OpenAPIFirstError</code></p> <p>Raised when an OpenAPI specification cannot be loaded or validated.</p> <p>This error indicates that the OpenAPI document is unreadable, malformed, or violates the OpenAPI 3.x specification.</p>"},{"location":"loader/#openapi_first.loader.load_openapi","title":"load_openapi","text":"<pre><code>load_openapi(path: Union[str, Path]) -> Dict[str, Any]\n</code></pre> <p>Load and validate an OpenAPI 3.x specification from disk.</p> <p>The specification is parsed based on file extension and validated using a strict OpenAPI schema validator. Any error results in an immediate exception, preventing application startup.</p>"},{"location":"loader/#openapi_first.loader.load_openapi--parameters","title":"Parameters","text":"<p>path : str or pathlib.Path Filesystem path to an OpenAPI specification file. Supported extensions: - <code>.json</code> - <code>.yaml</code> - <code>.yml</code></p>"},{"location":"loader/#openapi_first.loader.load_openapi--returns","title":"Returns","text":"<p>dict Parsed and validated OpenAPI specification.</p>"},{"location":"loader/#openapi_first.loader.load_openapi--raises","title":"Raises","text":"<p>OpenAPISpecLoadError If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.</p>"}]} |