Generate TypeScript clients from OpenAPI specifications
Project description
openapi-ts-client
Generate TypeScript clients from OpenAPI 3.x specifications.
Features
- Supports OpenAPI 3.0.x and 3.1.x specifications
- Three output formats: Fetch API, Axios, and Angular
- Fully typed TypeScript output with models and API classes
- Accepts specs as Python dictionaries or JSON strings
- Automatic validation of OpenAPI specifications
Why This Project?
Python backend frameworks like FastAPI and django-ninja already generate OpenAPI specs from your type hints. This library enables those frameworks to take the next step: generating TypeScript clients that mirror your backend types exactly. Framework authors can integrate openapi-ts-client to give their users end-to-end type safety with zero manual type definitions.
Installation
pip install openapi-ts-client
Or install from source:
git clone https://github.com/fa-krug/openapi-ts-client.git
cd openapi-ts-client
pip install -e .
CLI Usage
# Generate from file
openapi-ts-client ./openapi.json
# Specify output format and directory
openapi-ts-client ./openapi.json -f axios -o ./src/api
# Generate from URL
openapi-ts-client https://api.example.com/openapi.json
# Generate from stdin
cat openapi.json | openapi-ts-client -
# Use config file
openapi-ts-client --config ./my-config.json
# Verbose output
openapi-ts-client ./openapi.json -v
Config File
Create openapi-ts-client.json for repeated use:
{
"clients": [
{
"input": "./specs/users-api.json",
"format": "fetch",
"output": "./src/api/users"
},
{
"input": "./specs/orders-api.json",
"format": "axios",
"output": "./src/api/orders"
}
]
}
Then run:
openapi-ts-client
Options
| Option | Description | Default |
|---|---|---|
-f, --format |
Output format: fetch, axios, angular | fetch |
-o, --output |
Output directory | ./generated |
-c, --config |
Config file path | openapi-ts-client.json |
--no-validate |
Skip OpenAPI spec validation | - |
--clean |
Clear output directory before generating | - |
--force |
Continue even if output directory is not empty (may overwrite files) | - |
-q, --quiet |
Suppress all output except errors | - |
-v, --verbose |
Show detailed progress | - |
Quick Start
from openapi_ts_client import generate_typescript_client, ClientFormat
# Load your OpenAPI spec (from file, URL, or inline)
with open("openapi.json", "r") as f:
spec = f.read()
# Generate a TypeScript client
result = generate_typescript_client(
openapi_spec=spec,
output_format=ClientFormat.FETCH,
output_path="./generated/api"
)
print(result)
# Output: TypeScript Fetch client generated for 'My API' v1.0.0 (OpenAPI 3.0.0). Output: /path/to/generated/api
Usage
Basic Usage
from openapi_ts_client import generate_typescript_client, ClientFormat
# Inline OpenAPI 3.x specification
spec = {
"openapi": "3.0.0",
"info": {
"title": "My API",
"version": "1.0.0"
},
"paths": {
"/users": {
"get": {
"summary": "Get all users",
"operationId": "getUsers",
"responses": {
"200": {
"description": "Success"
}
}
}
}
}
}
# Generate with defaults (Fetch client, temp directory)
result = generate_typescript_client(spec)
Loading from JSON File
from openapi_ts_client import generate_typescript_client
# Load spec from a JSON file (as string)
with open("openapi.json", "r") as f:
json_string = f.read()
result = generate_typescript_client(json_string, output_path="./src/api")
Loading from YAML File
import yaml
from openapi_ts_client import generate_typescript_client
# Load spec from YAML (convert to dict)
with open("openapi.yaml", "r") as f:
spec = yaml.safe_load(f)
result = generate_typescript_client(spec, output_path="./src/api")
Client Formats
The package supports three output formats, each optimized for different use cases:
Fetch API Client (Default)
Native browser Fetch API client with no external dependencies.
from openapi_ts_client import generate_typescript_client, ClientFormat
result = generate_typescript_client(
spec,
output_format=ClientFormat.FETCH,
output_path="./generated/fetch-client"
)
Generated structure:
fetch-client/
├── index.ts # Main entry point, exports all
├── runtime.ts # HTTP client runtime utilities
├── apis/
│ ├── index.ts # Exports all API classes
│ ├── PetApi.ts # API class for /pet endpoints
│ ├── StoreApi.ts # API class for /store endpoints
│ └── UserApi.ts # API class for /user endpoints
└── models/
├── index.ts # Exports all model interfaces
├── Pet.ts # TypeScript interface for Pet
├── Order.ts # TypeScript interface for Order
└── User.ts # TypeScript interface for User
Usage in TypeScript:
import { Configuration, PetApi, Pet } from './generated/fetch-client';
const config = new Configuration({
basePath: 'https://api.example.com',
headers: {
'Authorization': 'Bearer YOUR_TOKEN'
}
});
const petApi = new PetApi(config);
// Get a pet by ID
const pet: Pet = await petApi.getPetById({ petId: 1 });
// Create a new pet
const newPet = await petApi.addPet({
pet: { name: 'Fluffy', status: 'available' }
});
Axios Client
Client using the popular Axios HTTP library with interceptors support.
from openapi_ts_client import generate_typescript_client, ClientFormat
result = generate_typescript_client(
spec,
output_format=ClientFormat.AXIOS,
output_path="./generated/axios-client"
)
Generated structure:
axios-client/
├── index.ts # Main entry point
├── api.ts # All API classes and interfaces
├── base.ts # Base API class
├── common.ts # Common utilities
└── configuration.ts # Configuration class
Usage in TypeScript:
import { Configuration, PetApi } from './generated/axios-client';
import axios from 'axios';
const config = new Configuration({
basePath: 'https://api.example.com',
accessToken: 'YOUR_TOKEN'
});
const petApi = new PetApi(config);
// Get a pet by ID
const response = await petApi.getPetById(1);
const pet = response.data;
// With custom Axios instance (for interceptors)
const axiosInstance = axios.create();
axiosInstance.interceptors.request.use((config) => {
config.headers.Authorization = `Bearer ${getToken()}`;
return config;
});
const petApiWithInterceptors = new PetApi(config, undefined, axiosInstance);
Angular Client
Angular-optimized client with injectable services and RxJS Observables.
from openapi_ts_client import generate_typescript_client, ClientFormat
result = generate_typescript_client(
spec,
output_format=ClientFormat.ANGULAR,
output_path="./generated/angular-client"
)
Generated structure:
angular-client/
├── index.ts # Main entry point
├── api.module.ts # Angular module for importing
├── api.base.service.ts # Base service class
├── configuration.ts # Configuration class
├── provide-api.ts # Standalone provider function
├── api/
│ ├── api.ts # Exports all services
│ ├── pet.service.ts # Injectable PetService
│ ├── store.service.ts # Injectable StoreService
│ └── user.service.ts # Injectable UserService
└── model/
├── models.ts # Exports all models
├── pet.ts # Pet interface
├── order.ts # Order interface
└── user.ts # User interface
Usage in Angular:
// app.module.ts
import { ApiModule, Configuration } from './generated/angular-client';
@NgModule({
imports: [
ApiModule.forRoot(() => new Configuration({
basePath: 'https://api.example.com'
}))
]
})
export class AppModule { }
// Or with standalone components (Angular 14+)
// app.config.ts
import { provideApi } from './generated/angular-client';
export const appConfig = {
providers: [
provideApi({
basePath: 'https://api.example.com'
})
]
};
// pet.component.ts
import { Component, inject } from '@angular/core';
import { PetService, Pet } from './generated/angular-client';
@Component({
selector: 'app-pet',
template: `<div>{{ pet?.name }}</div>`
})
export class PetComponent {
private petService = inject(PetService);
pet: Pet | null = null;
ngOnInit() {
this.petService.getPetById(1).subscribe(pet => {
this.pet = pet;
});
}
}
API Reference
generate_typescript_client(openapi_spec, output_format, output_path)
Generate a TypeScript client from an OpenAPI specification.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
openapi_spec |
dict | str |
required | The OpenAPI specification as a dictionary or JSON string |
output_format |
ClientFormat |
ClientFormat.FETCH |
The output client format |
output_path |
str | Path | None |
None |
Output directory (uses temp dir if not specified) |
skip_validation |
bool |
False |
Skip OpenAPI specification validation |
clean |
bool |
False |
Clear the output directory before generating. Cannot be used together with force. |
force |
bool |
False |
Continue generation even if output directory is not empty. Files will be overwritten but existing files not part of the generated output will remain. Cannot be used together with clean. |
Returns:
str: A status message with generation details
Raises:
ValueError: If the specification is invalid or missing required fieldsTypeError: Ifopenapi_specis neither a dict nor a string
ClientFormat Enum
| Value | Description |
|---|---|
ClientFormat.FETCH |
Native Fetch API client (default) |
ClientFormat.AXIOS |
Axios HTTP library client |
ClientFormat.ANGULAR |
Angular-optimized client with services |
Supported OpenAPI Features
Versions
- OpenAPI 3.0.x
- OpenAPI 3.1.x
Schema Types
- Primitive types (string, number, integer, boolean)
- Arrays and objects
- Enums
$refreferencesallOf,anyOf,oneOfcompositions- Nullable types
Operations
- All HTTP methods (GET, POST, PUT, DELETE, PATCH, etc.)
- Path parameters
- Query parameters
- Request bodies (JSON, form data)
- Response types
- Operation tags (for grouping into API classes)
Security
- API Key authentication
- Bearer token authentication
- OAuth2 flows
- Basic authentication
Requirements
- Python 3.8+
Runtime dependencies:
jinja2>=3.1.0- Template engineopenapi-core>=0.19.0- OpenAPI spec validation
For using generated clients:
- Node.js with TypeScript
- Axios (for Axios client)
- Angular 14+ (for Angular client)
Development
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Lint and format
ruff check src --fix
ruff format src
# Setup pre-commit hooks
pre-commit install
Acknowledgements
This project builds on the excellent work of the OpenAPI Generator team. Their years of effort creating robust code generation templates provided the foundation that made openapi-ts-client possible. Thank you for your contributions to the open-source community.
License
MIT License - see LICENSE for details.
Links
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_ts_client-1.3.1.tar.gz.
File metadata
- Download URL: openapi_ts_client-1.3.1.tar.gz
- Upload date:
- Size: 86.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9e5f7d13637dfefa5da96d704d3ab44bc93b9107ae53724f459ffc87316f658
|
|
| MD5 |
cd933be0b8e315496d6e0bdc43aabfab
|
|
| BLAKE2b-256 |
d5c953015c060220dda735df1a94118482e84f7b1a5925ec8bfb44dfffcf9ac8
|
Provenance
The following attestation bundles were made for openapi_ts_client-1.3.1.tar.gz:
Publisher:
release.yml on fa-krug/openapi-ts-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openapi_ts_client-1.3.1.tar.gz -
Subject digest:
c9e5f7d13637dfefa5da96d704d3ab44bc93b9107ae53724f459ffc87316f658 - Sigstore transparency entry: 848532682
- Sigstore integration time:
-
Permalink:
fa-krug/openapi-ts-client@1594aaf6a07dc97c566382eaa3f098c12b2ee803 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/fa-krug
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1594aaf6a07dc97c566382eaa3f098c12b2ee803 -
Trigger Event:
push
-
Statement type:
File details
Details for the file openapi_ts_client-1.3.1-py3-none-any.whl.
File metadata
- Download URL: openapi_ts_client-1.3.1-py3-none-any.whl
- Upload date:
- Size: 95.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb519b6bc96bdeb1c37c0f4b60f0ce54c48866df1f7fd41a84f6470fcaae8092
|
|
| MD5 |
1fd7efcf406cf645b5d13ff4bf342ef7
|
|
| BLAKE2b-256 |
a42c09bbc5d0a7feff0071556aba85fc17d584df5bf9ad5eb1721f0b47082c45
|
Provenance
The following attestation bundles were made for openapi_ts_client-1.3.1-py3-none-any.whl:
Publisher:
release.yml on fa-krug/openapi-ts-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openapi_ts_client-1.3.1-py3-none-any.whl -
Subject digest:
bb519b6bc96bdeb1c37c0f4b60f0ce54c48866df1f7fd41a84f6470fcaae8092 - Sigstore transparency entry: 848532752
- Sigstore integration time:
-
Permalink:
fa-krug/openapi-ts-client@1594aaf6a07dc97c566382eaa3f098c12b2ee803 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/fa-krug
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1594aaf6a07dc97c566382eaa3f098c12b2ee803 -
Trigger Event:
push
-
Statement type: