A simple OpenAPI client generator using AST transformation
Project description
openapi-to-httpx
An OpenAPI client generator for Python that uses AST transformation to create type-safe HTTP clients.
AST generation of code is a pain, which is why most generation libraries like openapi-generator rely on mustache/jinja code template to populate. But code templates are brittle, rely on manually stringing together whitespace in languages like Python, and have so many edge cases codified in the template they'll make your head spin. Luckily LLMs have very strong performance in writing AST parsers for input code.
Unlike traditional code generators that use templates, this tool:
- Defines an ideal, idiomatic Python client structure
- Uses AST (Abstract Syntax Tree) manipulation to inject OpenAPI-specific details
- Generates clean, type-safe code with full IDE support
This is an experiment in programming 95% of this AST logic via LLMs and agents alone. This trades some code interpretability for speed of development - but we figure that in the AST parsing game, this is best left for machines versus human rules anyway.
Installation
uv sync
Quick Start
# Generate from a URL
uv run openapi-to-httpx https://api.example.com/openapi.json -o ./my_client
# Generate from a local file
uv run openapi-to-httpx ./my-api.yaml -o ./my_client
# Use the built-in Petstore example
uv run openapi-to-httpx --petstore -o ./petstore_client
Generated Client Usage
from my_client import APIClient
from my_client.models import Pet
# Initialize the client
client = APIClient(
base_url="https://api.example.com",
api_key="your-api-key" # or bearer_token="..."
)
# No context manager needed!
# All methods return Response[T] with data, status_code, headers, response_time
response = client.get_pet_by_id(123)
print(f"Pet name: {response.data.name}")
print(f"Response time: {response.response_time}s")
# Create a new pet
new_pet = Pet(name="Fluffy", photoUrls=["https://..."])
response = client.add_pet(new_pet)
# List pets
response = client.find_pets_by_status(status="available")
for pet in response.data:
print(pet.name)
# Async usage (when implemented)
response = await client.aget_pet_by_id(123)
Features
- Type-safe: Full type hints for all parameters and return values
- Idiomatic Python: Direct method calls, snake_case naming, optional parameters
- Rich responses: Returns Response[T] with data, status_code, headers, and timing
- Error handling: Custom exceptions for common HTTP errors
- Pydantic models: Auto-generated models with validation
- Clean separation: Models in separate file for better organization
- Connection pooling: Reuses httpx clients for efficiency
- CI/CD Ready: GitHub Actions workflow with linting, type checking, and tests
How It Works
- Template Definition (
ideal_client.py): Defines the perfect Python HTTP client interface - AST Parsing: Parses the template into an Abstract Syntax Tree
- Schema Analysis: Reads the OpenAPI specification
- AST Transformation: Injects endpoints, models, and parameters into the AST
- Code Generation: Outputs clean, formatted Python code
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openapi_to_httpx-0.1.1.tar.gz.
File metadata
- Download URL: openapi_to_httpx-0.1.1.tar.gz
- Upload date:
- Size: 652.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41504be6148c3113837278f4d13a997b616887f7311f99ee787c9d6238a953a5
|
|
| MD5 |
47eb584a1f198ef37c7d6f8e34a3da11
|
|
| BLAKE2b-256 |
fda6e6d3fdeea8948fa36982b045c46c541648698e11b7e0225c367413bf60cb
|
Provenance
The following attestation bundles were made for openapi_to_httpx-0.1.1.tar.gz:
Publisher:
ci.yml on piercefreeman/openapi-to-httpx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openapi_to_httpx-0.1.1.tar.gz -
Subject digest:
41504be6148c3113837278f4d13a997b616887f7311f99ee787c9d6238a953a5 - Sigstore transparency entry: 299226593
- Sigstore integration time:
-
Permalink:
piercefreeman/openapi-to-httpx@613f8e8fb9689dc223c7399c28768be693416739 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/piercefreeman
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@613f8e8fb9689dc223c7399c28768be693416739 -
Trigger Event:
push
-
Statement type:
File details
Details for the file openapi_to_httpx-0.1.1-py3-none-any.whl.
File metadata
- Download URL: openapi_to_httpx-0.1.1-py3-none-any.whl
- Upload date:
- Size: 651.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e7671938e48e861d5cf7e71d2945442d49eb9aad397067d1a9793721dd1cbffd
|
|
| MD5 |
b1d1623a29c1e8fa530c5396c68a8388
|
|
| BLAKE2b-256 |
8b65149df2060829e8606a1ff50a4df5cbb75adabf49cf463ae227f28bdce2c5
|
Provenance
The following attestation bundles were made for openapi_to_httpx-0.1.1-py3-none-any.whl:
Publisher:
ci.yml on piercefreeman/openapi-to-httpx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openapi_to_httpx-0.1.1-py3-none-any.whl -
Subject digest:
e7671938e48e861d5cf7e71d2945442d49eb9aad397067d1a9793721dd1cbffd - Sigstore transparency entry: 299226623
- Sigstore integration time:
-
Permalink:
piercefreeman/openapi-to-httpx@613f8e8fb9689dc223c7399c28768be693416739 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/piercefreeman
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@613f8e8fb9689dc223c7399c28768be693416739 -
Trigger Event:
push
-
Statement type: