Skip to main content

Generate typed Python API clients from OpenAPI specs

Project description

Senzo

Senzo is a Python library for generating typed API clients from OpenAPI 3.x specifications. Unlike other client generators, Senzo is designed to support a number of HTTP clients (aiohttp, httpx, requests) for synchronous/async clients as well as several dataclass-like libraries such as Pydantic and msgspec.

Note: Senzo is still in development and is not yet ready for production use.

Using Senzo

Senzo is designed to be used programmatically through the Python package as opposed to a CLI tool. One can write a simple Python script in order to generate your client package. For example, if you wanted to build an API client that utilized Pydantic models for serialization and httpx for HTTP requests, you could do the following:

import json
import senzo

from senzo.backends.dataclass.pydantic import PydanticBackend
from senzo.backends.http.httpx import HttpxBackend

with open("openapi.json") as f:
    spec = json.load(f)

tree = senzo.generate_tree(
    spec,
    package_name="my_api",
    dataclass_backend=PydanticBackend(),
    http_backend=HttpxBackend(async_mode=True),
)
senzo.write_package(tree, output_dir="./my_api")

Senzo is designed to make it easy to generate synchronous and asynchronous clients for your API. For example, if you wanted to generate a synchronous client in addition to the asynchronous client, you could do the following:

import json
import senzo

from senzo.backends.dataclass.pydantic import PydanticBackend
from senzo.backends.http.httpx import HttpxBackend

with open("openapi.json") as f:
    spec = json.load(f)

tree = senzo.generate_tree(
    spec,
    package_name="my_api",
    dataclass_backend=PydanticBackend(),
    http_backend=HttpxBackend(async_mode=True),
)
senzo.write_package(tree, output_dir="./my_api")

tree = senzo.generate_tree(
    spec,
    package_name="my_sync_api",
    dataclass_backend=PydanticBackend(),
    http_backend=HttpxBackend(async_mode=False),
)
senzo.write_package(tree, output_dir="./my_sync_api")

The generated output is a small importable package (e.g. my_api/) containing:

  • client.py (HTTP client methods)
  • types/models.py (schema models)
  • _base.py (runtime helpers: errors, response wrapper, optional pagination/websocket support)
  • py.typed (PEP 561 marker)

Use the generated client

Exact method names depend on operationId and tag_style.

from my_api import Client

async with Client(base_url="https://api.example.com") as client:
    result = await client.some_operation(...)

Configuration

TagStyle

Controls how operations are organized:

  • TagStyle.FLAT (default): one Client class with all methods
  • TagStyle.FLAT_PREFIXED: one Client, methods prefixed with tag
  • TagStyle.GROUPED: Client exposes sub-clients per tag (uses the first tag only)
import senzo
tree = senzo.generate_tree(spec, tag_style=senzo.TagStyle.GROUPED, ...)

EnumStyle (inline enums)

Given an inline enum in your OpenAPI spec:

status:
  type: string
  enum: ["pending", "approved", "rejected"]
Style Generated Type
EnumStyle.LITERAL (default) Literal["pending", "approved", "rejected"]
EnumStyle.ENUM enum.Enum class
EnumStyle.STR_ENUM StrEnum class (Python 3.11+, recommended)
EnumStyle.STR str (no type safety)

Controls how inline OpenAPI enums (schemas with "enum": [...] but no named component) are represented in type annotations.

from senzo import generate_tree, EnumStyle

tree = generate_tree(spec, enum_style=EnumStyle.LITERAL, ...)

Named enum schemas under components/schemas are generated by the selected dataclass backend.

Backends

Dataclass (model) backends

  • senzo.backends.dataclass.pydantic.PydanticBackend
  • senzo.backends.dataclass.msgspec.MsgspecBackend

These backends control:

  • how schema objects are rendered (Pydantic models vs msgspec structs)
  • how JSON encoding/decoding code is emitted into the client

HTTP backends

  • senzo.backends.http.httpx.HttpxBackend(async_mode=...) (sync or async)
  • senzo.backends.http.aiohttp.AiohttpBackend() (async only)
  • senzo.backends.http.requests.RequestsBackend() (sync only)

Pagination (optional)

Senzo can generate an iterator helper <operation>_iter for operations that match a token-based pagination pattern.

Enable it via:

  • generator config: pagination={operation_id: {...}}, or
  • per-operation OpenAPI extension: x-senzo-pagination: {...}

Fields:

  • items (default "items"): response property containing the item list
  • next_token (default "next_page"): response property containing the next token
  • token_param (default "page_token"): query parameter name for the page token
  • limit_param (default "limit"): query parameter name for the page size

Limitations:

  • requires token_param and limit_param query parameters to exist
  • requires a success response type with items and next_token properties
  • does not paginate operations with a request body

WebSocket (optional; aiohttp backend only)

WebSocket endpoints are generated only when:

  • the OpenAPI operation has x-websocket: true, and
  • the selected HTTP backend supports websockets (currently AiohttpBackend)

Message types can be declared via x-websocket-messages:

paths:
  /ws/chat:
    get:
      operationId: connect_chat
      x-websocket: true
      x-websocket-messages:
        send:
          $ref: "#/components/schemas/ChatMessage"
        receive:
          $ref: "#/components/schemas/ServerEvent"

Hooks (generation-time; optional)

Senzo can bake calls to user-provided hook functions into the generated client. Hooks are configured at generation time using HooksConfig and are referenced by import path.

Supported hook slots:

  • pre_hook(inner, request, info) -> request
  • post_hook(inner, response, info) -> response
  • on_error(inner, error, info) -> None
  • on_result(inner, result, info) -> result

Acknowledgements

Senzo is heavily influenced by Progenitor, an OpenAPI client generator for Rust developed by Oxide.

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

senzo-0.1.0.tar.gz (410.7 kB view details)

Uploaded Source

Built Distribution

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

senzo-0.1.0-py3-none-any.whl (61.4 kB view details)

Uploaded Python 3

File details

Details for the file senzo-0.1.0.tar.gz.

File metadata

  • Download URL: senzo-0.1.0.tar.gz
  • Upload date:
  • Size: 410.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for senzo-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3fd8cf48ee7673a507f70b5e3b50159493360ec1877a00ae78af25c2c55e4770
MD5 cb7796e69860c99ea5bec6643d17f6ee
BLAKE2b-256 647108e69328e5b0a49ca99d254d2720e6dee5fecd66e7437952f72613877a42

See more details on using hashes here.

File details

Details for the file senzo-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: senzo-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 61.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for senzo-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a9d8c74f7f03e8f4db8878427594fc5eef6761b3dc7815f31936bd090cb3f87b
MD5 9b30b1611df0e88440dfd43ee14a5f77
BLAKE2b-256 5e868f031c497aea358c0f4ba8e68f9f23b13b8e0ffb7096585474aef56874a3

See more details on using hashes here.

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