Skip to main content

okapipy

okapipy

CI PyPI Python versions License Docs

Quality Gate Coverage Maintainability prek Checked with mypy Ruff

okapipy turns an OpenAPI 3.x document into a typed, hierarchical Python client — sync and async, sharing one tree. It lifts flat paths into Namespaces, Collections, Resources, Singletons, and Actions, then emits a project where regenerated base/ code carries the wiring and a one-shot user layer carries your customizations. Re-run the generator after a spec change and your code is left strictly alone.

The generated client is built to be navigated by hover: every class docstring opens with a short summary and lists the children you can reach from it — so client. in your IDE shows the whole tree without opening a single file.

📚 Full documentation: https://ffaraone.github.io/okapipy/

Install

okapipy needs Python 3.12+.

pip install okapipy            # or: uv add okapipy

The first NLP-dependent run downloads the spaCy en_core_web_sm model (~12 MB) into ./.spacy/. To pre-warm it (recommended in CI):

okapipy fetch-language en

Use

Sanity-check the parse:

okapipy parse openapi.yaml

Generate a full client project. okapipy reads its settings from a small manifest you commit alongside your consumer code; scaffold it with okapipy init:

okapipy init openapi.yaml \
    --package acme.commerce --client-class CommerceClient

That writes ./okapipy.yml. Then:

okapipy generate --output ./my-client

This writes a runnable Python project under ./my-client: a regenerated src/acme/commerce/base/ tree (transport, models, vendored runtime, per-node base classes) plus one-shot subclass stubs you can customize. Re-running the command refreshes base/ and leaves your edits alone.

Every project-level setting (shape, templates_dir, output) and every per-spec setting (rules, strip_prefix) lives in okapipy.yml — see the Quick start for the full schema. The CLI keeps only --manifest, --output, --check (CI dry-run that exits non-zero on any drift), and --quiet.

Customize

