Skip to main content

Autogenerated and fully typed OpenAPI Python clients with a developer-friendly, ergonomic interface.

Project description

openapi-python

QA Release PyPI

openapi-python generates typed Python API clients from OpenAPI specs, with a developer-friendly and ergonomic string-literal-based interface strongly inspired by openapi-typescript.

openapi-python demo

Installation

uv add openapi-python[httpx]  # Ships with an `httpx` transport
uv add openapi-python         # Bring your own transport (requests, asyncio, ...)

Client generation

Generate a client from an OpenAPI spec in openapi.json:

# Types + Protocol + HTTP transport
uv run openapi-python generate --spec ./openapi.json --out ./generated

# Types + Protocol
uv run openapi-python generate --spec ./openapi.json --out ./generated --protocol-only

Using generated clients

Generated clients expose route-specific callables with typed params, query, headers, body, and return values.

When using openapi-python[httpx]:

import httpx

from generated.my_client import AsyncClient, Client, DefaultAsyncTransport, DefaultTransport

sync_http = httpx.Client(
    base_url="https://api.example.com",
    headers={"authorization": "Bearer token"},
)
async_http = httpx.AsyncClient(
    base_url="https://api.example.com",
    headers={"authorization": "Bearer token"},
)

client = Client(
    transport=DefaultTransport(client=sync_http),
)
async_client = AsyncClient(
    transport=DefaultAsyncTransport(client=async_http),
)

book = client.get("/books/{book_id}")(params={"book_id": 1})
async_book = await async_client.get("/books/{book_id}")(params={"book_id": 1})

When using openapi-python, or for --protocol-only clients, provide your own transport:

from generated.my_client import Client

client = Client(transport=my_transport)
book = client.get("/books/{book_id}")(params={"book_id": 1})

See Custom transport on how to build a custom transport.

Protocols

Generated clients expose a transport protocol. You can plug in your own transport while keeping route-level typing guarantees.

Use --protocol-only to generate clients that don't ship with a built-in transport.

Protocol typing can be relaxed independently with --no-routes, --no-requests, and --no-responses.

Custom transport

Install openapi-python without extras and generate protocol-only code:

uv add openapi-python requests
uv run openapi-python generate \
  --spec ./openapi.json \
  --out ./generated \
  --package my_client \
  --protocol-only

Then provide an object that satisfies the generated Transport protocol:

from collections.abc import Mapping

import requests

from generated.my_client import Client


class RequestsTransport:
    def request(
        self,
        *,
        method: str,
        route: str,
        base_url: str,
        params: Mapping[str, object] | None,
        query: Mapping[str, object] | None,
        headers: Mapping[str, object] | None,
        request_media_type: str | None,
        body: object | None,
        response_media_type: str | None,
    ) -> object:
        request_kwargs = {"json": body}
        if request_media_type and request_media_type != "application/json":
            request_kwargs = {"data": body}
        response = requests.request(
            method=method.upper(),
            url=f"{base_url.rstrip('/')}{route.format(**(params or {}))}",
            params={key: str(value) for key, value in (query or {}).items()} or None,
            headers={key: str(value) for key, value in (headers or {}).items()} or None,
            **request_kwargs,
        )
        response.raise_for_status()
        if response.content:
            return response.json()
        return None


client = Client(
    transport=RequestsTransport(),
)
book = client.get("/books/{book_id}")(params={"book_id": 1})

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openapi_python-0.0.19.tar.gz (20.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openapi_python-0.0.19-py3-none-any.whl (27.4 kB view details)

Uploaded Python 3

File details

Details for the file openapi_python-0.0.19.tar.gz.

File metadata

  • Download URL: openapi_python-0.0.19.tar.gz
  • Upload date:
  • Size: 20.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for openapi_python-0.0.19.tar.gz
Algorithm Hash digest
SHA256 91166b07b7b5b7c7bea5bf46e524ec9c6a98e629ce99320bdce70276fafdc8b6
MD5 7ba9944b0d8274377b8330fd9f640bb5
BLAKE2b-256 c98c6053d705c0b89bf3755c8aed4b90d63a2b032d80d8956497974499b27c14

See more details on using hashes here.

Provenance

The following attestation bundles were made for openapi_python-0.0.19.tar.gz:

Publisher: release.yml on Minibrams/openapi-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file openapi_python-0.0.19-py3-none-any.whl.

File metadata

  • Download URL: openapi_python-0.0.19-py3-none-any.whl
  • Upload date:
  • Size: 27.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for openapi_python-0.0.19-py3-none-any.whl
Algorithm Hash digest
SHA256 d2ce1e5f45f0b0807ffba221dfcfb5f38e5563e44dd2e3f0afd08cdd9aa2e8b1
MD5 e1d9f33ab85b3c4688771d70259d5fdf
BLAKE2b-256 396d5ef2b4a65ed7a8618d9b46133702565076f892b162b7e44bdd5055226cfb

See more details on using hashes here.

Provenance

The following attestation bundles were made for openapi_python-0.0.19-py3-none-any.whl:

Publisher: release.yml on Minibrams/openapi-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page