Generated Clients¶
Responder can generate small API clients from the OpenAPI schema it already builds from your routes, markers, and Pydantic models.
Enable OpenAPI on your app, then write a Python client module:
import responder
api = responder.API(title="Service", version="1", openapi="3.0.2")
@api.get("/users/{user_id}", operation_id="get_user")
def get_user(req, resp, *, user_id: int):
resp.media = {"id": user_id}
api.generate_client("clients/service.py", class_name="ServiceClient")
Use language= to generate clients for other ecosystems:
api.generate_client(
"clients/service.ts",
class_name="ServiceClient",
language="typescript",
)
api.generate_client("clients/service.js", language="javascript")
api.generate_client("clients/service.rb", language="ruby")
api.generate_client("clients/ServiceClient.php", language="php")
Supported languages are python, javascript, typescript, ruby,
and php. The generated modules have no Responder runtime dependency. Python,
Ruby, and PHP clients use standard libraries for HTTP calls; JavaScript and
TypeScript clients use fetch.
When your OpenAPI schema includes component models, Python and TypeScript clients also generate model types. Request bodies use the request model type, and methods return the documented success response type:
class ItemIn(TypedDict):
name: str
class ItemOut(TypedDict):
id: int
name: str
def create_item(self, body: ItemIn | None = None) -> ItemOut:
...
export interface ItemIn {
name: string;
}
export interface ItemOut {
id: number;
name: string;
}
create_item(body: ItemIn | null = null): Promise<ItemOut>
from clients.service import ServiceClient
client = ServiceClient("https://api.example.com", bearer_token="secret")
user = client.get_user(42)
For Python tests, pass Responder’s in-process test client. This lets your generated client exercise the app without a listening socket:
client = ServiceClient(session=api.requests)
assert client.get_user(42) == {"id": 42}
For a fuller example, examples/atelier.py is the canonical contract app:
the test suite validates its OpenAPI document, generates a Python client from
it, and drives that client against the in-process API.
Python, JavaScript, and TypeScript clients can also validate JSON payloads at
runtime. Validation is off by default; pass validate=True in Python or
validate: true in JavaScript/TypeScript to check outgoing request bodies and
successful responses against the generated OpenAPI schemas:
client = ServiceClient(session=api.requests, validate=True)
client.create_item({"name": "tea"})
If validation fails, the client raises APIValidationError with the schema
path that failed, such as response.id expected integer.
When a request fails and the server returns application/problem+json, the
generated APIError exposes the parsed payload as problem. Python clients
also provide title, detail, and errors convenience attributes:
try:
client.get_user(404)
except APIError as exc:
assert exc.problem["status"] == 404
print(exc.title)
API.generate_client(...) returns source code when no path is supplied:
source = api.generate_client(class_name="ServiceClient")
typescript = api.generate_client(
class_name="ServiceClient",
language="typescript",
)
The lower-level helpers are available from responder.ext.clientgen:
from responder.ext.clientgen import generate_client, write_client
source = generate_client(api.openapi, class_name="ServiceClient")
write_client(api.openapi, "clients/service.py", class_name="ServiceClient")
write_client(
api.openapi,
"clients/service.ts",
class_name="ServiceClient",
language="typescript",
)
The command-line interface can generate clients from an import target too:
responder client app:api > clients/service.py
responder client --lang typescript --class-name ServiceClient \
--output clients/service.ts app:api
Generated clients include:
method signatures generated from path and query parameters,
JSON request-body support,
bearer, basic, and API-key header helpers,
structured
APIErrorexceptions for non-2xx responses,opt-in
APIValidationErrorchecks for JSON request/response schemas,real HTTP transport for network calls,
Python
TypedDictmodels and TypeScript interfaces for OpenAPI components,typed Python and TypeScript parameters/returns where schemas are available,
a Python-only
session=hook for Starlette/httpx-style clients in tests.