Skip to main content

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.

Metadata

Release files for senzo 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for senzo 0.1.0
File Size Uploaded Provenance
senzo-0.1.0.tar.gz 410.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for senzo 0.1.0
File Interpreter ABI Platform
senzo-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 472.1 kB

Release files / senzo-0.1.0.tar.gz

Download URL senzo-0.1.0.tar.gz
Size 410.7 kB
Tags Source
SHA-256 checksum
How to use checksums
3fd8cf48ee7673a507f70b5e3b50159493360ec1877a00ae78af25c2c55e4770
BLAKE2b-256 checksum
How to use checksums
647108e69328e5b0a49ca99d254d2720e6dee5fecd66e7437952f72613877a42
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release files / senzo-0.1.0-py3-none-any.whl

Download URL senzo-0.1.0-py3-none-any.whl
Size 61.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a9d8c74f7f03e8f4db8878427594fc5eef6761b3dc7815f31936bd090cb3f87b
BLAKE2b-256 checksum
How to use checksums
5e868f031c497aea358c0f4ba8e68f9f23b13b8e0ffb7096585474aef56874a3
Upload date
Uploaded using Trusted Publishing?
What is 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}

Security for senzo 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page