diff --git a/.changeset/fix-models-enums-lists.md b/.changeset/fix-models-enums-lists.md new file mode 100644 index 000000000..50b7671f3 --- /dev/null +++ b/.changeset/fix-models-enums-lists.md @@ -0,0 +1,11 @@ +--- +default: patch +--- + +# Make lists of models and enums work correctly in custom templates + +Lists of model and enum classes should be available to custom templates via the Jinja +variables `openapi.models` and `openapi.enums`, but these were being passed in a way that made +them always appear empty. This has been fixed so a custom template can now iterate over them. + +Closes #1188. diff --git a/end_to_end_tests/custom-templates-golden-record/my_test_api_client/models/__init__.py b/end_to_end_tests/custom-templates-golden-record/my_test_api_client/models/__init__.py new file mode 100644 index 000000000..611ed15f6 --- /dev/null +++ b/end_to_end_tests/custom-templates-golden-record/my_test_api_client/models/__init__.py @@ -0,0 +1,16 @@ +# Testing that we can access model-related information via Jinja variables. + +# To avoid having to update this file in the golden record every time the test specs are changed, +# we won't include all the classes in this output - we'll just look for one of them. + +# Using "alls" +# AModel + +# Using "imports" +# from .a_model import AModel + +# Using "openapi.models" +# AModel (a_model) + +# Using "openapi.enums" +# AnEnum (an_enum) diff --git a/end_to_end_tests/test_custom_templates/models_init.py.jinja b/end_to_end_tests/test_custom_templates/models_init.py.jinja new file mode 100644 index 000000000..8b0a55aee --- /dev/null +++ b/end_to_end_tests/test_custom_templates/models_init.py.jinja @@ -0,0 +1,33 @@ + +# Testing that we can access model-related information via Jinja variables. + +# To avoid having to update this file in the golden record every time the test specs are changed, +# we won't include all the classes in this output - we'll just look for one of them. + +# Using "alls" +{% for name in alls %} +{% if name == "AModel" %} +# {{ name }} +{% endif %} +{% endfor %} + +# Using "imports" +{% for import in imports %} +{% if import.endswith("import AModel") %} +# {{ import }} +{% endif %} +{% endfor %} + +# Using "openapi.models" +{% for model in openapi.models %} +{% if model.class_info.name == "AModel" %} +# {{ model.class_info.name }} ({{ model.class_info.module_name }}) +{% endif %} +{% endfor %} + +# Using "openapi.enums" +{% for enum in openapi.enums %} +{% if enum.class_info.name == "AnEnum" %} +# {{ enum.class_info.name }} ({{ enum.class_info.module_name }}) +{% endif %} +{% endfor %} diff --git a/end_to_end_tests/test_end_to_end.py b/end_to_end_tests/test_end_to_end.py index 124b801d2..ff0c3592b 100644 --- a/end_to_end_tests/test_end_to_end.py +++ b/end_to_end_tests/test_end_to_end.py @@ -197,6 +197,7 @@ def test_custom_templates(): {} ) # key: path relative to generated directory, value: expected generated content api_dir = Path("my_test_api_client").joinpath("api") + models_dir = Path("my_test_api_client").joinpath("models") golden_tpls_root_dir = Path(__file__).parent.joinpath( "custom-templates-golden-record" ) @@ -204,6 +205,7 @@ def test_custom_templates(): expected_difference_paths = [ Path("README.md"), api_dir.joinpath("__init__.py"), + models_dir.joinpath("__init__.py"), ] for expected_difference_path in expected_difference_paths: diff --git a/openapi_python_client/parser/openapi.py b/openapi_python_client/parser/openapi.py index 117b2ee30..bed82d774 100644 --- a/openapi_python_client/parser/openapi.py +++ b/openapi_python_client/parser/openapi.py @@ -493,10 +493,10 @@ class GeneratorData: title: str description: Optional[str] version: str - models: Iterator[ModelProperty] + models: list[ModelProperty] errors: list[ParseError] endpoint_collections_by_tag: dict[utils.PythonIdentifier, EndpointCollection] - enums: Iterator[Union[EnumProperty, LiteralEnumProperty]] + enums: list[Union[EnumProperty, LiteralEnumProperty]] @staticmethod def from_dict(data: dict[str, Any], *, config: Config) -> Union["GeneratorData", GeneratorError]: @@ -525,10 +525,10 @@ def from_dict(data: dict[str, Any], *, config: Config) -> Union["GeneratorData", data=openapi.paths, schemas=schemas, parameters=parameters, request_bodies=request_bodies, config=config ) - enums = ( + enums = [ prop for prop in schemas.classes_by_name.values() if isinstance(prop, (EnumProperty, LiteralEnumProperty)) - ) - models = (prop for prop in schemas.classes_by_name.values() if isinstance(prop, ModelProperty)) + ] + models = [prop for prop in schemas.classes_by_name.values() if isinstance(prop, ModelProperty)] return GeneratorData( title=openapi.info.title,