From bb10c5dd347f225cae5610001f22bff4cb2ea3da Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Thu, 5 Jan 2023 16:00:30 +1000 Subject: [PATCH 01/14] Use parameter.description for properties if the parameter's schema does not have description --- openapi_python_client/parser/openapi.py | 6 ++++++ openapi_python_client/parser/properties/schemas.py | 1 + 2 files changed, 7 insertions(+) diff --git a/openapi_python_client/parser/openapi.py b/openapi_python_client/parser/openapi.py index b7c4a8142..f7f543176 100644 --- a/openapi_python_client/parser/openapi.py +++ b/openapi_python_client/parser/openapi.py @@ -379,6 +379,12 @@ def add_parameters( unique_parameters.add(unique_param) + # In OpenAPI specification both of a parameter, and its schema, may optionally have a description. + # openapi-python-client only uses the schema description for the parameter, so if + # the schema does not have a description we will supply the parameter's description instead. + if param.param_schema.description is None: + param.param_schema.description = param.description + prop, new_schemas = property_from_data( name=param.name, required=param.required, diff --git a/openapi_python_client/parser/properties/schemas.py b/openapi_python_client/parser/properties/schemas.py index fd1af5c08..bf73b14e0 100644 --- a/openapi_python_client/parser/properties/schemas.py +++ b/openapi_python_client/parser/properties/schemas.py @@ -166,6 +166,7 @@ def parameter_from_data( style=data.style, param_schema=data.param_schema, param_in=data.param_in, + description=data.description, ) parameters = attr.evolve(parameters, classes_by_name={**parameters.classes_by_name, name: new_param}) return new_param, parameters From 304b752d02f1cdce0888eba305b8355a5c6fe854 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Thu, 5 Jan 2023 16:01:13 +1000 Subject: [PATCH 02/14] Add Property.enable_lazy_imports to allow disabling lazy imports in generated code --- openapi_python_client/parser/properties/model_property.py | 6 ++++++ openapi_python_client/parser/properties/property.py | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/openapi_python_client/parser/properties/model_property.py b/openapi_python_client/parser/properties/model_property.py index 38080cd40..4bdd90a40 100644 --- a/openapi_python_client/parser/properties/model_property.py +++ b/openapi_python_client/parser/properties/model_property.py @@ -60,6 +60,10 @@ def get_imports(self, *, prefix: str) -> Set[str]: "from typing import cast", } ) + + if not Property.enable_lazy_imports: + imports.update({f"from {prefix}{self.self_import}"}) + return imports def get_lazy_imports(self, *, prefix: str) -> Set[str]: @@ -69,6 +73,8 @@ def get_lazy_imports(self, *, prefix: str) -> Set[str]: prefix: A prefix to put before any relative (local) module names. This should be the number of . to get back to the root of the generated client. """ + if not Property.enable_lazy_imports: + return set() return {f"from {prefix}{self.self_import}"} def set_relative_imports(self, relative_imports: Set[str]) -> None: diff --git a/openapi_python_client/parser/properties/property.py b/openapi_python_client/parser/properties/property.py index 4e2aea76c..8733a2ab4 100644 --- a/openapi_python_client/parser/properties/property.py +++ b/openapi_python_client/parser/properties/property.py @@ -30,6 +30,8 @@ class Property: ValidationError: Raised when the default value fails to be converted to the expected type """ + enable_lazy_imports = False + name: str required: bool nullable: bool @@ -143,8 +145,8 @@ def to_string(self) -> str: default = None if default is not None: - return f"{self.python_name}: {self.get_type_string(quoted=True)} = {default}" - return f"{self.python_name}: {self.get_type_string(quoted=True)}" + return f"{self.python_name}: {self.get_type_string(quoted=Property.enable_lazy_imports)} = {default}" + return f"{self.python_name}: {self.get_type_string(quoted=Property.enable_lazy_imports)}" def to_docstring(self) -> str: """Returns property docstring""" From 1be3f04e44fd82725341a108e9a5eea236b7cde8 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Wed, 11 Jan 2023 09:46:22 +1000 Subject: [PATCH 03/14] Do not use List[ForwardRef] when lazy imports are disabled --- openapi_python_client/parser/properties/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index c4fe245e0..8123385cd 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -190,10 +190,10 @@ class ListProperty(Property, Generic[InnerProp]): # pylint: disable=unused-argument def get_base_type_string(self, *, quoted: bool = False) -> str: - return f"List[{self.inner_property.get_type_string(quoted=not self.inner_property.is_base_type)}]" + return f"List[{self.inner_property.get_type_string(quoted=not self.inner_property.is_base_type and Property.enable_lazy_imports)}]" def get_base_json_type_string(self, *, quoted: bool = False) -> str: - return f"List[{self.inner_property.get_type_string(json=True, quoted=not self.inner_property.is_base_type)}]" + return f"List[{self.inner_property.get_type_string(json=True, quoted=not self.inner_property.is_base_type and Property.enable_lazy_imports)}]" def get_instance_type_string(self) -> str: """Get a string representation of runtime type that should be used for `isinstance` checks""" From 6ef2e823f36eb973cc0d08d247a32918ee9f09f0 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Sat, 21 Jan 2023 17:20:26 +1000 Subject: [PATCH 04/14] Fix UNSET+Unset missing from __all__ export in types.py.jinja --- openapi_python_client/templates/types.py.jinja | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi_python_client/templates/types.py.jinja b/openapi_python_client/templates/types.py.jinja index c746db6e1..b6aa62b05 100644 --- a/openapi_python_client/templates/types.py.jinja +++ b/openapi_python_client/templates/types.py.jinja @@ -42,4 +42,4 @@ class Response(Generic[T]): parsed: Optional[T] -__all__ = ["File", "Response", "FileJsonType"] +__all__ = ["File", "Response", "FileJsonType", "UNSET", "Unset"] From 8ee794445e683ab090c2ff007a4afeccfa6dd676 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Sat, 21 Jan 2023 17:21:33 +1000 Subject: [PATCH 05/14] Add "data: oai.Operation" attribute to Endpoint --- openapi_python_client/parser/openapi.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openapi_python_client/parser/openapi.py b/openapi_python_client/parser/openapi.py index f7f543176..2a1635f7e 100644 --- a/openapi_python_client/parser/openapi.py +++ b/openapi_python_client/parser/openapi.py @@ -109,6 +109,7 @@ class Endpoint: Describes a single endpoint on the server """ + data: oai.Operation path: str method: str description: Optional[str] @@ -506,6 +507,7 @@ def from_data( name=name, requires_security=bool(data.security), tag=tag, + data=data, ) result, schemas, parameters = Endpoint.add_parameters( From 7551086ab907827e40a1047582f61cd2d0cdadbf Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Tue, 24 Jan 2023 08:01:51 +1000 Subject: [PATCH 06/14] Add note to README.md about temporary nature of this fork --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index cea385093..d329ed7c1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ +**This repository is a temporary fork of [openapi-python-client](https://github.com/openapi-generators/openapi-python-client), +and is intended for development work on [binarylane-cli](https://github.com/binarylane/binarylane-cli) only.** + +This repository will be removed once the changes here are available in upstream. + +---- + ![Run Checks](https://github.com/openapi-generators/openapi-python-client/workflows/Run%20Checks/badge.svg) [![codecov](https://codecov.io/gh/openapi-generators/openapi-python-client/branch/main/graph/badge.svg)](https://codecov.io/gh/triaxtec/openapi-python-client) [![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/) From 47b94df652fca64b7a17738e615309bbea90be68 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Tue, 24 Jan 2023 08:13:41 +1000 Subject: [PATCH 07/14] Include parameter description from parent schema in Property object --- openapi_python_client/parser/properties/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 8123385cd..a581c0baf 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -595,6 +595,8 @@ def _property_from_ref( ) if parent: prop = attr.evolve(prop, nullable=parent.nullable) + if parent.description: + prop = attr.evolve(prop, description=parent.description) if isinstance(prop, EnumProperty): default = get_enum_default(prop, parent) if isinstance(default, PropertyError): From d7e4556469111f3e672b29d6c8e1d2d83dcce828 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Tue, 24 Jan 2023 16:25:28 +1000 Subject: [PATCH 08/14] Change temporary fork package name and version --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3278591fb..f174ab7f1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] -name = "openapi-python-client" -version = "0.13.1" +name = "binarylane-python-client" +version = "0.13.2a0" description = "Generate modern Python clients from OpenAPI" repository = "https://github.com/triaxtec/openapi-python-client" license = "MIT" From be51ea208aaa1e7780e6cf73c415e760e44c6104 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Tue, 24 Jan 2023 17:04:41 +1000 Subject: [PATCH 09/14] fix: read distribution version from temporary fork name instead of upstream --- openapi_python_client/__init__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi_python_client/__init__.py b/openapi_python_client/__init__.py index 109ce84c7..f33a5bb91 100644 --- a/openapi_python_client/__init__.py +++ b/openapi_python_client/__init__.py @@ -26,7 +26,7 @@ else: from importlib.metadata import version # type: ignore -__version__ = version(__package__) +__version__ = version('binarylane-python-client') class MetaType(str, Enum): diff --git a/pyproject.toml b/pyproject.toml index f174ab7f1..1875696b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "binarylane-python-client" -version = "0.13.2a0" +version = "0.13.2a1" description = "Generate modern Python clients from OpenAPI" repository = "https://github.com/triaxtec/openapi-python-client" license = "MIT" From e310f86575c4cf5020da3492688b0f78d4f0d501 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Sun, 2 Apr 2023 10:24:42 +1000 Subject: [PATCH 10/14] refactor: fix lint errors from previous commits --- openapi_python_client/__init__.py | 2 +- openapi_python_client/parser/properties/__init__.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/openapi_python_client/__init__.py b/openapi_python_client/__init__.py index f33a5bb91..a61f4c85d 100644 --- a/openapi_python_client/__init__.py +++ b/openapi_python_client/__init__.py @@ -26,7 +26,7 @@ else: from importlib.metadata import version # type: ignore -__version__ = version('binarylane-python-client') +__version__ = version("binarylane-python-client") class MetaType(str, Enum): diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index a581c0baf..8187f4e3f 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -188,12 +188,15 @@ class ListProperty(Property, Generic[InnerProp]): inner_property: InnerProp template: ClassVar[str] = "list_property.py.jinja" + def _quoted(self) -> bool: + return not self.inner_property.is_base_type and Property.enable_lazy_imports + # pylint: disable=unused-argument def get_base_type_string(self, *, quoted: bool = False) -> str: - return f"List[{self.inner_property.get_type_string(quoted=not self.inner_property.is_base_type and Property.enable_lazy_imports)}]" + return f"List[{self.inner_property.get_type_string(quoted=self._quoted())}]" def get_base_json_type_string(self, *, quoted: bool = False) -> str: - return f"List[{self.inner_property.get_type_string(json=True, quoted=not self.inner_property.is_base_type and Property.enable_lazy_imports)}]" + return f"List[{self.inner_property.get_type_string(json=True, quoted=self._quoted())}]" def get_instance_type_string(self) -> str: """Get a string representation of runtime type that should be used for `isinstance` checks""" From 7115139e2ef017672953bb351768731e01e2cb15 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Sun, 2 Apr 2023 10:25:08 +1000 Subject: [PATCH 11/14] refactor: fix mypy error from previous commit --- openapi_python_client/parser/openapi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi_python_client/parser/openapi.py b/openapi_python_client/parser/openapi.py index 4813cca75..662ccdb84 100644 --- a/openapi_python_client/parser/openapi.py +++ b/openapi_python_client/parser/openapi.py @@ -385,7 +385,7 @@ def add_parameters( # In OpenAPI specification both of a parameter, and its schema, may optionally have a description. # openapi-python-client only uses the schema description for the parameter, so if # the schema does not have a description we will supply the parameter's description instead. - if param.param_schema.description is None: + if isinstance(param.param_schema, oai.Schema) and param.param_schema.description is None: param.param_schema.description = param.description prop, new_schemas = property_from_data( From adeef567c766c527648b7f2bba5e1d610ac315d3 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Sun, 2 Apr 2023 10:25:40 +1000 Subject: [PATCH 12/14] test: fix test errors introduced in previous commits --- tests/conftest.py | 3 +++ tests/test_parser/test_openapi.py | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index 7f8442ab7..b54c0d7cd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,6 +21,9 @@ from openapi_python_client.schema.openapi_schema_pydantic import Parameter from openapi_python_client.schema.parameter_location import ParameterLocation +# Existing test cases expect lazy imports +Property.enable_lazy_imports = True + @pytest.fixture def model_property_factory() -> Callable[..., ModelProperty]: diff --git a/tests/test_parser/test_openapi.py b/tests/test_parser/test_openapi.py index 8ef6b0a6a..7fc876b1d 100644 --- a/tests/test_parser/test_openapi.py +++ b/tests/test_parser/test_openapi.py @@ -126,6 +126,7 @@ def make_endpoint(self): from openapi_python_client.parser.openapi import Endpoint return Endpoint( + data=oai.Operation(responses=dict()), path="path", method="method", description=None, @@ -1077,6 +1078,7 @@ def test_from_data_standard(self, mocker): add_parameters.assert_called_once_with( endpoint=Endpoint( + data=data, path=path, method=method, description=data.description, @@ -1128,6 +1130,7 @@ def test_from_data_no_operation_id(self, mocker): add_parameters.assert_called_once_with( endpoint=Endpoint( + data=data, path=path, method=method, description=data.description, @@ -1180,6 +1183,7 @@ def test_from_data_no_security(self, mocker): add_parameters.assert_called_once_with( endpoint=Endpoint( + data=data, path=path, method=method, description=data.description, From eabd3fe130a2081175f437c47528137136b6a370 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Sun, 2 Apr 2023 10:38:55 +1000 Subject: [PATCH 13/14] doc: update README.md with summary of changes from upstream --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index d329ed7c1..f9ac0044f 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,16 @@ and is intended for development work on [binarylane-cli](https://github.com/bina This repository will be removed once the changes here are available in upstream. +It contains the following modifications: + +- New `data: Operation` attribute for `Endpoint` instances, allowing custom + templates to obtain additional information from pydantic `Operation` object +- New `enable_lazy_imports: bool` attribute for `Property` class, allowing lazy + imports to be disabled +- `Property` can obtain its `description` attribute from its schema, in + addition to the parameter itself +- Fix `types.py` not having `UNSET` and `Unset` in its `__all__` declaration + ---- ![Run Checks](https://github.com/openapi-generators/openapi-python-client/workflows/Run%20Checks/badge.svg) From e7f01841ceaca3fd1c2fdbe9f0049b82d4fe8ae2 Mon Sep 17 00:00:00 2001 From: Nathan O'Sullivan Date: Fri, 18 Jul 2025 16:08:37 +1000 Subject: [PATCH 14/14] chore: add support for OpenAPI Specification v3.0.4 --- .../schema/openapi_schema_pydantic/open_api.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openapi_python_client/schema/openapi_schema_pydantic/open_api.py b/openapi_python_client/schema/openapi_schema_pydantic/open_api.py index 50fdebd5e..fad3b0c27 100644 --- a/openapi_python_client/schema/openapi_schema_pydantic/open_api.py +++ b/openapi_python_client/schema/openapi_schema_pydantic/open_api.py @@ -33,7 +33,7 @@ class OpenAPI(BaseModel): security: Optional[List[SecurityRequirement]] = None tags: Optional[List[Tag]] = None externalDocs: Optional[ExternalDocumentation] = None - openapi: 'Union[Literal["3.0.0"], Literal["3.0.1"], Literal["3.0.2"], Literal["3.0.3"]]' + openapi: 'Union[Literal["3.0.0"], Literal["3.0.1"], Literal["3.0.2"], Literal["3.0.3"], Literal["3.0.4"]]' class Config: # pylint: disable=missing-class-docstring extra = Extra.allow diff --git a/pyproject.toml b/pyproject.toml index 8d16088ad..3bbf02afc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "binarylane-python-client" -version = "0.13.3a1" +version = "0.13.3a2" description = "Generate modern Python clients from OpenAPI" repository = "https://github.com/triaxtec/openapi-python-client" license = "MIT"