From f881628160a00728f746bf8c58492495b3e14511 Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Tue, 28 Dec 2021 03:44:40 -0800 Subject: [PATCH 1/5] add option to not prepend path to Model Classes with title names --- openapi_python_client/config.py | 1 + .../parser/properties/model_property.py | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/openapi_python_client/config.py b/openapi_python_client/config.py index ace95c6b1..d63d708db 100644 --- a/openapi_python_client/config.py +++ b/openapi_python_client/config.py @@ -27,6 +27,7 @@ class Config(BaseModel): project_name_override: Optional[str] package_name_override: Optional[str] package_version_override: Optional[str] + use_path_prefixes_for_title_model_names: bool = True post_hooks: List[str] = [ "autoflake -i -r --remove-all-unused-imports --remove-unused-variables --ignore-init-module-imports .", "isort .", diff --git a/openapi_python_client/parser/properties/model_property.py b/openapi_python_client/parser/properties/model_property.py index cfaea08b0..ade2592da 100644 --- a/openapi_python_client/parser/properties/model_property.py +++ b/openapi_python_client/parser/properties/model_property.py @@ -226,9 +226,14 @@ def build_model_property( parent_name: The name of the property that this property is inside of (affects class naming) config: Config data for this run of the generator, used to modifying names """ - class_string = data.title or name - if parent_name: - class_string = f"{utils.pascal_case(parent_name)}{utils.pascal_case(class_string)}" + if not config.use_path_prefixes_for_title_model_names and data.title: + class_string = data.title + else: + title = data.title or name + if parent_name: + class_string = f"{utils.pascal_case(parent_name)}{utils.pascal_case(title)}" + else: + class_string = utils.pascal_case(title) class_info = Class.from_string(string=class_string, config=config) property_data = _process_properties(data=data, schemas=schemas, class_name=class_info.name, config=config) From a61526a9b5430cb97a198e17db386a1ea6b68116 Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Fri, 31 Dec 2021 00:56:03 -0800 Subject: [PATCH 2/5] regen tests --- .../my_test_api_client/models/__init__.py | 22 +++++++++------- ...ta.py => componentsschemas_a_form_data.py} | 10 +++---- ...operties_reference_that_are_not_object.py} | 10 +++---- ...del_with_additional_properties_inlined.py} | 26 +++++++++++-------- ...properties_inlined_additional_property.py} | 10 +++---- ...ponentsschemas_model_with_property_ref.py} | 10 +++---- .../{none.py => componentsschemas_none.py} | 10 +++---- ...{import_.py => componentsschemasimport.py} | 10 +++---- 8 files changed, 58 insertions(+), 50 deletions(-) rename end_to_end_tests/golden-record/my_test_api_client/models/{a_form_data.py => componentsschemas_a_form_data.py} (87%) rename end_to_end_tests/golden-record/my_test_api_client/models/{a_model_with_properties_reference_that_are_not_object.py => componentsschemas_a_model_with_properties_reference_that_are_not_object.py} (97%) rename end_to_end_tests/golden-record/my_test_api_client/models/{model_with_additional_properties_inlined.py => componentsschemas_model_with_additional_properties_inlined.py} (55%) rename end_to_end_tests/golden-record/my_test_api_client/models/{model_with_additional_properties_inlined_additional_property.py => componentsschemas_model_with_additional_properties_inlined_additional_property.py} (74%) rename end_to_end_tests/golden-record/my_test_api_client/models/{model_with_property_ref.py => componentsschemas_model_with_property_ref.py} (84%) rename end_to_end_tests/golden-record/my_test_api_client/models/{none.py => componentsschemas_none.py} (82%) rename end_to_end_tests/golden-record/my_test_api_client/models/{import_.py => componentsschemasimport.py} (81%) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py index 40baca7b9..41299f9b3 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py @@ -1,8 +1,6 @@ """ Contains all the data models used in inputs/outputs """ -from .a_form_data import AFormData from .a_model import AModel -from .a_model_with_properties_reference_that_are_not_object import AModelWithPropertiesReferenceThatAreNotObject from .all_of_sub_model import AllOfSubModel from .all_of_sub_model_type_enum import AllOfSubModelTypeEnum from .an_all_of_enum import AnAllOfEnum @@ -17,27 +15,33 @@ from .body_upload_file_tests_upload_post_some_nullable_object import BodyUploadFileTestsUploadPostSomeNullableObject from .body_upload_file_tests_upload_post_some_object import BodyUploadFileTestsUploadPostSomeObject from .body_upload_file_tests_upload_post_some_optional_object import BodyUploadFileTestsUploadPostSomeOptionalObject +from .componentsschemas_a_form_data import ComponentsschemasAFormData +from .componentsschemas_a_model_with_properties_reference_that_are_not_object import ( + ComponentsschemasAModelWithPropertiesReferenceThatAreNotObject, +) +from .componentsschemas_model_with_additional_properties_inlined import ( + ComponentsschemasModelWithAdditionalPropertiesInlined, +) +from .componentsschemas_model_with_additional_properties_inlined_additional_property import ( + ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty, +) +from .componentsschemas_model_with_property_ref import ComponentsschemasModelWithPropertyRef +from .componentsschemas_none import ComponentsschemasNone +from .componentsschemasimport import Componentsschemasimport from .different_enum import DifferentEnum from .free_form_model import FreeFormModel from .http_validation_error import HTTPValidationError -from .import_ import Import from .model_from_all_of import ModelFromAllOf from .model_name import ModelName -from .model_with_additional_properties_inlined import ModelWithAdditionalPropertiesInlined -from .model_with_additional_properties_inlined_additional_property import ( - ModelWithAdditionalPropertiesInlinedAdditionalProperty, -) from .model_with_additional_properties_refed import ModelWithAdditionalPropertiesRefed from .model_with_any_json_properties import ModelWithAnyJsonProperties from .model_with_any_json_properties_additional_property_type_0 import ModelWithAnyJsonPropertiesAdditionalPropertyType0 from .model_with_primitive_additional_properties import ModelWithPrimitiveAdditionalProperties from .model_with_primitive_additional_properties_a_date_holder import ModelWithPrimitiveAdditionalPropertiesADateHolder -from .model_with_property_ref import ModelWithPropertyRef from .model_with_union_property import ModelWithUnionProperty from .model_with_union_property_inlined import ModelWithUnionPropertyInlined from .model_with_union_property_inlined_fruit_type_0 import ModelWithUnionPropertyInlinedFruitType0 from .model_with_union_property_inlined_fruit_type_1 import ModelWithUnionPropertyInlinedFruitType1 -from .none import None_ from .test_inline_objects_json_body import TestInlineObjectsJsonBody from .test_inline_objects_response_200 import TestInlineObjectsResponse200 from .validation_error import ValidationError diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_form_data.py b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_form_data.py similarity index 87% rename from end_to_end_tests/golden-record/my_test_api_client/models/a_form_data.py rename to end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_form_data.py index 958b24ab5..45cfd2aa6 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_form_data.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_form_data.py @@ -4,11 +4,11 @@ from ..types import UNSET, Unset -T = TypeVar("T", bound="AFormData") +T = TypeVar("T", bound="ComponentsschemasAFormData") @attr.s(auto_attribs=True) -class AFormData: +class ComponentsschemasAFormData: """ Attributes: an_required_field (str): @@ -42,13 +42,13 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: an_optional_field = d.pop("an_optional_field", UNSET) - a_form_data = cls( + componentsschemas_a_form_data = cls( an_required_field=an_required_field, an_optional_field=an_optional_field, ) - a_form_data.additional_properties = d - return a_form_data + componentsschemas_a_form_data.additional_properties = d + return componentsschemas_a_form_data @property def additional_keys(self) -> List[str]: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_with_properties_reference_that_are_not_object.py b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_model_with_properties_reference_that_are_not_object.py similarity index 97% rename from end_to_end_tests/golden-record/my_test_api_client/models/a_model_with_properties_reference_that_are_not_object.py rename to end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_model_with_properties_reference_that_are_not_object.py index 1f1c05565..82826e677 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/a_model_with_properties_reference_that_are_not_object.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_model_with_properties_reference_that_are_not_object.py @@ -8,11 +8,11 @@ from ..models.an_enum import AnEnum from ..types import File -T = TypeVar("T", bound="AModelWithPropertiesReferenceThatAreNotObject") +T = TypeVar("T", bound="ComponentsschemasAModelWithPropertiesReferenceThatAreNotObject") @attr.s(auto_attribs=True) -class AModelWithPropertiesReferenceThatAreNotObject: +class ComponentsschemasAModelWithPropertiesReferenceThatAreNotObject: """ Attributes: enum_properties_ref (List[AnEnum]): @@ -320,7 +320,7 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: bytestream_property_ref = d.pop("bytestream_property_ref") - a_model_with_properties_reference_that_are_not_object = cls( + componentsschemas_a_model_with_properties_reference_that_are_not_object = cls( enum_properties_ref=enum_properties_ref, str_properties_ref=str_properties_ref, date_properties_ref=date_properties_ref, @@ -353,8 +353,8 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: bytestream_property_ref=bytestream_property_ref, ) - a_model_with_properties_reference_that_are_not_object.additional_properties = d - return a_model_with_properties_reference_that_are_not_object + componentsschemas_a_model_with_properties_reference_that_are_not_object.additional_properties = d + return componentsschemas_a_model_with_properties_reference_that_are_not_object @property def additional_keys(self) -> List[str]: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined.py similarity index 55% rename from end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py rename to end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined.py index 6e3faebf4..492b3a42a 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined.py @@ -2,23 +2,23 @@ import attr -from ..models.model_with_additional_properties_inlined_additional_property import ( - ModelWithAdditionalPropertiesInlinedAdditionalProperty, +from ..models.componentsschemas_model_with_additional_properties_inlined_additional_property import ( + ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty, ) from ..types import UNSET, Unset -T = TypeVar("T", bound="ModelWithAdditionalPropertiesInlined") +T = TypeVar("T", bound="ComponentsschemasModelWithAdditionalPropertiesInlined") @attr.s(auto_attribs=True) -class ModelWithAdditionalPropertiesInlined: +class ComponentsschemasModelWithAdditionalPropertiesInlined: """ Attributes: a_number (Union[Unset, float]): """ a_number: Union[Unset, float] = UNSET - additional_properties: Dict[str, ModelWithAdditionalPropertiesInlinedAdditionalProperty] = attr.ib( + additional_properties: Dict[str, ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty] = attr.ib( init=False, factory=dict ) @@ -40,27 +40,31 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() a_number = d.pop("a_number", UNSET) - model_with_additional_properties_inlined = cls( + componentsschemas_model_with_additional_properties_inlined = cls( a_number=a_number, ) additional_properties = {} for prop_name, prop_dict in d.items(): - additional_property = ModelWithAdditionalPropertiesInlinedAdditionalProperty.from_dict(prop_dict) + additional_property = ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty.from_dict( + prop_dict + ) additional_properties[prop_name] = additional_property - model_with_additional_properties_inlined.additional_properties = additional_properties - return model_with_additional_properties_inlined + componentsschemas_model_with_additional_properties_inlined.additional_properties = additional_properties + return componentsschemas_model_with_additional_properties_inlined @property def additional_keys(self) -> List[str]: return list(self.additional_properties.keys()) - def __getitem__(self, key: str) -> ModelWithAdditionalPropertiesInlinedAdditionalProperty: + def __getitem__(self, key: str) -> ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty: return self.additional_properties[key] - def __setitem__(self, key: str, value: ModelWithAdditionalPropertiesInlinedAdditionalProperty) -> None: + def __setitem__( + self, key: str, value: ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty + ) -> None: self.additional_properties[key] = value def __delitem__(self, key: str) -> None: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined_additional_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined_additional_property.py similarity index 74% rename from end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined_additional_property.py rename to end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined_additional_property.py index 66b487c00..1b9317a21 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined_additional_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined_additional_property.py @@ -4,11 +4,11 @@ from ..types import UNSET, Unset -T = TypeVar("T", bound="ModelWithAdditionalPropertiesInlinedAdditionalProperty") +T = TypeVar("T", bound="ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty") @attr.s(auto_attribs=True) -class ModelWithAdditionalPropertiesInlinedAdditionalProperty: +class ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty: """ Attributes: extra_props_prop (Union[Unset, str]): @@ -33,12 +33,12 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() extra_props_prop = d.pop("extra_props_prop", UNSET) - model_with_additional_properties_inlined_additional_property = cls( + componentsschemas_model_with_additional_properties_inlined_additional_property = cls( extra_props_prop=extra_props_prop, ) - model_with_additional_properties_inlined_additional_property.additional_properties = d - return model_with_additional_properties_inlined_additional_property + componentsschemas_model_with_additional_properties_inlined_additional_property.additional_properties = d + return componentsschemas_model_with_additional_properties_inlined_additional_property @property def additional_keys(self) -> List[str]: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_property_ref.py b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_property_ref.py similarity index 84% rename from end_to_end_tests/golden-record/my_test_api_client/models/model_with_property_ref.py rename to end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_property_ref.py index a3713efe2..0beccd4d8 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_property_ref.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_property_ref.py @@ -5,11 +5,11 @@ from ..models.model_name import ModelName from ..types import UNSET, Unset -T = TypeVar("T", bound="ModelWithPropertyRef") +T = TypeVar("T", bound="ComponentsschemasModelWithPropertyRef") @attr.s(auto_attribs=True) -class ModelWithPropertyRef: +class ComponentsschemasModelWithPropertyRef: """ Attributes: inner (Union[Unset, ModelName]): @@ -41,12 +41,12 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: else: inner = ModelName.from_dict(_inner) - model_with_property_ref = cls( + componentsschemas_model_with_property_ref = cls( inner=inner, ) - model_with_property_ref.additional_properties = d - return model_with_property_ref + componentsschemas_model_with_property_ref.additional_properties = d + return componentsschemas_model_with_property_ref @property def additional_keys(self) -> List[str]: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/none.py b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_none.py similarity index 82% rename from end_to_end_tests/golden-record/my_test_api_client/models/none.py rename to end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_none.py index e1722f094..3387f9927 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/none.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_none.py @@ -2,11 +2,11 @@ import attr -T = TypeVar("T", bound="None_") +T = TypeVar("T", bound="ComponentsschemasNone") @attr.s(auto_attribs=True) -class None_: +class ComponentsschemasNone: """ """ additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) @@ -22,10 +22,10 @@ def to_dict(self) -> Dict[str, Any]: @classmethod def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - none = cls() + componentsschemas_none = cls() - none.additional_properties = d - return none + componentsschemas_none.additional_properties = d + return componentsschemas_none @property def additional_keys(self) -> List[str]: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/import_.py b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemasimport.py similarity index 81% rename from end_to_end_tests/golden-record/my_test_api_client/models/import_.py rename to end_to_end_tests/golden-record/my_test_api_client/models/componentsschemasimport.py index 276a4f21b..d308892e0 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/import_.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemasimport.py @@ -2,11 +2,11 @@ import attr -T = TypeVar("T", bound="Import") +T = TypeVar("T", bound="Componentsschemasimport") @attr.s(auto_attribs=True) -class Import: +class Componentsschemasimport: """ """ additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) @@ -22,10 +22,10 @@ def to_dict(self) -> Dict[str, Any]: @classmethod def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - import_ = cls() + componentsschemasimport = cls() - import_.additional_properties = d - return import_ + componentsschemasimport.additional_properties = d + return componentsschemasimport @property def additional_keys(self) -> List[str]: From 9bb82b08932f88268b07c52334df68ab5dbaedf4 Mon Sep 17 00:00:00 2001 From: "Roman A. Taycher" Date: Fri, 31 Dec 2021 01:58:39 -0800 Subject: [PATCH 3/5] fixed model name, regenerated tests --- .../my_test_api_client/models/__init__.py | 22 +++++++--------- ...sschemas_a_form_data.py => a_form_data.py} | 10 +++---- ...operties_reference_that_are_not_object.py} | 10 +++---- .../{componentsschemas_none.py => import_.py} | 10 +++---- ...del_with_additional_properties_inlined.py} | 26 ++++++++----------- ...properties_inlined_additional_property.py} | 10 +++---- ...erty_ref.py => model_with_property_ref.py} | 10 +++---- .../{componentsschemasimport.py => none.py} | 10 +++---- .../parser/properties/model_property.py | 2 +- 9 files changed, 51 insertions(+), 59 deletions(-) rename end_to_end_tests/golden-record/my_test_api_client/models/{componentsschemas_a_form_data.py => a_form_data.py} (87%) rename end_to_end_tests/golden-record/my_test_api_client/models/{componentsschemas_a_model_with_properties_reference_that_are_not_object.py => a_model_with_properties_reference_that_are_not_object.py} (97%) rename end_to_end_tests/golden-record/my_test_api_client/models/{componentsschemas_none.py => import_.py} (82%) rename end_to_end_tests/golden-record/my_test_api_client/models/{componentsschemas_model_with_additional_properties_inlined.py => model_with_additional_properties_inlined.py} (55%) rename end_to_end_tests/golden-record/my_test_api_client/models/{componentsschemas_model_with_additional_properties_inlined_additional_property.py => model_with_additional_properties_inlined_additional_property.py} (74%) rename end_to_end_tests/golden-record/my_test_api_client/models/{componentsschemas_model_with_property_ref.py => model_with_property_ref.py} (84%) rename end_to_end_tests/golden-record/my_test_api_client/models/{componentsschemasimport.py => none.py} (81%) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py index 41299f9b3..40baca7b9 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py @@ -1,6 +1,8 @@ """ Contains all the data models used in inputs/outputs """ +from .a_form_data import AFormData from .a_model import AModel +from .a_model_with_properties_reference_that_are_not_object import AModelWithPropertiesReferenceThatAreNotObject from .all_of_sub_model import AllOfSubModel from .all_of_sub_model_type_enum import AllOfSubModelTypeEnum from .an_all_of_enum import AnAllOfEnum @@ -15,33 +17,27 @@ from .body_upload_file_tests_upload_post_some_nullable_object import BodyUploadFileTestsUploadPostSomeNullableObject from .body_upload_file_tests_upload_post_some_object import BodyUploadFileTestsUploadPostSomeObject from .body_upload_file_tests_upload_post_some_optional_object import BodyUploadFileTestsUploadPostSomeOptionalObject -from .componentsschemas_a_form_data import ComponentsschemasAFormData -from .componentsschemas_a_model_with_properties_reference_that_are_not_object import ( - ComponentsschemasAModelWithPropertiesReferenceThatAreNotObject, -) -from .componentsschemas_model_with_additional_properties_inlined import ( - ComponentsschemasModelWithAdditionalPropertiesInlined, -) -from .componentsschemas_model_with_additional_properties_inlined_additional_property import ( - ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty, -) -from .componentsschemas_model_with_property_ref import ComponentsschemasModelWithPropertyRef -from .componentsschemas_none import ComponentsschemasNone -from .componentsschemasimport import Componentsschemasimport from .different_enum import DifferentEnum from .free_form_model import FreeFormModel from .http_validation_error import HTTPValidationError +from .import_ import Import from .model_from_all_of import ModelFromAllOf from .model_name import ModelName +from .model_with_additional_properties_inlined import ModelWithAdditionalPropertiesInlined +from .model_with_additional_properties_inlined_additional_property import ( + ModelWithAdditionalPropertiesInlinedAdditionalProperty, +) from .model_with_additional_properties_refed import ModelWithAdditionalPropertiesRefed from .model_with_any_json_properties import ModelWithAnyJsonProperties from .model_with_any_json_properties_additional_property_type_0 import ModelWithAnyJsonPropertiesAdditionalPropertyType0 from .model_with_primitive_additional_properties import ModelWithPrimitiveAdditionalProperties from .model_with_primitive_additional_properties_a_date_holder import ModelWithPrimitiveAdditionalPropertiesADateHolder +from .model_with_property_ref import ModelWithPropertyRef from .model_with_union_property import ModelWithUnionProperty from .model_with_union_property_inlined import ModelWithUnionPropertyInlined from .model_with_union_property_inlined_fruit_type_0 import ModelWithUnionPropertyInlinedFruitType0 from .model_with_union_property_inlined_fruit_type_1 import ModelWithUnionPropertyInlinedFruitType1 +from .none import None_ from .test_inline_objects_json_body import TestInlineObjectsJsonBody from .test_inline_objects_response_200 import TestInlineObjectsResponse200 from .validation_error import ValidationError diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_form_data.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_form_data.py similarity index 87% rename from end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_form_data.py rename to end_to_end_tests/golden-record/my_test_api_client/models/a_form_data.py index 45cfd2aa6..958b24ab5 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_form_data.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_form_data.py @@ -4,11 +4,11 @@ from ..types import UNSET, Unset -T = TypeVar("T", bound="ComponentsschemasAFormData") +T = TypeVar("T", bound="AFormData") @attr.s(auto_attribs=True) -class ComponentsschemasAFormData: +class AFormData: """ Attributes: an_required_field (str): @@ -42,13 +42,13 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: an_optional_field = d.pop("an_optional_field", UNSET) - componentsschemas_a_form_data = cls( + a_form_data = cls( an_required_field=an_required_field, an_optional_field=an_optional_field, ) - componentsschemas_a_form_data.additional_properties = d - return componentsschemas_a_form_data + a_form_data.additional_properties = d + return a_form_data @property def additional_keys(self) -> List[str]: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_model_with_properties_reference_that_are_not_object.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_with_properties_reference_that_are_not_object.py similarity index 97% rename from end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_model_with_properties_reference_that_are_not_object.py rename to end_to_end_tests/golden-record/my_test_api_client/models/a_model_with_properties_reference_that_are_not_object.py index 82826e677..1f1c05565 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_a_model_with_properties_reference_that_are_not_object.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_model_with_properties_reference_that_are_not_object.py @@ -8,11 +8,11 @@ from ..models.an_enum import AnEnum from ..types import File -T = TypeVar("T", bound="ComponentsschemasAModelWithPropertiesReferenceThatAreNotObject") +T = TypeVar("T", bound="AModelWithPropertiesReferenceThatAreNotObject") @attr.s(auto_attribs=True) -class ComponentsschemasAModelWithPropertiesReferenceThatAreNotObject: +class AModelWithPropertiesReferenceThatAreNotObject: """ Attributes: enum_properties_ref (List[AnEnum]): @@ -320,7 +320,7 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: bytestream_property_ref = d.pop("bytestream_property_ref") - componentsschemas_a_model_with_properties_reference_that_are_not_object = cls( + a_model_with_properties_reference_that_are_not_object = cls( enum_properties_ref=enum_properties_ref, str_properties_ref=str_properties_ref, date_properties_ref=date_properties_ref, @@ -353,8 +353,8 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: bytestream_property_ref=bytestream_property_ref, ) - componentsschemas_a_model_with_properties_reference_that_are_not_object.additional_properties = d - return componentsschemas_a_model_with_properties_reference_that_are_not_object + a_model_with_properties_reference_that_are_not_object.additional_properties = d + return a_model_with_properties_reference_that_are_not_object @property def additional_keys(self) -> List[str]: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_none.py b/end_to_end_tests/golden-record/my_test_api_client/models/import_.py similarity index 82% rename from end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_none.py rename to end_to_end_tests/golden-record/my_test_api_client/models/import_.py index 3387f9927..276a4f21b 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_none.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/import_.py @@ -2,11 +2,11 @@ import attr -T = TypeVar("T", bound="ComponentsschemasNone") +T = TypeVar("T", bound="Import") @attr.s(auto_attribs=True) -class ComponentsschemasNone: +class Import: """ """ additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) @@ -22,10 +22,10 @@ def to_dict(self) -> Dict[str, Any]: @classmethod def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - componentsschemas_none = cls() + import_ = cls() - componentsschemas_none.additional_properties = d - return componentsschemas_none + import_.additional_properties = d + return import_ @property def additional_keys(self) -> List[str]: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py similarity index 55% rename from end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined.py rename to end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py index 492b3a42a..6e3faebf4 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined.py @@ -2,23 +2,23 @@ import attr -from ..models.componentsschemas_model_with_additional_properties_inlined_additional_property import ( - ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty, +from ..models.model_with_additional_properties_inlined_additional_property import ( + ModelWithAdditionalPropertiesInlinedAdditionalProperty, ) from ..types import UNSET, Unset -T = TypeVar("T", bound="ComponentsschemasModelWithAdditionalPropertiesInlined") +T = TypeVar("T", bound="ModelWithAdditionalPropertiesInlined") @attr.s(auto_attribs=True) -class ComponentsschemasModelWithAdditionalPropertiesInlined: +class ModelWithAdditionalPropertiesInlined: """ Attributes: a_number (Union[Unset, float]): """ a_number: Union[Unset, float] = UNSET - additional_properties: Dict[str, ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty] = attr.ib( + additional_properties: Dict[str, ModelWithAdditionalPropertiesInlinedAdditionalProperty] = attr.ib( init=False, factory=dict ) @@ -40,31 +40,27 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() a_number = d.pop("a_number", UNSET) - componentsschemas_model_with_additional_properties_inlined = cls( + model_with_additional_properties_inlined = cls( a_number=a_number, ) additional_properties = {} for prop_name, prop_dict in d.items(): - additional_property = ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty.from_dict( - prop_dict - ) + additional_property = ModelWithAdditionalPropertiesInlinedAdditionalProperty.from_dict(prop_dict) additional_properties[prop_name] = additional_property - componentsschemas_model_with_additional_properties_inlined.additional_properties = additional_properties - return componentsschemas_model_with_additional_properties_inlined + model_with_additional_properties_inlined.additional_properties = additional_properties + return model_with_additional_properties_inlined @property def additional_keys(self) -> List[str]: return list(self.additional_properties.keys()) - def __getitem__(self, key: str) -> ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty: + def __getitem__(self, key: str) -> ModelWithAdditionalPropertiesInlinedAdditionalProperty: return self.additional_properties[key] - def __setitem__( - self, key: str, value: ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty - ) -> None: + def __setitem__(self, key: str, value: ModelWithAdditionalPropertiesInlinedAdditionalProperty) -> None: self.additional_properties[key] = value def __delitem__(self, key: str) -> None: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined_additional_property.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined_additional_property.py similarity index 74% rename from end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined_additional_property.py rename to end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined_additional_property.py index 1b9317a21..66b487c00 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_additional_properties_inlined_additional_property.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_additional_properties_inlined_additional_property.py @@ -4,11 +4,11 @@ from ..types import UNSET, Unset -T = TypeVar("T", bound="ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty") +T = TypeVar("T", bound="ModelWithAdditionalPropertiesInlinedAdditionalProperty") @attr.s(auto_attribs=True) -class ComponentsschemasModelWithAdditionalPropertiesInlinedAdditionalProperty: +class ModelWithAdditionalPropertiesInlinedAdditionalProperty: """ Attributes: extra_props_prop (Union[Unset, str]): @@ -33,12 +33,12 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() extra_props_prop = d.pop("extra_props_prop", UNSET) - componentsschemas_model_with_additional_properties_inlined_additional_property = cls( + model_with_additional_properties_inlined_additional_property = cls( extra_props_prop=extra_props_prop, ) - componentsschemas_model_with_additional_properties_inlined_additional_property.additional_properties = d - return componentsschemas_model_with_additional_properties_inlined_additional_property + model_with_additional_properties_inlined_additional_property.additional_properties = d + return model_with_additional_properties_inlined_additional_property @property def additional_keys(self) -> List[str]: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_property_ref.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_property_ref.py similarity index 84% rename from end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_property_ref.py rename to end_to_end_tests/golden-record/my_test_api_client/models/model_with_property_ref.py index 0beccd4d8..a3713efe2 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemas_model_with_property_ref.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_property_ref.py @@ -5,11 +5,11 @@ from ..models.model_name import ModelName from ..types import UNSET, Unset -T = TypeVar("T", bound="ComponentsschemasModelWithPropertyRef") +T = TypeVar("T", bound="ModelWithPropertyRef") @attr.s(auto_attribs=True) -class ComponentsschemasModelWithPropertyRef: +class ModelWithPropertyRef: """ Attributes: inner (Union[Unset, ModelName]): @@ -41,12 +41,12 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: else: inner = ModelName.from_dict(_inner) - componentsschemas_model_with_property_ref = cls( + model_with_property_ref = cls( inner=inner, ) - componentsschemas_model_with_property_ref.additional_properties = d - return componentsschemas_model_with_property_ref + model_with_property_ref.additional_properties = d + return model_with_property_ref @property def additional_keys(self) -> List[str]: diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemasimport.py b/end_to_end_tests/golden-record/my_test_api_client/models/none.py similarity index 81% rename from end_to_end_tests/golden-record/my_test_api_client/models/componentsschemasimport.py rename to end_to_end_tests/golden-record/my_test_api_client/models/none.py index d308892e0..e1722f094 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/componentsschemasimport.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/none.py @@ -2,11 +2,11 @@ import attr -T = TypeVar("T", bound="Componentsschemasimport") +T = TypeVar("T", bound="None_") @attr.s(auto_attribs=True) -class Componentsschemasimport: +class None_: """ """ additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) @@ -22,10 +22,10 @@ def to_dict(self) -> Dict[str, Any]: @classmethod def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - componentsschemasimport = cls() + none = cls() - componentsschemasimport.additional_properties = d - return componentsschemasimport + none.additional_properties = d + return none @property def additional_keys(self) -> List[str]: diff --git a/openapi_python_client/parser/properties/model_property.py b/openapi_python_client/parser/properties/model_property.py index ade2592da..5136a423f 100644 --- a/openapi_python_client/parser/properties/model_property.py +++ b/openapi_python_client/parser/properties/model_property.py @@ -233,7 +233,7 @@ def build_model_property( if parent_name: class_string = f"{utils.pascal_case(parent_name)}{utils.pascal_case(title)}" else: - class_string = utils.pascal_case(title) + class_string = title class_info = Class.from_string(string=class_string, config=config) property_data = _process_properties(data=data, schemas=schemas, class_name=class_info.name, config=config) From 58c6eaf1dbed9f52a96399fa0f71a76072d26cc0 Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Sat, 17 Dec 2022 16:01:05 -0700 Subject: [PATCH 4/5] docs: Add instructions for new config option --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index c5f869d52..4baa93c9e 100644 --- a/README.md +++ b/README.md @@ -157,5 +157,13 @@ post_hooks: - "black ." ``` +### use_path_prefixes_for_title_model_names + +By default, `openapi-python-client` generates class names which include the full path to the schema, including any parent-types. This can result in very long class names like `MyRouteSomeClassAnotherClassResponse`—which is very unique and unlikely to cause conflicts with future API additions, but also super verbose. + +If you are carefully curating your `title` properties already to ensure no duplicate class names, you can turn off this prefixing feature by setting `use_path_prefixes_for_title_model_names` to `false` in your config file. This will use the `title` property of any object that has it set _without_ prefixing. + +If this option results in conflicts, you will need to manually override class names instead via the `class_overrides` option. + [changelog.md]: CHANGELOG.md [poetry]: https://python-poetry.org/ From ef44f8e213831b47701b4d1f483eeaaa17b1bdc0 Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Sat, 17 Dec 2022 16:28:55 -0700 Subject: [PATCH 5/5] test: Add a unit test for model naming --- .../test_properties/test_model_property.py | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/test_parser/test_properties/test_model_property.py b/tests/test_parser/test_properties/test_model_property.py index 7f8a92270..8e82145bb 100644 --- a/tests/test_parser/test_properties/test_model_property.py +++ b/tests/test_parser/test_properties/test_model_property.py @@ -1,3 +1,4 @@ +from typing import Optional from unittest.mock import MagicMock import pytest @@ -201,6 +202,46 @@ def test_model_name_conflict(self): assert new_schemas == schemas assert err == PropertyError(detail='Attempted to generate duplicate models with name "OtherModel"', data=data) + @pytest.mark.parametrize( + "name, title, parent_name, use_title_prefixing, expected", + ids=( + "basic name only", + "title override", + "name with parent", + "name with parent and title prefixing disabled", + "title with parent", + "title with parent and title prefixing disabled", + ), + argvalues=( + ("prop", None, None, True, "Prop"), + ("prop", "MyModel", None, True, "MyModel"), + ("prop", None, "parent", True, "ParentProp"), + ("prop", None, "parent", False, "ParentProp"), + ("prop", "MyModel", "parent", True, "ParentMyModel"), + ("prop", "MyModel", "parent", False, "MyModel"), + ), + ) + def test_model_naming( + self, name: str, title: Optional[str], parent_name: Optional[str], use_title_prefixing: bool, expected: str + ): + from openapi_python_client.parser.properties import Schemas, build_model_property + + data = oai.Schema( + title=title, + properties={}, + ) + result = build_model_property( + data=data, + name=name, + schemas=Schemas(), + required=True, + parent_name=parent_name, + config=Config(use_path_prefixes_for_title_model_names=use_title_prefixing), + roots={"root"}, + process_properties=True, + )[0] + assert result.class_info.name == expected + def test_model_bad_properties(self): from openapi_python_client.parser.properties import Schemas, build_model_property