Compare commits
1 Commits
80f8defcc2
...
google-doc
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c48f58578 |
96
README.md
Normal file
96
README.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# openapi_first
|
||||
|
||||
# Summary
|
||||
|
||||
FastAPI OpenAPI First — strict OpenAPI-first application bootstrap for FastAPI.
|
||||
|
||||
FastAPI OpenAPI First is a **contract-first infrastructure library** that
|
||||
enforces OpenAPI as the single source of truth for FastAPI services.
|
||||
|
||||
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`.
|
||||
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
Install using pip:
|
||||
|
||||
```bash
|
||||
pip install openapi-first
|
||||
```
|
||||
|
||||
Or with Poetry:
|
||||
|
||||
```bash
|
||||
poetry add openapi-first
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Quick Start
|
||||
|
||||
Minimal OpenAPI-first FastAPI application:
|
||||
|
||||
```python
|
||||
from openapi_first import app
|
||||
import my_service.routes as routes
|
||||
|
||||
api = app.OpenAPIFirstApp(
|
||||
openapi_path="openapi.yaml",
|
||||
routes_module=routes,
|
||||
title="My Service",
|
||||
version="1.0.0",
|
||||
)
|
||||
```
|
||||
|
||||
OperationId-driven HTTP client:
|
||||
|
||||
```python
|
||||
from openapi_first.loader import load_openapi
|
||||
from openapi_first.client import OpenAPIClient
|
||||
|
||||
spec = load_openapi("openapi.yaml")
|
||||
client = OpenAPIClient(spec)
|
||||
|
||||
response = client.get_health()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Architecture
|
||||
|
||||
The library is structured around four core responsibilities:
|
||||
|
||||
- `loader`: Load and validate OpenAPI 3.x specifications (JSON/YAML).
|
||||
- `binder`: Bind OpenAPI operations to FastAPI routes via `operationId`.
|
||||
- `app`: OpenAPI-first FastAPI application bootstrap.
|
||||
- `client`: OpenAPI-first HTTP client driven by the same specification.
|
||||
- `errors`: Explicit error hierarchy for contract violations.
|
||||
|
||||
---
|
||||
|
||||
# Public API
|
||||
|
||||
The supported public API consists of the following top-level modules:
|
||||
|
||||
- `openapi_first.app`
|
||||
- `openapi_first.binder`
|
||||
- `openapi_first.loader`
|
||||
- `openapi_first.client`
|
||||
- `openapi_first.errors`
|
||||
|
||||
---
|
||||
|
||||
# Design Guarantees
|
||||
|
||||
- OpenAPI is the single source of truth.
|
||||
- No undocumented routes can exist.
|
||||
- No OpenAPI operation can exist without a handler or client callable.
|
||||
- All contract violations fail at application startup or client creation.
|
||||
- No hidden FastAPI magic or implicit behavior.
|
||||
- Deterministic, testable application assembly.
|
||||
|
||||
---
|
||||
@@ -1,4 +1,3 @@
|
||||
# openapi_first
|
||||
|
||||
::: openapi_first
|
||||
- [Openapi First](openapi_first/)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"module": "openapi_first.app",
|
||||
"content": {
|
||||
"path": "openapi_first.app",
|
||||
"docstring": "OpenAPI-first application bootstrap for FastAPI.\n\n---\n\n## Summary\n\nThis module provides `OpenAPIFirstApp`, a thin but strict abstraction\nthat enforces OpenAPI as the single source of truth for a FastAPI service.\n\nNotes:\n **Core Principles:**\n\n - The OpenAPI specification (JSON or YAML) defines the entire API surface\n - Every operationId in the OpenAPI spec must have a corresponding Python handler function\n - Handlers are plain Python callables (no FastAPI decorators)\n - FastAPI route registration is derived exclusively from the spec\n - FastAPI's autogenerated OpenAPI schema is fully overridden\n\n **Responsibilities:**\n\n - Loads and validates an OpenAPI 3.x specification\n - Dynamically binds HTTP routes to handler functions using operationId\n - Registers routes with FastAPI at application startup\n - Ensures runtime behavior matches the OpenAPI contract exactly\n\n **Constraints:**\n\n - This module intentionally does NOT: Generate OpenAPI specs, generate client code, introduce a new framework or lifecycle, or alter FastAPI dependency injection semantics.",
|
||||
"docstring": "# Summary\n\nOpenAPI-first application bootstrap for FastAPI.\n\nThis module provides `OpenAPIFirstApp`, a thin but strict abstraction\nthat enforces OpenAPI as the single source of truth for a FastAPI service.\n\nNotes:\n **Core Principles:**\n\n - The OpenAPI specification (JSON or YAML) defines the entire API surface.\n - Every `operationId` in the OpenAPI spec must have a corresponding\n Python handler function.\n - Handlers are plain Python callables (no FastAPI decorators).\n - FastAPI route registration is derived exclusively from the spec.\n - FastAPI's autogenerated OpenAPI schema is fully overridden.\n\n **Responsibilities:**\n\n - Loads and validates an OpenAPI 3.x specification.\n - Dynamically binds HTTP routes to handler functions using `operationId`.\n - Registers routes with FastAPI at application startup.\n - Ensures runtime behavior matches the OpenAPI contract exactly.\n\n **Constraints:**\n\n - This module intentionally does NOT:\n - Generate OpenAPI specs.\n - Generate client code.\n - Introduce a new framework or lifecycle.\n - Alter FastAPI dependency injection semantics.",
|
||||
"objects": {
|
||||
"FastAPI": {
|
||||
"name": "FastAPI",
|
||||
@@ -16,21 +16,21 @@
|
||||
"kind": "function",
|
||||
"path": "openapi_first.app.load_openapi",
|
||||
"signature": "<bound method Alias.signature of Alias('load_openapi', 'openapi_first.loader.load_openapi')>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"bind_routes": {
|
||||
"name": "bind_routes",
|
||||
"kind": "function",
|
||||
"path": "openapi_first.app.bind_routes",
|
||||
"signature": "<bound method Alias.signature of Alias('bind_routes', 'openapi_first.binder.bind_routes')>",
|
||||
"docstring": "Bind OpenAPI operations to FastAPI routes.\n\nArgs:\n app (fastapi.FastAPI):\n The FastAPI application instance to which routes will be added.\n spec (dict):\n Parsed OpenAPI 3.x specification dictionary.\n routes_module (module):\n Python module containing handler functions. Each handler's name MUST exactly match an OpenAPI operationId.\n\nRaises:\n MissingOperationHandler:\n If an operationId is missing from the spec or if no corresponding handler function exists in the routes module.\n\nNotes:\n **Responsibilities:**\n\n - Iterates through the OpenAPI specification paths and methods\n - Resolves each operationId to a handler function, and registers a corresponding APIRoute on the FastAPI application\n\n **Guarantees:**\n\n - Route registration is deterministic and spec-driven. No route decorators are required or supported. Handler resolution errors surface at application startup."
|
||||
"docstring": "Bind OpenAPI operations to FastAPI routes.\n\nArgs:\n app (fastapi.FastAPI):\n The FastAPI application instance to which routes will be added.\n spec (dict):\n Parsed OpenAPI 3.x specification dictionary.\n routes_module (module):\n Python module containing handler functions. Each handler's name MUST\n exactly match an OpenAPI `operationId`.\n\nRaises:\n MissingOperationHandler:\n If an `operationId` is missing from the spec or if no corresponding\n handler function exists in the routes module.\n\nNotes:\n **Responsibilities:**\n\n - Iterates through the OpenAPI specification paths and methods.\n - Resolves each `operationId` to a handler function, and registers\n a corresponding `APIRoute` on the FastAPI application.\n\n **Guarantees:**\n\n - Route registration is deterministic and spec-driven. No route\n decorators are required or supported. Handler resolution errors\n surface at application startup."
|
||||
},
|
||||
"OpenAPIFirstApp": {
|
||||
"name": "OpenAPIFirstApp",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.app.OpenAPIFirstApp",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIFirstApp', 38, 104)>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIFirstApp', 41, 115)>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"module": "openapi_first.binder",
|
||||
"content": {
|
||||
"path": "openapi_first.binder",
|
||||
"docstring": "OpenAPI-driven route binding for FastAPI.\n\n---\n\n## Summary\n\nThis module is responsible for translating an OpenAPI 3.x specification\ninto concrete FastAPI routes. It enforces a strict one-to-one mapping\nbetween OpenAPI operations and Python handler functions using operationId.\n\nNotes:\n **Core Responsibility:**\n\n - Read path + method definitions from an OpenAPI specification\n - Resolve each operationId to a Python callable\n - Register routes with FastAPI using APIRoute\n - Fail fast when contract violations are detected\n\n **Design Constraints:**\n\n - All routes MUST be declared in the OpenAPI specification\n - All OpenAPI operations MUST define an operationId\n - Every operationId MUST resolve to a handler function\n - Handlers are plain Python callables (no decorators required)\n - No implicit route creation or inference is allowed\n\n **Constraints:**\n\n - This module intentionally does NOT: Perform request or response validation, generate Pydantic models, modify FastAPI dependency injection, or interpret OpenAPI semantics beyond routing metadata.",
|
||||
"docstring": "# Summary\n\nOpenAPI-driven route binding for FastAPI.\n\nThis module is responsible for translating an OpenAPI 3.x specification\ninto concrete FastAPI routes. It enforces a strict one-to-one mapping\nbetween OpenAPI operations and Python handler functions using `operationId`.\n\nNotes:\n **Core Responsibility:**\n\n - Read path + method definitions from an OpenAPI specification.\n - Resolve each `operationId` to a Python callable.\n - Register routes with FastAPI using `APIRoute`.\n - Fail fast when contract violations are detected.\n\n **Design Constraints:**\n\n - All routes MUST be declared in the OpenAPI specification.\n - All OpenAPI operations MUST define an `operationId`.\n - Every `operationId` MUST resolve to a handler function.\n - Handlers are plain Python callables (no decorators required).\n - No implicit route creation or inference is allowed.\n\n **Constraints:**\n\n - This module intentionally does NOT:\n - Perform request or response validation.\n - Generate Pydantic models.\n - Modify FastAPI dependency injection.\n - Interpret OpenAPI semantics beyond routing metadata.",
|
||||
"objects": {
|
||||
"APIRoute": {
|
||||
"name": "APIRoute",
|
||||
@@ -16,14 +16,14 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.binder.MissingOperationHandler",
|
||||
"signature": "<bound method Alias.signature of Alias('MissingOperationHandler', 'openapi_first.errors.MissingOperationHandler')>",
|
||||
"docstring": "Raised when an OpenAPI operation cannot be resolved to a handler.\n\nNotes:\n **Scenarios:**\n\n - An OpenAPI operation does not define an operationId\n - An operationId is defined but no matching function exists in the provided routes module\n\n **Guarantees:**\n\n - This represents a violation of the OpenAPI-first contract and indicates that the specification and implementation are out of sync"
|
||||
"docstring": "Raised when an OpenAPI operation cannot be resolved to a handler.\n\nNotes:\n **Scenarios:**\n\n - An OpenAPI operation does not define an `operationId`.\n - An `operationId` is defined but no matching function exists in\n the provided routes module.\n\n **Guarantees:**\n\n - This represents a violation of the OpenAPI-first contract and\n indicates that the specification and implementation are out of\n sync."
|
||||
},
|
||||
"bind_routes": {
|
||||
"name": "bind_routes",
|
||||
"kind": "function",
|
||||
"path": "openapi_first.binder.bind_routes",
|
||||
"signature": "<bound method Function.signature of Function('bind_routes', 38, 93)>",
|
||||
"docstring": "Bind OpenAPI operations to FastAPI routes.\n\nArgs:\n app (fastapi.FastAPI):\n The FastAPI application instance to which routes will be added.\n spec (dict):\n Parsed OpenAPI 3.x specification dictionary.\n routes_module (module):\n Python module containing handler functions. Each handler's name MUST exactly match an OpenAPI operationId.\n\nRaises:\n MissingOperationHandler:\n If an operationId is missing from the spec or if no corresponding handler function exists in the routes module.\n\nNotes:\n **Responsibilities:**\n\n - Iterates through the OpenAPI specification paths and methods\n - Resolves each operationId to a handler function, and registers a corresponding APIRoute on the FastAPI application\n\n **Guarantees:**\n\n - Route registration is deterministic and spec-driven. No route decorators are required or supported. Handler resolution errors surface at application startup."
|
||||
"signature": "<bound method Function.signature of Function('bind_routes', 40, 100)>",
|
||||
"docstring": "Bind OpenAPI operations to FastAPI routes.\n\nArgs:\n app (fastapi.FastAPI):\n The FastAPI application instance to which routes will be added.\n spec (dict):\n Parsed OpenAPI 3.x specification dictionary.\n routes_module (module):\n Python module containing handler functions. Each handler's name MUST\n exactly match an OpenAPI `operationId`.\n\nRaises:\n MissingOperationHandler:\n If an `operationId` is missing from the spec or if no corresponding\n handler function exists in the routes module.\n\nNotes:\n **Responsibilities:**\n\n - Iterates through the OpenAPI specification paths and methods.\n - Resolves each `operationId` to a handler function, and registers\n a corresponding `APIRoute` on the FastAPI application.\n\n **Guarantees:**\n\n - Route registration is deterministic and spec-driven. No route\n decorators are required or supported. Handler resolution errors\n surface at application startup."
|
||||
},
|
||||
"Any": {
|
||||
"name": "Any",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"module": "openapi_first.client",
|
||||
"content": {
|
||||
"path": "openapi_first.client",
|
||||
"docstring": "OpenAPI-first HTTP client for contract-driven services.\n\n---\n\n## Summary\n\nThis module provides `OpenAPIClient`, a thin, strict HTTP client that\nderives all callable operations directly from an OpenAPI 3.x specification.\n\nIt is the client counterpart to `OpenAPIFirstApp`.\n\nNotes:\n **Core Principles:**\n\n - The OpenAPI specification is the single source of truth\n - Each operationId becomes a callable Python method\n - No implicit schema mutation or inference\n - No code generation step\n - Minimal abstraction over httpx\n\n **Responsibilities:**\n\n - Parses an OpenAPI 3.x specification\n - Dynamically creates one callable per operationId\n - Enforces presence of servers, paths, and operationId\n - Formats path parameters safely\n - Handles JSON request bodies explicitly\n - Returns raw `httpx.Response` objects\n\n **Constraints:**\n\n - This module intentionally does NOT: Generate client code, validate request/response schemas, deserialize responses, retry requests, implement authentication helpers, or assume non-2xx responses are failures.",
|
||||
"docstring": "# Summary\n\nOpenAPI-first HTTP client for contract-driven services.\n\nThis module provides `OpenAPIClient`, a thin, strict HTTP client that\nderives all callable operations directly from an OpenAPI 3.x specification.\n\nIt is the client counterpart to `OpenAPIFirstApp`.\n\nNotes:\n **Core Principles:**\n\n - The OpenAPI specification is the single source of truth\n - Each operationId becomes a callable Python method\n - No implicit schema mutation or inference\n - No code generation step\n - Minimal abstraction over httpx\n\n **Responsibilities:**\n\n - Parses an OpenAPI 3.x specification\n - Dynamically creates one callable per operationId\n - Enforces presence of servers, paths, and operationId\n - Formats path parameters safely\n - Handles JSON request bodies explicitly\n - Returns raw `httpx.Response` objects\n\n **Constraints:**\n\n - This module intentionally does NOT: Generate client code, validate request/response schemas, deserialize responses, retry requests, implement authentication helpers, or assume non-2xx responses are failures.",
|
||||
"objects": {
|
||||
"Any": {
|
||||
"name": "Any",
|
||||
@@ -51,21 +51,21 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.client.OpenAPIFirstError",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstError', 'openapi_first.errors.OpenAPIFirstError')>",
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI pipelines to catch and distinguish OpenAPI contract violations from unrelated runtime errors\n - All exceptions raised by the OpenAPI-first core should inherit from this type"
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI\n pipelines to catch and distinguish OpenAPI contract violations\n from unrelated runtime errors.\n - All exceptions raised by the OpenAPI-first core should inherit\n from this type."
|
||||
},
|
||||
"OpenAPIClientError": {
|
||||
"name": "OpenAPIClientError",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.client.OpenAPIClientError",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIClientError', 44, 47)>",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIClientError', 42, 45)>",
|
||||
"docstring": "Raised when an OpenAPI client operation fails."
|
||||
},
|
||||
"OpenAPIClient": {
|
||||
"name": "OpenAPIClient",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.client.OpenAPIClient",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIClient', 50, 257)>",
|
||||
"docstring": "OpenAPI-first HTTP client (httpx-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an OpenAPI 3.x specification. Each operationId becomes a method on the client instance.\n\n **Guarantees:**\n\n - One callable per operationId\n - Explicit parameters (path, query, headers, body)\n - No implicit schema inference or mutation\n - Returns raw `httpx.Response` objects\n - No response validation or deserialization\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIClient', 48, 257)>",
|
||||
"docstring": "OpenAPI-first HTTP client (`httpx`-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an\n OpenAPI 3.x specification. Each `operationId` becomes a method\n on the client instance.\n\n **Guarantees:**\n\n - One callable per `operationId`.\n - Explicit parameters (path, query, headers, body).\n - No implicit schema inference or mutation.\n - Returns raw `httpx.Response` objects.\n - No response validation or deserialization.\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"members": {
|
||||
"spec": {
|
||||
"name": "spec",
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
"module": "openapi_first.errors",
|
||||
"content": {
|
||||
"path": "openapi_first.errors",
|
||||
"docstring": "Exceptions for OpenAPI-first FastAPI applications.\n\n---\n\n## Summary\n\nThis module defines a small hierarchy of explicit, intention-revealing\nexceptions used to signal contract violations between an OpenAPI\nspecification and its Python implementation.\n\nNotes:\n **Design Principles:**\n\n - Errors represent programmer mistakes, not runtime conditions\n - All errors are raised during application startup\n - Messages are actionable and suitable for CI/CD output\n - Exceptions are explicit rather than reused from generic built-ins\n\n These errors should normally cause immediate application failure.",
|
||||
"docstring": "# Summary\n\nExceptions for OpenAPI-first FastAPI applications.\n\nThis module defines a small hierarchy of explicit, intention-revealing\nexceptions used to signal contract violations between an OpenAPI\nspecification and its Python implementation.\n\nNotes:\n **Design Principles:**\n\n - Errors represent programmer mistakes, not runtime conditions.\n - All errors are raised during application startup.\n - Messages are actionable and suitable for CI/CD output.\n - Exceptions are explicit rather than reused from generic built-ins.\n\n These errors should normally cause immediate application failure.",
|
||||
"objects": {
|
||||
"OpenAPIFirstError": {
|
||||
"name": "OpenAPIFirstError",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.errors.OpenAPIFirstError",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIFirstError', 23, 33)>",
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI pipelines to catch and distinguish OpenAPI contract violations from unrelated runtime errors\n - All exceptions raised by the OpenAPI-first core should inherit from this type"
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIFirstError', 21, 34)>",
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI\n pipelines to catch and distinguish OpenAPI contract violations\n from unrelated runtime errors.\n - All exceptions raised by the OpenAPI-first core should inherit\n from this type."
|
||||
},
|
||||
"MissingOperationHandler": {
|
||||
"name": "MissingOperationHandler",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.errors.MissingOperationHandler",
|
||||
"signature": "<bound method Class.signature of Class('MissingOperationHandler', 36, 74)>",
|
||||
"docstring": "Raised when an OpenAPI operation cannot be resolved to a handler.\n\nNotes:\n **Scenarios:**\n\n - An OpenAPI operation does not define an operationId\n - An operationId is defined but no matching function exists in the provided routes module\n\n **Guarantees:**\n\n - This represents a violation of the OpenAPI-first contract and indicates that the specification and implementation are out of sync"
|
||||
"signature": "<bound method Class.signature of Class('MissingOperationHandler', 37, 78)>",
|
||||
"docstring": "Raised when an OpenAPI operation cannot be resolved to a handler.\n\nNotes:\n **Scenarios:**\n\n - An OpenAPI operation does not define an `operationId`.\n - An `operationId` is defined but no matching function exists in\n the provided routes module.\n\n **Guarantees:**\n\n - This represents a violation of the OpenAPI-first contract and\n indicates that the specification and implementation are out of\n sync."
|
||||
},
|
||||
"Optional": {
|
||||
"name": "Optional",
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
"module": "openapi_first",
|
||||
"content": {
|
||||
"path": "openapi_first",
|
||||
"docstring": "FastAPI OpenAPI First — strict OpenAPI-first application bootstrap for FastAPI.\n\n---\n\n## Summary\n\nFastAPI OpenAPI First is a **contract-first infrastructure library** that\nenforces OpenAPI as the single source of truth for FastAPI services.\n\nThe library removes decorator-driven routing and replaces it with\ndeterministic, spec-driven application assembly. Every HTTP route,\nmethod, and operation is defined in OpenAPI first and bound to Python\nhandlers explicitly via operationId.\n\n---\n\n## Installation\n\nInstall using pip:\n\n pip install openapi-first\n\nOr with Poetry:\n\n poetry add openapi-first\n\n---\n\n## Quick start\n\nMinimal OpenAPI-first FastAPI application:\n\n from openapi_first import app\n import my_service.routes as routes\n\n api = app.OpenAPIFirstApp(\n openapi_path=\"openapi.yaml\",\n routes_module=routes,\n title=\"My Service\",\n version=\"1.0.0\",\n )\n\nOperationId-driven HTTP client:\n\n from openapi_first.loader import load_openapi\n from openapi_first.client import OpenAPIClient\n\n spec = load_openapi(\"openapi.yaml\")\n client = OpenAPIClient(spec)\n\n response = client.get_health()\n\n---\n\n## Architecture\n\nThe library is structured around four core responsibilities:\n\n- **loader**: Load and validate OpenAPI 3.x specifications (JSON/YAML)\n- **binder**: Bind OpenAPI operations to FastAPI routes via operationId\n- **app**: OpenAPI-first FastAPI application bootstrap\n- **client**: OpenAPI-first HTTP client driven by the same specification\n- **errors**: Explicit error hierarchy for contract violations\n\n---\n\n## Public API\n\nThe supported public API consists of the following top-level modules:\n\n- `openapi_first.app`\n- `openapi_first.binder`\n- `openapi_first.loader`\n- `openapi_first.client`\n- `openapi_first.errors`\n\n---\n\n## Design Guarantees\n\n- OpenAPI is the single source of truth\n- No undocumented routes can exist\n- No OpenAPI operation can exist without a handler or client callable\n- All contract violations fail at application startup or client creation\n- No hidden FastAPI magic or implicit behavior\n- Deterministic, testable application assembly\n\n---",
|
||||
"docstring": "# Summary\n\nFastAPI OpenAPI First — strict OpenAPI-first application bootstrap for FastAPI.\n\nFastAPI OpenAPI First is a **contract-first infrastructure library** that\nenforces OpenAPI as the single source of truth for FastAPI services.\n\nThe library removes decorator-driven routing and replaces it with\ndeterministic, spec-driven application assembly. Every HTTP route,\nmethod, and operation is defined in OpenAPI first and bound to Python\nhandlers explicitly via `operationId`.\n\n---\n\n# Installation\n\nInstall using pip:\n\n```bash\npip install openapi-first\n```\n\nOr with Poetry:\n\n```bash\npoetry add openapi-first\n```\n\n---\n\n# Quick Start\n\nMinimal OpenAPI-first FastAPI application:\n\n```python\nfrom 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\nOperationId-driven HTTP client:\n\n```python\nfrom openapi_first.loader import load_openapi\nfrom openapi_first.client import OpenAPIClient\n\nspec = load_openapi(\"openapi.yaml\")\nclient = OpenAPIClient(spec)\n\nresponse = client.get_health()\n```\n\n---\n\n# Architecture\n\nThe library is structured around four core responsibilities:\n\n- `loader`: Load and validate OpenAPI 3.x specifications (JSON/YAML).\n- `binder`: Bind OpenAPI operations to FastAPI routes via `operationId`.\n- `app`: OpenAPI-first FastAPI application bootstrap.\n- `client`: OpenAPI-first HTTP client driven by the same specification.\n- `errors`: Explicit error hierarchy for contract violations.\n\n---\n\n# Public API\n\nThe supported public API consists of the following top-level modules:\n\n- `openapi_first.app`\n- `openapi_first.binder`\n- `openapi_first.loader`\n- `openapi_first.client`\n- `openapi_first.errors`\n\n---\n\n# Design Guarantees\n\n- OpenAPI is the single source of truth.\n- No undocumented routes can exist.\n- No OpenAPI operation can exist without a handler or client callable.\n- All contract violations fail at application startup or client creation.\n- No hidden FastAPI magic or implicit behavior.\n- Deterministic, testable application assembly.\n\n---",
|
||||
"objects": {
|
||||
"app": {
|
||||
"name": "app",
|
||||
"kind": "module",
|
||||
"path": "openapi_first.app",
|
||||
"signature": null,
|
||||
"docstring": "OpenAPI-first application bootstrap for FastAPI.\n\n---\n\n## Summary\n\nThis module provides `OpenAPIFirstApp`, a thin but strict abstraction\nthat enforces OpenAPI as the single source of truth for a FastAPI service.\n\nNotes:\n **Core Principles:**\n\n - The OpenAPI specification (JSON or YAML) defines the entire API surface\n - Every operationId in the OpenAPI spec must have a corresponding Python handler function\n - Handlers are plain Python callables (no FastAPI decorators)\n - FastAPI route registration is derived exclusively from the spec\n - FastAPI's autogenerated OpenAPI schema is fully overridden\n\n **Responsibilities:**\n\n - Loads and validates an OpenAPI 3.x specification\n - Dynamically binds HTTP routes to handler functions using operationId\n - Registers routes with FastAPI at application startup\n - Ensures runtime behavior matches the OpenAPI contract exactly\n\n **Constraints:**\n\n - This module intentionally does NOT: Generate OpenAPI specs, generate client code, introduce a new framework or lifecycle, or alter FastAPI dependency injection semantics.",
|
||||
"docstring": "# Summary\n\nOpenAPI-first application bootstrap for FastAPI.\n\nThis module provides `OpenAPIFirstApp`, a thin but strict abstraction\nthat enforces OpenAPI as the single source of truth for a FastAPI service.\n\nNotes:\n **Core Principles:**\n\n - The OpenAPI specification (JSON or YAML) defines the entire API surface.\n - Every `operationId` in the OpenAPI spec must have a corresponding\n Python handler function.\n - Handlers are plain Python callables (no FastAPI decorators).\n - FastAPI route registration is derived exclusively from the spec.\n - FastAPI's autogenerated OpenAPI schema is fully overridden.\n\n **Responsibilities:**\n\n - Loads and validates an OpenAPI 3.x specification.\n - Dynamically binds HTTP routes to handler functions using `operationId`.\n - Registers routes with FastAPI at application startup.\n - Ensures runtime behavior matches the OpenAPI contract exactly.\n\n **Constraints:**\n\n - This module intentionally does NOT:\n - Generate OpenAPI specs.\n - Generate client code.\n - Introduce a new framework or lifecycle.\n - Alter FastAPI dependency injection semantics.",
|
||||
"members": {
|
||||
"FastAPI": {
|
||||
"name": "FastAPI",
|
||||
@@ -23,21 +23,21 @@
|
||||
"kind": "function",
|
||||
"path": "openapi_first.app.load_openapi",
|
||||
"signature": "<bound method Alias.signature of Alias('load_openapi', 'openapi_first.loader.load_openapi')>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"bind_routes": {
|
||||
"name": "bind_routes",
|
||||
"kind": "function",
|
||||
"path": "openapi_first.app.bind_routes",
|
||||
"signature": "<bound method Alias.signature of Alias('bind_routes', 'openapi_first.binder.bind_routes')>",
|
||||
"docstring": "Bind OpenAPI operations to FastAPI routes.\n\nArgs:\n app (fastapi.FastAPI):\n The FastAPI application instance to which routes will be added.\n spec (dict):\n Parsed OpenAPI 3.x specification dictionary.\n routes_module (module):\n Python module containing handler functions. Each handler's name MUST exactly match an OpenAPI operationId.\n\nRaises:\n MissingOperationHandler:\n If an operationId is missing from the spec or if no corresponding handler function exists in the routes module.\n\nNotes:\n **Responsibilities:**\n\n - Iterates through the OpenAPI specification paths and methods\n - Resolves each operationId to a handler function, and registers a corresponding APIRoute on the FastAPI application\n\n **Guarantees:**\n\n - Route registration is deterministic and spec-driven. No route decorators are required or supported. Handler resolution errors surface at application startup."
|
||||
"docstring": "Bind OpenAPI operations to FastAPI routes.\n\nArgs:\n app (fastapi.FastAPI):\n The FastAPI application instance to which routes will be added.\n spec (dict):\n Parsed OpenAPI 3.x specification dictionary.\n routes_module (module):\n Python module containing handler functions. Each handler's name MUST\n exactly match an OpenAPI `operationId`.\n\nRaises:\n MissingOperationHandler:\n If an `operationId` is missing from the spec or if no corresponding\n handler function exists in the routes module.\n\nNotes:\n **Responsibilities:**\n\n - Iterates through the OpenAPI specification paths and methods.\n - Resolves each `operationId` to a handler function, and registers\n a corresponding `APIRoute` on the FastAPI application.\n\n **Guarantees:**\n\n - Route registration is deterministic and spec-driven. No route\n decorators are required or supported. Handler resolution errors\n surface at application startup."
|
||||
},
|
||||
"OpenAPIFirstApp": {
|
||||
"name": "OpenAPIFirstApp",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.app.OpenAPIFirstApp",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIFirstApp', 38, 104)>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIFirstApp', 41, 115)>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
@@ -62,7 +62,7 @@
|
||||
"kind": "module",
|
||||
"path": "openapi_first.binder",
|
||||
"signature": null,
|
||||
"docstring": "OpenAPI-driven route binding for FastAPI.\n\n---\n\n## Summary\n\nThis module is responsible for translating an OpenAPI 3.x specification\ninto concrete FastAPI routes. It enforces a strict one-to-one mapping\nbetween OpenAPI operations and Python handler functions using operationId.\n\nNotes:\n **Core Responsibility:**\n\n - Read path + method definitions from an OpenAPI specification\n - Resolve each operationId to a Python callable\n - Register routes with FastAPI using APIRoute\n - Fail fast when contract violations are detected\n\n **Design Constraints:**\n\n - All routes MUST be declared in the OpenAPI specification\n - All OpenAPI operations MUST define an operationId\n - Every operationId MUST resolve to a handler function\n - Handlers are plain Python callables (no decorators required)\n - No implicit route creation or inference is allowed\n\n **Constraints:**\n\n - This module intentionally does NOT: Perform request or response validation, generate Pydantic models, modify FastAPI dependency injection, or interpret OpenAPI semantics beyond routing metadata.",
|
||||
"docstring": "# Summary\n\nOpenAPI-driven route binding for FastAPI.\n\nThis module is responsible for translating an OpenAPI 3.x specification\ninto concrete FastAPI routes. It enforces a strict one-to-one mapping\nbetween OpenAPI operations and Python handler functions using `operationId`.\n\nNotes:\n **Core Responsibility:**\n\n - Read path + method definitions from an OpenAPI specification.\n - Resolve each `operationId` to a Python callable.\n - Register routes with FastAPI using `APIRoute`.\n - Fail fast when contract violations are detected.\n\n **Design Constraints:**\n\n - All routes MUST be declared in the OpenAPI specification.\n - All OpenAPI operations MUST define an `operationId`.\n - Every `operationId` MUST resolve to a handler function.\n - Handlers are plain Python callables (no decorators required).\n - No implicit route creation or inference is allowed.\n\n **Constraints:**\n\n - This module intentionally does NOT:\n - Perform request or response validation.\n - Generate Pydantic models.\n - Modify FastAPI dependency injection.\n - Interpret OpenAPI semantics beyond routing metadata.",
|
||||
"members": {
|
||||
"APIRoute": {
|
||||
"name": "APIRoute",
|
||||
@@ -76,14 +76,14 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.binder.MissingOperationHandler",
|
||||
"signature": "<bound method Alias.signature of Alias('MissingOperationHandler', 'openapi_first.errors.MissingOperationHandler')>",
|
||||
"docstring": "Raised when an OpenAPI operation cannot be resolved to a handler.\n\nNotes:\n **Scenarios:**\n\n - An OpenAPI operation does not define an operationId\n - An operationId is defined but no matching function exists in the provided routes module\n\n **Guarantees:**\n\n - This represents a violation of the OpenAPI-first contract and indicates that the specification and implementation are out of sync"
|
||||
"docstring": "Raised when an OpenAPI operation cannot be resolved to a handler.\n\nNotes:\n **Scenarios:**\n\n - An OpenAPI operation does not define an `operationId`.\n - An `operationId` is defined but no matching function exists in\n the provided routes module.\n\n **Guarantees:**\n\n - This represents a violation of the OpenAPI-first contract and\n indicates that the specification and implementation are out of\n sync."
|
||||
},
|
||||
"bind_routes": {
|
||||
"name": "bind_routes",
|
||||
"kind": "function",
|
||||
"path": "openapi_first.binder.bind_routes",
|
||||
"signature": "<bound method Function.signature of Function('bind_routes', 38, 93)>",
|
||||
"docstring": "Bind OpenAPI operations to FastAPI routes.\n\nArgs:\n app (fastapi.FastAPI):\n The FastAPI application instance to which routes will be added.\n spec (dict):\n Parsed OpenAPI 3.x specification dictionary.\n routes_module (module):\n Python module containing handler functions. Each handler's name MUST exactly match an OpenAPI operationId.\n\nRaises:\n MissingOperationHandler:\n If an operationId is missing from the spec or if no corresponding handler function exists in the routes module.\n\nNotes:\n **Responsibilities:**\n\n - Iterates through the OpenAPI specification paths and methods\n - Resolves each operationId to a handler function, and registers a corresponding APIRoute on the FastAPI application\n\n **Guarantees:**\n\n - Route registration is deterministic and spec-driven. No route decorators are required or supported. Handler resolution errors surface at application startup."
|
||||
"signature": "<bound method Function.signature of Function('bind_routes', 40, 100)>",
|
||||
"docstring": "Bind OpenAPI operations to FastAPI routes.\n\nArgs:\n app (fastapi.FastAPI):\n The FastAPI application instance to which routes will be added.\n spec (dict):\n Parsed OpenAPI 3.x specification dictionary.\n routes_module (module):\n Python module containing handler functions. Each handler's name MUST\n exactly match an OpenAPI `operationId`.\n\nRaises:\n MissingOperationHandler:\n If an `operationId` is missing from the spec or if no corresponding\n handler function exists in the routes module.\n\nNotes:\n **Responsibilities:**\n\n - Iterates through the OpenAPI specification paths and methods.\n - Resolves each `operationId` to a handler function, and registers\n a corresponding `APIRoute` on the FastAPI application.\n\n **Guarantees:**\n\n - Route registration is deterministic and spec-driven. No route\n decorators are required or supported. Handler resolution errors\n surface at application startup."
|
||||
},
|
||||
"Any": {
|
||||
"name": "Any",
|
||||
@@ -178,7 +178,7 @@
|
||||
"kind": "module",
|
||||
"path": "openapi_first.client",
|
||||
"signature": null,
|
||||
"docstring": "OpenAPI-first HTTP client for contract-driven services.\n\n---\n\n## Summary\n\nThis module provides `OpenAPIClient`, a thin, strict HTTP client that\nderives all callable operations directly from an OpenAPI 3.x specification.\n\nIt is the client counterpart to `OpenAPIFirstApp`.\n\nNotes:\n **Core Principles:**\n\n - The OpenAPI specification is the single source of truth\n - Each operationId becomes a callable Python method\n - No implicit schema mutation or inference\n - No code generation step\n - Minimal abstraction over httpx\n\n **Responsibilities:**\n\n - Parses an OpenAPI 3.x specification\n - Dynamically creates one callable per operationId\n - Enforces presence of servers, paths, and operationId\n - Formats path parameters safely\n - Handles JSON request bodies explicitly\n - Returns raw `httpx.Response` objects\n\n **Constraints:**\n\n - This module intentionally does NOT: Generate client code, validate request/response schemas, deserialize responses, retry requests, implement authentication helpers, or assume non-2xx responses are failures.",
|
||||
"docstring": "# Summary\n\nOpenAPI-first HTTP client for contract-driven services.\n\nThis module provides `OpenAPIClient`, a thin, strict HTTP client that\nderives all callable operations directly from an OpenAPI 3.x specification.\n\nIt is the client counterpart to `OpenAPIFirstApp`.\n\nNotes:\n **Core Principles:**\n\n - The OpenAPI specification is the single source of truth\n - Each operationId becomes a callable Python method\n - No implicit schema mutation or inference\n - No code generation step\n - Minimal abstraction over httpx\n\n **Responsibilities:**\n\n - Parses an OpenAPI 3.x specification\n - Dynamically creates one callable per operationId\n - Enforces presence of servers, paths, and operationId\n - Formats path parameters safely\n - Handles JSON request bodies explicitly\n - Returns raw `httpx.Response` objects\n\n **Constraints:**\n\n - This module intentionally does NOT: Generate client code, validate request/response schemas, deserialize responses, retry requests, implement authentication helpers, or assume non-2xx responses are failures.",
|
||||
"members": {
|
||||
"Any": {
|
||||
"name": "Any",
|
||||
@@ -227,21 +227,21 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.client.OpenAPIFirstError",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstError', 'openapi_first.errors.OpenAPIFirstError')>",
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI pipelines to catch and distinguish OpenAPI contract violations from unrelated runtime errors\n - All exceptions raised by the OpenAPI-first core should inherit from this type"
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI\n pipelines to catch and distinguish OpenAPI contract violations\n from unrelated runtime errors.\n - All exceptions raised by the OpenAPI-first core should inherit\n from this type."
|
||||
},
|
||||
"OpenAPIClientError": {
|
||||
"name": "OpenAPIClientError",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.client.OpenAPIClientError",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIClientError', 44, 47)>",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIClientError', 42, 45)>",
|
||||
"docstring": "Raised when an OpenAPI client operation fails."
|
||||
},
|
||||
"OpenAPIClient": {
|
||||
"name": "OpenAPIClient",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.client.OpenAPIClient",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIClient', 50, 257)>",
|
||||
"docstring": "OpenAPI-first HTTP client (httpx-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an OpenAPI 3.x specification. Each operationId becomes a method on the client instance.\n\n **Guarantees:**\n\n - One callable per operationId\n - Explicit parameters (path, query, headers, body)\n - No implicit schema inference or mutation\n - Returns raw `httpx.Response` objects\n - No response validation or deserialization\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIClient', 48, 257)>",
|
||||
"docstring": "OpenAPI-first HTTP client (`httpx`-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an\n OpenAPI 3.x specification. Each `operationId` becomes a method\n on the client instance.\n\n **Guarantees:**\n\n - One callable per `operationId`.\n - Explicit parameters (path, query, headers, body).\n - No implicit schema inference or mutation.\n - Returns raw `httpx.Response` objects.\n - No response validation or deserialization.\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"members": {
|
||||
"spec": {
|
||||
"name": "spec",
|
||||
@@ -280,21 +280,21 @@
|
||||
"kind": "module",
|
||||
"path": "openapi_first.errors",
|
||||
"signature": null,
|
||||
"docstring": "Exceptions for OpenAPI-first FastAPI applications.\n\n---\n\n## Summary\n\nThis module defines a small hierarchy of explicit, intention-revealing\nexceptions used to signal contract violations between an OpenAPI\nspecification and its Python implementation.\n\nNotes:\n **Design Principles:**\n\n - Errors represent programmer mistakes, not runtime conditions\n - All errors are raised during application startup\n - Messages are actionable and suitable for CI/CD output\n - Exceptions are explicit rather than reused from generic built-ins\n\n These errors should normally cause immediate application failure.",
|
||||
"docstring": "# Summary\n\nExceptions for OpenAPI-first FastAPI applications.\n\nThis module defines a small hierarchy of explicit, intention-revealing\nexceptions used to signal contract violations between an OpenAPI\nspecification and its Python implementation.\n\nNotes:\n **Design Principles:**\n\n - Errors represent programmer mistakes, not runtime conditions.\n - All errors are raised during application startup.\n - Messages are actionable and suitable for CI/CD output.\n - Exceptions are explicit rather than reused from generic built-ins.\n\n These errors should normally cause immediate application failure.",
|
||||
"members": {
|
||||
"OpenAPIFirstError": {
|
||||
"name": "OpenAPIFirstError",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.errors.OpenAPIFirstError",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIFirstError', 23, 33)>",
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI pipelines to catch and distinguish OpenAPI contract violations from unrelated runtime errors\n - All exceptions raised by the OpenAPI-first core should inherit from this type"
|
||||
"signature": "<bound method Class.signature of Class('OpenAPIFirstError', 21, 34)>",
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI\n pipelines to catch and distinguish OpenAPI contract violations\n from unrelated runtime errors.\n - All exceptions raised by the OpenAPI-first core should inherit\n from this type."
|
||||
},
|
||||
"MissingOperationHandler": {
|
||||
"name": "MissingOperationHandler",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.errors.MissingOperationHandler",
|
||||
"signature": "<bound method Class.signature of Class('MissingOperationHandler', 36, 74)>",
|
||||
"docstring": "Raised when an OpenAPI operation cannot be resolved to a handler.\n\nNotes:\n **Scenarios:**\n\n - An OpenAPI operation does not define an operationId\n - An operationId is defined but no matching function exists in the provided routes module\n\n **Guarantees:**\n\n - This represents a violation of the OpenAPI-first contract and indicates that the specification and implementation are out of sync"
|
||||
"signature": "<bound method Class.signature of Class('MissingOperationHandler', 37, 78)>",
|
||||
"docstring": "Raised when an OpenAPI operation cannot be resolved to a handler.\n\nNotes:\n **Scenarios:**\n\n - An OpenAPI operation does not define an `operationId`.\n - An `operationId` is defined but no matching function exists in\n the provided routes module.\n\n **Guarantees:**\n\n - This represents a violation of the OpenAPI-first contract and\n indicates that the specification and implementation are out of\n sync."
|
||||
},
|
||||
"Optional": {
|
||||
"name": "Optional",
|
||||
@@ -310,7 +310,7 @@
|
||||
"kind": "module",
|
||||
"path": "openapi_first.loader",
|
||||
"signature": null,
|
||||
"docstring": "OpenAPI specification loading and validation utilities.\n\n---\n\n## Summary\n\nThis module is responsible for loading an OpenAPI 3.x specification\nfrom disk and validating it before it is used by the application.\n\nIt enforces the principle that an invalid or malformed OpenAPI document\nmust never reach the routing or runtime layers.\n\nNotes:\n **Design Principles:**\n\n - OpenAPI is treated as an authoritative contract\n - Invalid specifications fail fast at application startup\n - Supported formats are JSON and YAML\n - Validation errors are surfaced clearly and early\n\n **Constraints:**\n\n - This module intentionally does NOT: Modify the OpenAPI document, infer missing fields, generate models or code, or perform request/response validation at runtime.",
|
||||
"docstring": "# Summary\n\nOpenAPI specification loading and validation utilities.\n\nThis module is responsible for loading an OpenAPI 3.x specification\nfrom disk and validating it before it is used by the application.\n\nIt enforces the principle that an invalid or malformed OpenAPI document\nmust never reach the routing or runtime layers.\n\nNotes:\n **Design Principles:**\n\n - OpenAPI is treated as an authoritative contract.\n - Invalid specifications fail fast at application startup.\n - Supported formats are JSON and YAML.\n - Validation errors are surfaced clearly and early.\n\n **Constraints:**\n\n - This module intentionally does NOT:\n - Modify the OpenAPI document.\n - Infer missing fields.\n - Generate models or code.\n - Perform request/response validation at runtime.",
|
||||
"members": {
|
||||
"json": {
|
||||
"name": "json",
|
||||
@@ -352,21 +352,21 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.loader.OpenAPIFirstError",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstError', 'openapi_first.errors.OpenAPIFirstError')>",
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI pipelines to catch and distinguish OpenAPI contract violations from unrelated runtime errors\n - All exceptions raised by the OpenAPI-first core should inherit from this type"
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI\n pipelines to catch and distinguish OpenAPI contract violations\n from unrelated runtime errors.\n - All exceptions raised by the OpenAPI-first core should inherit\n from this type."
|
||||
},
|
||||
"OpenAPISpecLoadError": {
|
||||
"name": "OpenAPISpecLoadError",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.loader.OpenAPISpecLoadError",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPISpecLoadError', 37, 46)>",
|
||||
"docstring": "Raised when an OpenAPI specification cannot be loaded or validated.\n\nNotes:\n **Guarantees:**\n\n - This error indicates that the OpenAPI document is unreadable, malformed, or violates the OpenAPI 3.x specification"
|
||||
"signature": "<bound method Class.signature of Class('OpenAPISpecLoadError', 39, 49)>",
|
||||
"docstring": "Raised when an OpenAPI specification cannot be loaded or validated.\n\nNotes:\n **Guarantees:**\n\n - This error indicates that the OpenAPI document is unreadable,\n malformed, or violates the OpenAPI 3.x specification."
|
||||
},
|
||||
"load_openapi": {
|
||||
"name": "load_openapi",
|
||||
"kind": "function",
|
||||
"path": "openapi_first.loader.load_openapi",
|
||||
"signature": "<bound method Function.signature of Function('load_openapi', 49, 102)>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"signature": "<bound method Function.signature of Function('load_openapi', 52, 109)>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"Dict": {
|
||||
"name": "Dict",
|
||||
@@ -461,7 +461,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.crud_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
@@ -572,14 +572,14 @@
|
||||
"kind": "function",
|
||||
"path": "openapi_first.templates.crud_app.test_crud_app.load_openapi",
|
||||
"signature": "<bound method Alias.signature of Alias('load_openapi', 'openapi_first.loader.load_openapi')>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"OpenAPIClient": {
|
||||
"name": "OpenAPIClient",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.crud_app.test_crud_app.OpenAPIClient",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIClient', 'openapi_first.client.OpenAPIClient')>",
|
||||
"docstring": "OpenAPI-first HTTP client (httpx-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an OpenAPI 3.x specification. Each operationId becomes a method on the client instance.\n\n **Guarantees:**\n\n - One callable per operationId\n - Explicit parameters (path, query, headers, body)\n - No implicit schema inference or mutation\n - Returns raw `httpx.Response` objects\n - No response validation or deserialization\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"docstring": "OpenAPI-first HTTP client (`httpx`-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an\n OpenAPI 3.x specification. Each `operationId` becomes a method\n on the client instance.\n\n **Guarantees:**\n\n - One callable per `operationId`.\n - Explicit parameters (path, query, headers, body).\n - No implicit schema inference or mutation.\n - Returns raw `httpx.Response` objects.\n - No response validation or deserialization.\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"members": {
|
||||
"spec": {
|
||||
"name": "spec",
|
||||
@@ -683,7 +683,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.health_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
@@ -812,7 +812,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.model_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
@@ -992,14 +992,14 @@
|
||||
"kind": "function",
|
||||
"path": "openapi_first.templates.model_app.test_model_app.load_openapi",
|
||||
"signature": "<bound method Alias.signature of Alias('load_openapi', 'openapi_first.loader.load_openapi')>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"OpenAPIClient": {
|
||||
"name": "OpenAPIClient",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.model_app.test_model_app.OpenAPIClient",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIClient', 'openapi_first.client.OpenAPIClient')>",
|
||||
"docstring": "OpenAPI-first HTTP client (httpx-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an OpenAPI 3.x specification. Each operationId becomes a method on the client instance.\n\n **Guarantees:**\n\n - One callable per operationId\n - Explicit parameters (path, query, headers, body)\n - No implicit schema inference or mutation\n - Returns raw `httpx.Response` objects\n - No response validation or deserialization\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"docstring": "OpenAPI-first HTTP client (`httpx`-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an\n OpenAPI 3.x specification. Each `operationId` becomes a method\n on the client instance.\n\n **Guarantees:**\n\n - One callable per `operationId`.\n - Explicit parameters (path, query, headers, body).\n - No implicit schema inference or mutation.\n - Returns raw `httpx.Response` objects.\n - No response validation or deserialization.\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"members": {
|
||||
"spec": {
|
||||
"name": "spec",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"module": "openapi_first.loader",
|
||||
"content": {
|
||||
"path": "openapi_first.loader",
|
||||
"docstring": "OpenAPI specification loading and validation utilities.\n\n---\n\n## Summary\n\nThis module is responsible for loading an OpenAPI 3.x specification\nfrom disk and validating it before it is used by the application.\n\nIt enforces the principle that an invalid or malformed OpenAPI document\nmust never reach the routing or runtime layers.\n\nNotes:\n **Design Principles:**\n\n - OpenAPI is treated as an authoritative contract\n - Invalid specifications fail fast at application startup\n - Supported formats are JSON and YAML\n - Validation errors are surfaced clearly and early\n\n **Constraints:**\n\n - This module intentionally does NOT: Modify the OpenAPI document, infer missing fields, generate models or code, or perform request/response validation at runtime.",
|
||||
"docstring": "# Summary\n\nOpenAPI specification loading and validation utilities.\n\nThis module is responsible for loading an OpenAPI 3.x specification\nfrom disk and validating it before it is used by the application.\n\nIt enforces the principle that an invalid or malformed OpenAPI document\nmust never reach the routing or runtime layers.\n\nNotes:\n **Design Principles:**\n\n - OpenAPI is treated as an authoritative contract.\n - Invalid specifications fail fast at application startup.\n - Supported formats are JSON and YAML.\n - Validation errors are surfaced clearly and early.\n\n **Constraints:**\n\n - This module intentionally does NOT:\n - Modify the OpenAPI document.\n - Infer missing fields.\n - Generate models or code.\n - Perform request/response validation at runtime.",
|
||||
"objects": {
|
||||
"json": {
|
||||
"name": "json",
|
||||
@@ -44,21 +44,21 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.loader.OpenAPIFirstError",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstError', 'openapi_first.errors.OpenAPIFirstError')>",
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI pipelines to catch and distinguish OpenAPI contract violations from unrelated runtime errors\n - All exceptions raised by the OpenAPI-first core should inherit from this type"
|
||||
"docstring": "Base exception for all OpenAPI-first enforcement errors.\n\nNotes:\n **Responsibilities:**\n\n - This exception exists to allow callers, test suites, and CI\n pipelines to catch and distinguish OpenAPI contract violations\n from unrelated runtime errors.\n - All exceptions raised by the OpenAPI-first core should inherit\n from this type."
|
||||
},
|
||||
"OpenAPISpecLoadError": {
|
||||
"name": "OpenAPISpecLoadError",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.loader.OpenAPISpecLoadError",
|
||||
"signature": "<bound method Class.signature of Class('OpenAPISpecLoadError', 37, 46)>",
|
||||
"docstring": "Raised when an OpenAPI specification cannot be loaded or validated.\n\nNotes:\n **Guarantees:**\n\n - This error indicates that the OpenAPI document is unreadable, malformed, or violates the OpenAPI 3.x specification"
|
||||
"signature": "<bound method Class.signature of Class('OpenAPISpecLoadError', 39, 49)>",
|
||||
"docstring": "Raised when an OpenAPI specification cannot be loaded or validated.\n\nNotes:\n **Guarantees:**\n\n - This error indicates that the OpenAPI document is unreadable,\n malformed, or violates the OpenAPI 3.x specification."
|
||||
},
|
||||
"load_openapi": {
|
||||
"name": "load_openapi",
|
||||
"kind": "function",
|
||||
"path": "openapi_first.loader.load_openapi",
|
||||
"signature": "<bound method Function.signature of Function('load_openapi', 49, 102)>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"signature": "<bound method Function.signature of Function('load_openapi', 52, 109)>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"Dict": {
|
||||
"name": "Dict",
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.crud_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
@@ -178,14 +178,14 @@
|
||||
"kind": "function",
|
||||
"path": "openapi_first.templates.crud_app.test_crud_app.load_openapi",
|
||||
"signature": "<bound method Alias.signature of Alias('load_openapi', 'openapi_first.loader.load_openapi')>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"OpenAPIClient": {
|
||||
"name": "OpenAPIClient",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.crud_app.test_crud_app.OpenAPIClient",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIClient', 'openapi_first.client.OpenAPIClient')>",
|
||||
"docstring": "OpenAPI-first HTTP client (httpx-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an OpenAPI 3.x specification. Each operationId becomes a method on the client instance.\n\n **Guarantees:**\n\n - One callable per operationId\n - Explicit parameters (path, query, headers, body)\n - No implicit schema inference or mutation\n - Returns raw `httpx.Response` objects\n - No response validation or deserialization\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"docstring": "OpenAPI-first HTTP client (`httpx`-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an\n OpenAPI 3.x specification. Each `operationId` becomes a method\n on the client instance.\n\n **Guarantees:**\n\n - One callable per `operationId`.\n - Explicit parameters (path, query, headers, body).\n - No implicit schema inference or mutation.\n - Returns raw `httpx.Response` objects.\n - No response validation or deserialization.\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"members": {
|
||||
"spec": {
|
||||
"name": "spec",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.crud_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
"kind": "function",
|
||||
"path": "openapi_first.templates.crud_app.test_crud_app.load_openapi",
|
||||
"signature": "<bound method Alias.signature of Alias('load_openapi', 'openapi_first.loader.load_openapi')>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"OpenAPIClient": {
|
||||
"name": "OpenAPIClient",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.crud_app.test_crud_app.OpenAPIClient",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIClient', 'openapi_first.client.OpenAPIClient')>",
|
||||
"docstring": "OpenAPI-first HTTP client (httpx-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an OpenAPI 3.x specification. Each operationId becomes a method on the client instance.\n\n **Guarantees:**\n\n - One callable per operationId\n - Explicit parameters (path, query, headers, body)\n - No implicit schema inference or mutation\n - Returns raw `httpx.Response` objects\n - No response validation or deserialization\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"docstring": "OpenAPI-first HTTP client (`httpx`-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an\n OpenAPI 3.x specification. Each `operationId` becomes a method\n on the client instance.\n\n **Guarantees:**\n\n - One callable per `operationId`.\n - Explicit parameters (path, query, headers, body).\n - No implicit schema inference or mutation.\n - Returns raw `httpx.Response` objects.\n - No response validation or deserialization.\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"members": {
|
||||
"spec": {
|
||||
"name": "spec",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.health_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.health_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.crud_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
@@ -185,14 +185,14 @@
|
||||
"kind": "function",
|
||||
"path": "openapi_first.templates.crud_app.test_crud_app.load_openapi",
|
||||
"signature": "<bound method Alias.signature of Alias('load_openapi', 'openapi_first.loader.load_openapi')>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"OpenAPIClient": {
|
||||
"name": "OpenAPIClient",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.crud_app.test_crud_app.OpenAPIClient",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIClient', 'openapi_first.client.OpenAPIClient')>",
|
||||
"docstring": "OpenAPI-first HTTP client (httpx-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an OpenAPI 3.x specification. Each operationId becomes a method on the client instance.\n\n **Guarantees:**\n\n - One callable per operationId\n - Explicit parameters (path, query, headers, body)\n - No implicit schema inference or mutation\n - Returns raw `httpx.Response` objects\n - No response validation or deserialization\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"docstring": "OpenAPI-first HTTP client (`httpx`-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an\n OpenAPI 3.x specification. Each `operationId` becomes a method\n on the client instance.\n\n **Guarantees:**\n\n - One callable per `operationId`.\n - Explicit parameters (path, query, headers, body).\n - No implicit schema inference or mutation.\n - Returns raw `httpx.Response` objects.\n - No response validation or deserialization.\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"members": {
|
||||
"spec": {
|
||||
"name": "spec",
|
||||
@@ -296,7 +296,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.health_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
@@ -425,7 +425,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.model_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
@@ -605,14 +605,14 @@
|
||||
"kind": "function",
|
||||
"path": "openapi_first.templates.model_app.test_model_app.load_openapi",
|
||||
"signature": "<bound method Alias.signature of Alias('load_openapi', 'openapi_first.loader.load_openapi')>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"OpenAPIClient": {
|
||||
"name": "OpenAPIClient",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.model_app.test_model_app.OpenAPIClient",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIClient', 'openapi_first.client.OpenAPIClient')>",
|
||||
"docstring": "OpenAPI-first HTTP client (httpx-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an OpenAPI 3.x specification. Each operationId becomes a method on the client instance.\n\n **Guarantees:**\n\n - One callable per operationId\n - Explicit parameters (path, query, headers, body)\n - No implicit schema inference or mutation\n - Returns raw `httpx.Response` objects\n - No response validation or deserialization\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"docstring": "OpenAPI-first HTTP client (`httpx`-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an\n OpenAPI 3.x specification. Each `operationId` becomes a method\n on the client instance.\n\n **Guarantees:**\n\n - One callable per `operationId`.\n - Explicit parameters (path, query, headers, body).\n - No implicit schema inference or mutation.\n - Returns raw `httpx.Response` objects.\n - No response validation or deserialization.\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"members": {
|
||||
"spec": {
|
||||
"name": "spec",
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.model_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
@@ -261,14 +261,14 @@
|
||||
"kind": "function",
|
||||
"path": "openapi_first.templates.model_app.test_model_app.load_openapi",
|
||||
"signature": "<bound method Alias.signature of Alias('load_openapi', 'openapi_first.loader.load_openapi')>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"OpenAPIClient": {
|
||||
"name": "OpenAPIClient",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.model_app.test_model_app.OpenAPIClient",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIClient', 'openapi_first.client.OpenAPIClient')>",
|
||||
"docstring": "OpenAPI-first HTTP client (httpx-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an OpenAPI 3.x specification. Each operationId becomes a method on the client instance.\n\n **Guarantees:**\n\n - One callable per operationId\n - Explicit parameters (path, query, headers, body)\n - No implicit schema inference or mutation\n - Returns raw `httpx.Response` objects\n - No response validation or deserialization\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"docstring": "OpenAPI-first HTTP client (`httpx`-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an\n OpenAPI 3.x specification. Each `operationId` becomes a method\n on the client instance.\n\n **Guarantees:**\n\n - One callable per `operationId`.\n - Explicit parameters (path, query, headers, body).\n - No implicit schema inference or mutation.\n - Returns raw `httpx.Response` objects.\n - No response validation or deserialization.\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"members": {
|
||||
"spec": {
|
||||
"name": "spec",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.model_app.main.OpenAPIFirstApp",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIFirstApp', 'openapi_first.app.OpenAPIFirstApp')>",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses FastAPI and replaces manual route registration with OpenAPI-driven binding\n - All routes are derived from the provided OpenAPI specification, and each operationId is mapped to a Python function in the supplied routes module\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration\n - No OpenAPI operation can exist without a handler\n - Swagger UI and `/openapi.json` always reflect the provided spec\n - Handler functions remain framework-agnostic and testable\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"docstring": "FastAPI application enforcing OpenAPI-first design.\n\nNotes:\n **Responsibilities:**\n\n - `OpenAPIFirstApp` subclasses `FastAPI` and replaces manual route\n registration with OpenAPI-driven binding.\n - All routes are derived from the provided OpenAPI specification,\n and each `operationId` is mapped to a Python function in the\n supplied routes module.\n\n **Guarantees:**\n\n - No route can exist without an OpenAPI declaration.\n - No OpenAPI operation can exist without a handler.\n - Swagger UI and `/openapi.json` always reflect the provided spec.\n - Handler functions remain framework-agnostic and testable.\n\nExample:\n ```python\n from openapi_first import OpenAPIFirstApp\n import app.routes as routes\n\n app = OpenAPIFirstApp(\n openapi_path=\"app/openapi.json\",\n routes_module=routes,\n title=\"Example Service\",\n )\n ```",
|
||||
"members": {
|
||||
"openapi": {
|
||||
"name": "openapi",
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
"kind": "function",
|
||||
"path": "openapi_first.templates.model_app.test_model_app.load_openapi",
|
||||
"signature": "<bound method Alias.signature of Alias('load_openapi', 'openapi_first.loader.load_openapi')>",
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated using a strict OpenAPI schema validator\n - Any error results in an immediate exception, preventing application startup"
|
||||
"docstring": "Load and validate an OpenAPI 3.x specification from disk.\n\nArgs:\n path (str | Path):\n Filesystem path to an OpenAPI specification file. Supported\n extensions: `.json`, `.yaml`, `.yml`.\n\nReturns:\n dict[str, Any]:\n Parsed and validated OpenAPI specification.\n\nRaises:\n OpenAPISpecLoadError:\n If the file does not exist, cannot be parsed, or fails OpenAPI\n schema validation.\n\nNotes:\n **Guarantees:**\n\n - The specification is parsed based on file extension and validated\n using a strict OpenAPI schema validator.\n - Any error results in an immediate exception, preventing\n application startup."
|
||||
},
|
||||
"OpenAPIClient": {
|
||||
"name": "OpenAPIClient",
|
||||
"kind": "class",
|
||||
"path": "openapi_first.templates.model_app.test_model_app.OpenAPIClient",
|
||||
"signature": "<bound method Alias.signature of Alias('OpenAPIClient', 'openapi_first.client.OpenAPIClient')>",
|
||||
"docstring": "OpenAPI-first HTTP client (httpx-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an OpenAPI 3.x specification. Each operationId becomes a method on the client instance.\n\n **Guarantees:**\n\n - One callable per operationId\n - Explicit parameters (path, query, headers, body)\n - No implicit schema inference or mutation\n - Returns raw `httpx.Response` objects\n - No response validation or deserialization\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"docstring": "OpenAPI-first HTTP client (`httpx`-based).\n\nNotes:\n **Responsibilities:**\n\n - This client derives all callable methods directly from an\n OpenAPI 3.x specification. Each `operationId` becomes a method\n on the client instance.\n\n **Guarantees:**\n\n - One callable per `operationId`.\n - Explicit parameters (path, query, headers, body).\n - No implicit schema inference or mutation.\n - Returns raw `httpx.Response` objects.\n - No response validation or deserialization.\n\nExample:\n ```python\n from openapi_first import loader, client\n\n spec = loader.load_openapi(\"openapi.yaml\")\n\n api = client.OpenAPIClient(\n spec=spec,\n base_url=\"http://localhost:8000\",\n )\n\n # Call operationId: getUser\n response = api.getUser(\n path_params={\"user_id\": 123}\n )\n\n print(response.status_code)\n print(response.json())\n ```",
|
||||
"members": {
|
||||
"spec": {
|
||||
"name": "spec",
|
||||
|
||||
@@ -1,71 +1,77 @@
|
||||
"""
|
||||
# Summary
|
||||
|
||||
FastAPI OpenAPI First — strict OpenAPI-first application bootstrap for FastAPI.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
FastAPI OpenAPI First is a **contract-first infrastructure library** that
|
||||
enforces OpenAPI as the single source of truth for FastAPI services.
|
||||
|
||||
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.
|
||||
handlers explicitly via `operationId`.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
# Installation
|
||||
|
||||
Install using pip:
|
||||
|
||||
pip install openapi-first
|
||||
```bash
|
||||
pip install openapi-first
|
||||
```
|
||||
|
||||
Or with Poetry:
|
||||
|
||||
poetry add openapi-first
|
||||
```bash
|
||||
poetry add openapi-first
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick start
|
||||
# Quick Start
|
||||
|
||||
Minimal OpenAPI-first FastAPI application:
|
||||
|
||||
from openapi_first import app
|
||||
import my_service.routes as routes
|
||||
```python
|
||||
from openapi_first import app
|
||||
import my_service.routes as routes
|
||||
|
||||
api = app.OpenAPIFirstApp(
|
||||
api = app.OpenAPIFirstApp(
|
||||
openapi_path="openapi.yaml",
|
||||
routes_module=routes,
|
||||
title="My Service",
|
||||
version="1.0.0",
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
OperationId-driven HTTP client:
|
||||
|
||||
from openapi_first.loader import load_openapi
|
||||
from openapi_first.client import OpenAPIClient
|
||||
```python
|
||||
from openapi_first.loader import load_openapi
|
||||
from openapi_first.client import OpenAPIClient
|
||||
|
||||
spec = load_openapi("openapi.yaml")
|
||||
client = OpenAPIClient(spec)
|
||||
spec = load_openapi("openapi.yaml")
|
||||
client = OpenAPIClient(spec)
|
||||
|
||||
response = client.get_health()
|
||||
response = client.get_health()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
# Architecture
|
||||
|
||||
The library is structured around four core responsibilities:
|
||||
|
||||
- **loader**: Load and validate OpenAPI 3.x specifications (JSON/YAML)
|
||||
- **binder**: Bind OpenAPI operations to FastAPI routes via operationId
|
||||
- **app**: OpenAPI-first FastAPI application bootstrap
|
||||
- **client**: OpenAPI-first HTTP client driven by the same specification
|
||||
- **errors**: Explicit error hierarchy for contract violations
|
||||
- `loader`: Load and validate OpenAPI 3.x specifications (JSON/YAML).
|
||||
- `binder`: Bind OpenAPI operations to FastAPI routes via `operationId`.
|
||||
- `app`: OpenAPI-first FastAPI application bootstrap.
|
||||
- `client`: OpenAPI-first HTTP client driven by the same specification.
|
||||
- `errors`: Explicit error hierarchy for contract violations.
|
||||
|
||||
---
|
||||
|
||||
## Public API
|
||||
# Public API
|
||||
|
||||
The supported public API consists of the following top-level modules:
|
||||
|
||||
@@ -77,14 +83,14 @@ The supported public API consists of the following top-level modules:
|
||||
|
||||
---
|
||||
|
||||
## Design Guarantees
|
||||
# Design Guarantees
|
||||
|
||||
- OpenAPI is the single source of truth
|
||||
- No undocumented routes can exist
|
||||
- No OpenAPI operation can exist without a handler or client callable
|
||||
- All contract violations fail at application startup or client creation
|
||||
- No hidden FastAPI magic or implicit behavior
|
||||
- Deterministic, testable application assembly
|
||||
- OpenAPI is the single source of truth.
|
||||
- No undocumented routes can exist.
|
||||
- No OpenAPI operation can exist without a handler or client callable.
|
||||
- All contract violations fail at application startup or client creation.
|
||||
- No hidden FastAPI magic or implicit behavior.
|
||||
- Deterministic, testable application assembly.
|
||||
|
||||
---
|
||||
"""
|
||||
|
||||
@@ -1,32 +1,35 @@
|
||||
"""
|
||||
# Summary
|
||||
|
||||
OpenAPI-first application bootstrap for FastAPI.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
This module provides `OpenAPIFirstApp`, a thin but strict abstraction
|
||||
that enforces OpenAPI as the single source of truth for a FastAPI service.
|
||||
|
||||
Notes:
|
||||
**Core Principles:**
|
||||
|
||||
- The OpenAPI specification (JSON or YAML) defines the entire API surface
|
||||
- Every operationId in the OpenAPI spec must have a corresponding Python handler function
|
||||
- Handlers are plain Python callables (no FastAPI decorators)
|
||||
- FastAPI route registration is derived exclusively from the spec
|
||||
- FastAPI's autogenerated OpenAPI schema is fully overridden
|
||||
- The OpenAPI specification (JSON or YAML) defines the entire API surface.
|
||||
- Every `operationId` in the OpenAPI spec must have a corresponding
|
||||
Python handler function.
|
||||
- Handlers are plain Python callables (no FastAPI decorators).
|
||||
- FastAPI route registration is derived exclusively from the spec.
|
||||
- FastAPI's autogenerated OpenAPI schema is fully overridden.
|
||||
|
||||
**Responsibilities:**
|
||||
|
||||
- Loads and validates an OpenAPI 3.x specification
|
||||
- Dynamically binds HTTP routes to handler functions using operationId
|
||||
- Registers routes with FastAPI at application startup
|
||||
- Ensures runtime behavior matches the OpenAPI contract exactly
|
||||
- Loads and validates an OpenAPI 3.x specification.
|
||||
- Dynamically binds HTTP routes to handler functions using `operationId`.
|
||||
- Registers routes with FastAPI at application startup.
|
||||
- Ensures runtime behavior matches the OpenAPI contract exactly.
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- This module intentionally does NOT: Generate OpenAPI specs, generate client code, introduce a new framework or lifecycle, or alter FastAPI dependency injection semantics.
|
||||
- This module intentionally does NOT:
|
||||
- Generate OpenAPI specs.
|
||||
- Generate client code.
|
||||
- Introduce a new framework or lifecycle.
|
||||
- Alter FastAPI dependency injection semantics.
|
||||
"""
|
||||
|
||||
from fastapi import FastAPI
|
||||
@@ -42,15 +45,18 @@ class OpenAPIFirstApp(FastAPI):
|
||||
Notes:
|
||||
**Responsibilities:**
|
||||
|
||||
- `OpenAPIFirstApp` 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
|
||||
- `OpenAPIFirstApp` 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.
|
||||
|
||||
**Guarantees:**
|
||||
|
||||
- No route can exist without an OpenAPI declaration
|
||||
- No OpenAPI operation can exist without a handler
|
||||
- Swagger UI and `/openapi.json` always reflect the provided spec
|
||||
- Handler functions remain framework-agnostic and testable
|
||||
- No route can exist without an OpenAPI declaration.
|
||||
- No OpenAPI operation can exist without a handler.
|
||||
- Swagger UI and `/openapi.json` always reflect the provided spec.
|
||||
- Handler functions remain framework-agnostic and testable.
|
||||
|
||||
Example:
|
||||
```python
|
||||
@@ -77,15 +83,20 @@ class OpenAPIFirstApp(FastAPI):
|
||||
|
||||
Args:
|
||||
openapi_path (str):
|
||||
Filesystem path to the OpenAPI 3.x specification file. This specification is treated as the authoritative API contract.
|
||||
Filesystem path to the OpenAPI 3.x specification file. This
|
||||
specification is treated as the authoritative API contract.
|
||||
routes_module (module):
|
||||
Python module containing handler functions whose names correspond exactly to OpenAPI operationId values.
|
||||
Python module containing handler functions whose names correspond
|
||||
exactly to OpenAPI `operationId` values.
|
||||
**fastapi_kwargs (Any):
|
||||
Additional keyword arguments passed directly to `fastapi.FastAPI` (e.g., title, version, middleware, lifespan handlers).
|
||||
Additional keyword arguments passed directly to
|
||||
`fastapi.FastAPI` (e.g., title, version, middleware, lifespan
|
||||
handlers).
|
||||
|
||||
Raises:
|
||||
OpenAPIFirstError:
|
||||
If the OpenAPI specification is invalid, or if any declared operationId does not have a corresponding handler function.
|
||||
If the OpenAPI specification is invalid, or if any declared
|
||||
`operationId` does not have a corresponding handler function.
|
||||
"""
|
||||
# Initialize FastAPI normally
|
||||
super().__init__(**fastapi_kwargs)
|
||||
|
||||
@@ -1,33 +1,35 @@
|
||||
"""
|
||||
# Summary
|
||||
|
||||
OpenAPI-driven route binding for FastAPI.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
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.
|
||||
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
|
||||
- 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
|
||||
- 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, or interpret OpenAPI semantics beyond routing metadata.
|
||||
- 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
|
||||
@@ -45,21 +47,26 @@ def bind_routes(app, spec: dict, routes_module) -> None:
|
||||
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.
|
||||
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.
|
||||
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
|
||||
- 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.
|
||||
- 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", {})
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
"""
|
||||
# Summary
|
||||
|
||||
OpenAPI-first HTTP client for contract-driven services.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
This module provides `OpenAPIClient`, a thin, strict HTTP client that
|
||||
derives all callable operations directly from an OpenAPI 3.x specification.
|
||||
|
||||
@@ -49,20 +47,22 @@ class OpenAPIClientError(OpenAPIFirstError):
|
||||
|
||||
class OpenAPIClient:
|
||||
"""
|
||||
OpenAPI-first HTTP client (httpx-based).
|
||||
OpenAPI-first HTTP client (`httpx`-based).
|
||||
|
||||
Notes:
|
||||
**Responsibilities:**
|
||||
|
||||
- This client derives all callable methods directly from an OpenAPI 3.x specification. Each operationId becomes a method on the client instance.
|
||||
- This client derives all callable methods directly from an
|
||||
OpenAPI 3.x specification. Each `operationId` becomes a method
|
||||
on the client instance.
|
||||
|
||||
**Guarantees:**
|
||||
|
||||
- One callable per operationId
|
||||
- Explicit parameters (path, query, headers, body)
|
||||
- No implicit schema inference or mutation
|
||||
- Returns raw `httpx.Response` objects
|
||||
- No response validation or deserialization
|
||||
- One callable per `operationId`.
|
||||
- Explicit parameters (path, query, headers, body).
|
||||
- No implicit schema inference or mutation.
|
||||
- Returns raw `httpx.Response` objects.
|
||||
- No response validation or deserialization.
|
||||
|
||||
Example:
|
||||
```python
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
"""
|
||||
# Summary
|
||||
|
||||
Exceptions for OpenAPI-first FastAPI applications.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
This module defines a small hierarchy of explicit, intention-revealing
|
||||
exceptions used to signal contract violations between an OpenAPI
|
||||
specification and its Python implementation.
|
||||
@@ -12,10 +10,10 @@ specification and its Python implementation.
|
||||
Notes:
|
||||
**Design Principles:**
|
||||
|
||||
- Errors represent programmer mistakes, not runtime conditions
|
||||
- All errors are raised during application startup
|
||||
- Messages are actionable and suitable for CI/CD output
|
||||
- Exceptions are explicit rather than reused from generic built-ins
|
||||
- Errors represent programmer mistakes, not runtime conditions.
|
||||
- All errors are raised during application startup.
|
||||
- Messages are actionable and suitable for CI/CD output.
|
||||
- Exceptions are explicit rather than reused from generic built-ins.
|
||||
|
||||
These errors should normally cause immediate application failure.
|
||||
"""
|
||||
@@ -27,8 +25,11 @@ class OpenAPIFirstError(Exception):
|
||||
Notes:
|
||||
**Responsibilities:**
|
||||
|
||||
- This exception exists to allow callers, test suites, and CI pipelines to catch and distinguish OpenAPI contract violations from unrelated runtime errors
|
||||
- All exceptions raised by the OpenAPI-first core should inherit from this type
|
||||
- This exception exists to allow callers, test suites, and CI
|
||||
pipelines to catch and distinguish OpenAPI contract violations
|
||||
from unrelated runtime errors.
|
||||
- All exceptions raised by the OpenAPI-first core should inherit
|
||||
from this type.
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -40,12 +41,15 @@ class MissingOperationHandler(OpenAPIFirstError):
|
||||
Notes:
|
||||
**Scenarios:**
|
||||
|
||||
- An OpenAPI operation does not define an operationId
|
||||
- An operationId is defined but no matching function exists in the provided routes module
|
||||
- An OpenAPI operation does not define an `operationId`.
|
||||
- An `operationId` is defined but no matching function exists in
|
||||
the provided routes module.
|
||||
|
||||
**Guarantees:**
|
||||
|
||||
- This represents a violation of the OpenAPI-first contract and indicates that the specification and implementation are out of sync
|
||||
- This represents a violation of the OpenAPI-first contract and
|
||||
indicates that the specification and implementation are out of
|
||||
sync.
|
||||
"""
|
||||
|
||||
def __init__(self, *, path: str, method: str, operation_id: str | None = None):
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
"""
|
||||
# Summary
|
||||
|
||||
OpenAPI specification loading and validation utilities.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
This module is responsible for loading an OpenAPI 3.x specification
|
||||
from disk and validating it before it is used by the application.
|
||||
|
||||
@@ -14,14 +12,18 @@ must never reach the routing or runtime layers.
|
||||
Notes:
|
||||
**Design Principles:**
|
||||
|
||||
- OpenAPI is treated as an authoritative contract
|
||||
- Invalid specifications fail fast at application startup
|
||||
- Supported formats are JSON and YAML
|
||||
- Validation errors are surfaced clearly and early
|
||||
- OpenAPI is treated as an authoritative contract.
|
||||
- Invalid specifications fail fast at application startup.
|
||||
- Supported formats are JSON and YAML.
|
||||
- Validation errors are surfaced clearly and early.
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- This module intentionally does NOT: Modify the OpenAPI document, infer missing fields, generate models or code, or perform request/response validation at runtime.
|
||||
- This module intentionally does NOT:
|
||||
- Modify the OpenAPI document.
|
||||
- Infer missing fields.
|
||||
- Generate models or code.
|
||||
- Perform request/response validation at runtime.
|
||||
"""
|
||||
|
||||
import json
|
||||
@@ -41,7 +43,8 @@ class OpenAPISpecLoadError(OpenAPIFirstError):
|
||||
Notes:
|
||||
**Guarantees:**
|
||||
|
||||
- This error indicates that the OpenAPI document is unreadable, malformed, or violates the OpenAPI 3.x specification
|
||||
- This error indicates that the OpenAPI document is unreadable,
|
||||
malformed, or violates the OpenAPI 3.x specification.
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -52,7 +55,8 @@ def load_openapi(path: str | Path) -> dict[str, Any]:
|
||||
|
||||
Args:
|
||||
path (str | Path):
|
||||
Filesystem path to an OpenAPI specification file. Supported extensions: .json, .yaml, .yml.
|
||||
Filesystem path to an OpenAPI specification file. Supported
|
||||
extensions: `.json`, `.yaml`, `.yml`.
|
||||
|
||||
Returns:
|
||||
dict[str, Any]:
|
||||
@@ -60,13 +64,16 @@ def load_openapi(path: str | Path) -> dict[str, Any]:
|
||||
|
||||
Raises:
|
||||
OpenAPISpecLoadError:
|
||||
If the file does not exist, cannot be parsed, or fails OpenAPI schema validation.
|
||||
If the file does not exist, cannot be parsed, or fails OpenAPI
|
||||
schema validation.
|
||||
|
||||
Notes:
|
||||
**Guarantees:**
|
||||
|
||||
- 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
|
||||
- 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.
|
||||
"""
|
||||
spec_path = Path(path)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user