openapi-ts-fetch
Lightweight Python OpenAPI 3.x → TypeScript fetch client generator. Zero Java, zero npm — just Python 3.10+ and your OpenAPI spec.
A fast, single-file alternative to the 200MB+ Java openapi-generator-cli. Generates fully typed TypeScript fetch clients with the same output structure.
Features
- OpenAPI 3.0.3 & 3.1.x — handles both spec versions natively
- Remote & local specs — load from URLs or local JSON/YAML files
- Schema deduplication — identical schemas share a single model via content-hash
- Nested extraction — inline object properties and array items become named models
- Tag filtering — generate only the APIs you need with
--tags - Dry-run mode — validate spec and preview what would be generated
- No runtime dependencies — pure Python stdlib, TypeScript output uses only
fetch - Drop-in compatible — output matches the
openapi-generatorTypeScript-fetch structure
Installation
pip install openapi-ts-fetch
# Or with uv
uv tool install openapi-ts-fetch
Usage
# Generate full client from local spec
openapi-ts-fetch openapi.json ./src/api-client
# Generate from a remote URL
openapi-ts-fetch https://petstore3.swagger.io/api/v3/openapi.json ./src/api-client
# Generate only specific API tags (and their referenced models)
openapi-ts-fetch openapi.json ./src/api-client --tags users,orders
# Override BASE_PATH in generated runtime.ts
openapi-ts-fetch openapi.json ./src/api-client --base-path /api/v1
# Validate spec without generating (dry-run)
openapi-ts-fetch openapi.json ./src/api-client --dry-run
# Check version
openapi-ts-fetch --version
From Python
from openapi_ts_fetch import generate
model_files, api_files = generate("openapi.json", "./src/api-client", tag_filter={"shl"})
The package also exposes the pieces the generator is built from: SchemaRegistry
(inline-schema extraction and dedup), gen_model and gen_api (the two
emitters), and the naming helpers pascal, camel and operation_id.
Output Structure
src/api-client/
├── runtime.ts # Configuration, BaseAPI, middleware, fetch helpers
├── index.ts # Barrel exports
├── apis/
│ ├── index.ts
│ ├── UsersApi.ts # One class per OpenAPI tag
│ └── OrdersApi.ts
└── models/
├── index.ts
├── User.ts # Interface + FromJSON/ToJSON
└── CreateUserRequest.ts
Using the Generated Client
import { Configuration, UsersApi } from './api-client'
const config = new Configuration({
basePath: 'https://api.example.com',
accessToken: async () => getMyToken(),
})
const users = new UsersApi(config)
// Fully typed request and response
const user = await users.getUser({ id: '123' })
console.log(user.name)
Tag Filtering
When you only need a subset of your API in a particular app, use --tags to generate a lean client:
# Full API has 26 tags and 220 models, but your app only uses 'shl'
openapi-ts-fetch openapi.json ./src/api-client --tags shl
# Output: 1 API class, 3 models (only transitively referenced ones)
This is especially useful in monorepos where different apps consume different parts of the same backend API.
Comparison
| openapi-ts-fetch | openapi-generator-cli | |
|---|---|---|
| Runtime | Python 3.10+ (~1000 LOC) | Java 11+ (~200MB JAR) |
| Install | pip install or copy 2 files |
Docker / Java / npm wrapper |
| Speed | ~1s for 200+ models | ~10s+ for same spec |
| Tag filtering | Built-in --tags |
Templates + config |
| Schema dedup | Content-hash based | Limited |
| Output | TypeScript fetch | TypeScript fetch (+ 40 others) |
Schema Naming Strategy
titlefield — uses the schema'stitleif present (frameworks like Elysia/TypeBox set these automatically)- Content-hash dedup — identical schemas with the same title share a single model
- Nested objects —
ParentName+PropertyName(PascalCase) - Array items —
ParentName+PropertyName+"Inner" - Fallback —
OperationId+StatusCode+"Response"/"Request"
License
MIT — Max Health Inc.
Release files for openapi-ts-fetch 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| openapi_ts_fetch-0.3.0.tar.gz | 27.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| openapi_ts_fetch-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.7 kB
Release files / openapi_ts_fetch-0.3.0.tar.gz
| Download URL | openapi_ts_fetch-0.3.0.tar.gz |
|---|---|
| Size | 27.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ceb2e580faea99f4d5092d307a7a82c8b334ddc2991f254b6f24246c7161c731
|
|
BLAKE2b-256 checksum How to use checksums |
cf1a9113a4a7db7f21698bcdc20ad1cd84540ec03e82d05a40994445e38baa85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 27, 2026.
Transparency logRelease files / openapi_ts_fetch-0.3.0-py3-none-any.whl
| Download URL | openapi_ts_fetch-0.3.0-py3-none-any.whl |
|---|---|
| Size | 23.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
34283db123ece0769174007876bba9e0730bc10a0f14ef71a823732056bc4de4
|
|
BLAKE2b-256 checksum How to use checksums |
bb883624e49e32e72e80e988461f01cadf32070f49b65999cda8a1b636b8dafb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 27, 2026.
Transparency log