okapipy decides what each path segment is using POS tagging plus a small heuristic registry. When the heuristics get it wrong — or when you need to fence off pieces of the spec — you decorate the spec with x-okapipy-* extensions, or carry the same overrides in a project-local rules file (useful when you don't own the OpenAPI document). Rules-file values win on every conflict.

Point a specs[] entry at the rules file via rules: in okapipy.yml:

specs:
  - namespace: ''
    source: openapi.yaml
    rules: okapipy.rules.yaml

Then run okapipy generate as usual.

OpenAPI extensions

openapi: 3.0.0
info: { title: Commerce API, version: 1.0.0 }

# Declare top-level folders so single-noun segments aren't misclassified.
x-okapipy-ns:
  - commerce
  - commerce/internal
  - settings

paths:
  /commerce/orders:                      # Plural → Collection
    get: ...
    post: ...

  /commerce/orders/{id}/submit:          # Verb → Action (NLP catches it)
    post: ...

  /me:
    x-okapipy-kind: singleton            # Force singleton; NLP can't tell apart from a namespace
    get: ...
    patch: ...

  /staff:
    x-okapipy-kind: collection           # spaCy thinks "staff" is singular — override

  /currencies:
    x-okapipy-paginated: false           # Override pagination heuristic
    get: ...

  /internal/debug:
    x-okapipy-exclude: "*"               # Drop every method on this path

  /orders/{id}:
    x-okapipy-exclude: [DELETE]          # Or just selected methods
    get: ...
    delete: ...

Allowed x-okapipy-kind values: namespace, collection, singleton, action. Path-item hints classify the segment and propagate to other paths walking through the same prefix. Operation-level x-okapipy-kind: action is narrower — it routes a single method to a synthetic Action without changing the segment classification.

Rules file

The rules file mirrors the spec extensions and is local-only (no URLs). JSON or YAML, same shape:

x-okapipy-ns:
  - commerce
  - settings

paths:
  /staff:
    x-okapipy-kind: collection
  /me:
    x-okapipy-kind: singleton
  /orders/{id}/submit:
    post:
      x-okapipy-kind: action
  /currencies:
    x-okapipy-paginated: false
  /internal/debug:
    x-okapipy-exclude: "*"
  /orders/{id}:
    x-okapipy-exclude: [DELETE]

For more — code customization, custom strategies, template overrides, client construction options — see https://ffaraone.github.io/okapipy/.

Using the generated client

from acme.commerce import CommerceClient
import httpx

with CommerceClient(
    base_url="https://api.example.com",
    auth=httpx.BearerAuth("..."),
) as client:
    # Iterate a collection — pagination is automatic.
    for order in client.commerce.orders:
        print(order.id, order.total)

    # Filter, sort, page-size — fluent and order-independent.
    for order in (
        client.commerce.orders
        .filter(status="open")
        .order_by("-created_at")
        .page_size(50)
    ):
        ...

    # Resource lookup uses [id], not (id). Indexing is request-free;
    # .retrieve() issues the GET.
    order = client.commerce.orders["ord_42"].retrieve()

    # Sub-collections walk the tree naturally.
    line = client.commerce.orders["ord_42"].lines.create(
        body={"sku": "SKU-1", "qty": 2},
    )

    # Actions return an action object whose method is `.run()`.
    client.commerce.orders["ord_42"].submit.run()

    # Singletons (e.g. /me, /health) are direct attributes.
    me = client.me.retrieve()

    # Count without a full walk.
    total = client.commerce.orders.filter(status="open").count()

Async is the same shape, Async-prefixed:

from acme.commerce import AsyncCommerceClient

async with AsyncCommerceClient(base_url="https://api.example.com") as client:
    async for order in client.commerce.orders:
        ...
    me = await client.me.retrieve()

Contributing

Bug reports, feature requests, and pull requests are welcome via GitHub issues and pull requests.

To work on okapipy locally:

git clone https://github.com/ffaraone/okapipy.git
cd okapipy
uv sync
uv run okapipy fetch-language en              # one-time spaCy model download
uv run pytest                            # full suite + coverage
uv run mypy src/okapipy/parser           # strict type-check (parser)
uv run ruff check src tests              # lint

Before opening a PR, please ensure tests, type-check, and lint all pass. The internal design notes live under design/ — read the relevant spec and plan before changing parser, generator, or customization behavior. Coding and documentation conventions are in CLAUDE.md.

License

okapipy is released under the Apache License 2.0. You're free to use it commercially, modify it, and redistribute it; please keep the copyright notice and the license text intact.

Metadata

Release files for okapipy 0.4.5

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

Source distribution (sdist)

Source distribution for okapipy 0.4.5
File Size Uploaded Provenance
okapipy-0.4.5.tar.gz 2.1 MB With provenance Details

Built distribution (wheel)

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

Total release size: 2.3 MB

Release files / okapipy-0.4.5.tar.gz

Download URL okapipy-0.4.5.tar.gz
Size 2.1 MB
Tags Source
SHA-256 checksum
How to use checksums
1ddca3342c0f6381c86a1ef79a9b5f4530ec2fd1d03d6b4dd8173a5c7a2c9297
BLAKE2b-256 checksum
How to use checksums
4353a38426dedee14e0fca2cf75bd27086f191218a998c75e39a8e0910f6d274
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 9, 2026.

Transparency log

Release files / okapipy-0.4.5-py3-none-any.whl

Download URL okapipy-0.4.5-py3-none-any.whl
Size 186.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7a22eee5b222f4798b8434d73e03779bc651dc98ef2bf135e2e97e7c4e07e8c6
BLAKE2b-256 checksum
How to use checksums
23c185c55539cce4740575d3705579feafb6551dc706fc360b28d5983f5ca0d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 9, 2026.

Transparency log

Security for okapipy 0.4.5

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for okapipy-0.4.5.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 9, 2026.

Transparency log

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.

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