Generate modern Python clients from OpenAPI 3.0 and 3.1 documents
npx @tessl/cli install tessl/pypi-openapi-python-client@0.26.0A command-line tool and Python library for generating modern Python client libraries from OpenAPI 3.0 and 3.1 specifications. It focuses on creating type-safe, well-documented Python clients with modern Python features like type annotations, dataclasses, and comprehensive error handling.
pip install openapi-python-clientpipx install openapi-python-client --include-depsfrom openapi_python_client import generate, Project, __version__
from openapi_python_client.config import Config, ConfigFile, MetaType, ClassOverrideCLI usage:
openapi-python-client generate --url https://api.example.com/openapi.jsonfrom pathlib import Path
from openapi_python_client import generate
from openapi_python_client.config import Config, ConfigFile, MetaType
# Create configuration
config_file = ConfigFile()
config = Config.from_sources(
config_file=config_file,
meta_type=MetaType.POETRY,
document_source="https://api.example.com/openapi.json",
file_encoding="utf-8",
overwrite=True,
output_path=None
)
# Generate client library
errors = generate(config=config)
# Handle any errors
if errors:
for error in errors:
print(f"Error: {error.header}")
if error.detail:
print(f"Detail: {error.detail}")CLI usage:
# Generate from URL
openapi-python-client generate --url https://api.example.com/openapi.json
# Generate from local file
openapi-python-client generate --path ./openapi.yaml
# Generate with custom configuration
openapi-python-client generate \
--url https://api.example.com/openapi.json \
--config config.yaml \
--meta poetry \
--overwrite \
--output-path ./my-clientThe generator follows a pipeline architecture:
The generated clients follow a structured pattern:
Command-line interface for generating Python clients from OpenAPI specifications. Supports various options for customization, configuration files, and output formats.
def generate(
url: Optional[str] = None,
path: Optional[Path] = None,
custom_template_path: Optional[Path] = None,
meta: MetaType = MetaType.POETRY,
file_encoding: str = "utf-8",
config_path: Optional[Path] = None,
fail_on_warning: bool = False,
overwrite: bool = False,
output_path: Optional[Path] = None,
) -> None: ...Python API for integrating client generation into other tools and workflows. Provides full control over configuration and error handling.
def generate(
*,
config: Config,
custom_template_path: Optional[Path] = None,
) -> Sequence[GeneratorError]: ...
class Config:
@staticmethod
def from_sources(
config_file: ConfigFile,
meta_type: MetaType,
document_source: Union[Path, str],
file_encoding: str,
overwrite: bool,
output_path: Optional[Path],
) -> "Config": ...Comprehensive configuration system supporting file-based configuration, class overrides, project customization, and post-generation hooks.
class ConfigFile(BaseModel):
class_overrides: Optional[dict[str, ClassOverride]] = None
content_type_overrides: Optional[dict[str, str]] = None
project_name_override: Optional[str] = None
package_name_override: Optional[str] = None
package_version_override: Optional[str] = None
use_path_prefixes_for_title_model_names: bool = True
post_hooks: Optional[list[str]] = None
docstrings_on_attributes: bool = False
field_prefix: str = "field_"
generate_all_tags: bool = False
http_timeout: int = 5
literal_enums: bool = False
@staticmethod
def load_from_path(path: Path) -> "ConfigFile": ...Extensible Jinja2-based template system for customizing generated code structure, formatting, and content. Supports custom templates and filters.
class Project:
def __init__(
self,
*,
openapi: GeneratorData,
config: Config,
custom_template_path: Optional[Path] = None,
) -> None: ...
def build(self) -> Sequence[GeneratorError]: ...String manipulation and validation utilities used internally and available for custom templates and extensions.
class PythonIdentifier(str):
def __new__(cls, value: str, prefix: str, skip_snake_case: bool = False) -> PythonIdentifier: ...
class ClassName(str):
def __new__(cls, value: str, prefix: str) -> ClassName: ...
def snake_case(value: str) -> str: ...
def pascal_case(value: str) -> str: ...
def kebab_case(value: str) -> str: ...
def sanitize(value: str) -> str: ...
def fix_reserved_words(value: str) -> str: ...
def get_content_type(content_type: str, config: Config) -> str | None: ...from openapi_python_client.config import MetaType, ClassOverride
from openapi_python_client.parser.errors import GeneratorError, ErrorLevel
from openapi_python_client.parser import GeneratorDataclass MetaType(str, Enum):
NONE = "none"
POETRY = "poetry"
SETUP = "setup"
PDM = "pdm"
UV = "uv"
class ClassOverride(BaseModel):
class_name: Optional[str] = None
module_name: Optional[str] = None
class GeneratorError:
header: str
detail: Optional[str]
level: ErrorLevel
class ErrorLevel(str, Enum):
WARNING = "warning"
ERROR = "error"
# Parser and Schema Types
class GeneratorData:
"""Parsed OpenAPI specification data"""
pass
def import_string_from_class(class_info) -> str:
"""Generate import string for a class"""
pass
# OpenAPI Schema Types
class DataType(str, Enum): ...
class ParameterLocation(str, Enum): ...
class MediaType: ...
class OpenAPI: ...
class Operation: ...
class Parameter: ...
class PathItem: ...
class Reference: ...
class RequestBody: ...
class Response: ...
class Responses: ...
class Schema: ...