Skip to content

Commit 1177cf7

Browse files
authored
pass models & enums as lists so custom templates can use them (#1189)
Resolves #1188. The change is simply to store a list, rather than a generator expression. The new `models_init.py.jinja` template in the end-to-end tests shows that this now works. Without the fix in `openapi.py`, this template is rendered with nothing under the `Using "openapi.models"` and `Using "openapi.enums"` headings. This fix is somewhat important for our use case, because we need to put some code in `models/__init__.py` that is aware of what the model class names and modules are. Without the fix, the only way to get this would be to iterate over `imports`, which gives you strings like `from .module_name import ClassName`, and then parse those strings, which is workable but pretty clunky.
1 parent 0681547 commit 1177cf7

File tree

5 files changed

+67
-5
lines changed

5 files changed

+67
-5
lines changed

Diff for: .changeset/fix-models-enums-lists.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
default: patch
3+
---
4+
5+
# Make lists of models and enums work correctly in custom templates
6+
7+
Lists of model and enum classes should be available to custom templates via the Jinja
8+
variables `openapi.models` and `openapi.enums`, but these were being passed in a way that made
9+
them always appear empty. This has been fixed so a custom template can now iterate over them.
10+
11+
Closes #1188.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Testing that we can access model-related information via Jinja variables.
2+
3+
# To avoid having to update this file in the golden record every time the test specs are changed,
4+
# we won't include all the classes in this output - we'll just look for one of them.
5+
6+
# Using "alls"
7+
# AModel
8+
9+
# Using "imports"
10+
# from .a_model import AModel
11+
12+
# Using "openapi.models"
13+
# AModel (a_model)
14+
15+
# Using "openapi.enums"
16+
# AnEnum (an_enum)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
# Testing that we can access model-related information via Jinja variables.
3+
4+
# To avoid having to update this file in the golden record every time the test specs are changed,
5+
# we won't include all the classes in this output - we'll just look for one of them.
6+
7+
# Using "alls"
8+
{% for name in alls %}
9+
{% if name == "AModel" %}
10+
# {{ name }}
11+
{% endif %}
12+
{% endfor %}
13+
14+
# Using "imports"
15+
{% for import in imports %}
16+
{% if import.endswith("import AModel") %}
17+
# {{ import }}
18+
{% endif %}
19+
{% endfor %}
20+
21+
# Using "openapi.models"
22+
{% for model in openapi.models %}
23+
{% if model.class_info.name == "AModel" %}
24+
# {{ model.class_info.name }} ({{ model.class_info.module_name }})
25+
{% endif %}
26+
{% endfor %}
27+
28+
# Using "openapi.enums"
29+
{% for enum in openapi.enums %}
30+
{% if enum.class_info.name == "AnEnum" %}
31+
# {{ enum.class_info.name }} ({{ enum.class_info.module_name }})
32+
{% endif %}
33+
{% endfor %}

Diff for: end_to_end_tests/test_end_to_end.py

+2
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,15 @@ def test_custom_templates():
185185
{}
186186
) # key: path relative to generated directory, value: expected generated content
187187
api_dir = Path("my_test_api_client").joinpath("api")
188+
models_dir = Path("my_test_api_client").joinpath("models")
188189
golden_tpls_root_dir = Path(__file__).parent.joinpath(
189190
"custom-templates-golden-record"
190191
)
191192

192193
expected_difference_paths = [
193194
Path("README.md"),
194195
api_dir.joinpath("__init__.py"),
196+
models_dir.joinpath("__init__.py"),
195197
]
196198

197199
for expected_difference_path in expected_difference_paths:

Diff for: openapi_python_client/parser/openapi.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -508,10 +508,10 @@ class GeneratorData:
508508
title: str
509509
description: Optional[str]
510510
version: str
511-
models: Iterator[ModelProperty]
511+
models: list[ModelProperty]
512512
errors: list[ParseError]
513513
endpoint_collections_by_tag: dict[utils.PythonIdentifier, EndpointCollection]
514-
enums: Iterator[Union[EnumProperty, LiteralEnumProperty]]
514+
enums: list[Union[EnumProperty, LiteralEnumProperty]]
515515

516516
@staticmethod
517517
def from_dict(data: dict[str, Any], *, config: Config) -> Union["GeneratorData", GeneratorError]:
@@ -546,10 +546,10 @@ def from_dict(data: dict[str, Any], *, config: Config) -> Union["GeneratorData",
546546
config=config,
547547
)
548548

549-
enums = (
549+
enums = [
550550
prop for prop in schemas.classes_by_name.values() if isinstance(prop, (EnumProperty, LiteralEnumProperty))
551-
)
552-
models = (prop for prop in schemas.classes_by_name.values() if isinstance(prop, ModelProperty))
551+
]
552+
models = [prop for prop in schemas.classes_by_name.values() if isinstance(prop, ModelProperty)]
553553

554554
return GeneratorData(
555555
title=openapi.info.title,

0 commit comments

Comments
 (0)