openapi-python-client 0.21.4__tar.gz → 0.21.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/PKG-INFO +14 -2
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/README.md +11 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/__init__.py +5 -1
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/config.py +3 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/openapi.py +7 -4
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/__init__.py +23 -3
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/any.py +6 -2
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/boolean.py +3 -3
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/const.py +5 -7
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/date.py +1 -1
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/datetime.py +1 -1
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/enum_property.py +8 -5
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/float.py +3 -3
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/int.py +10 -6
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/list_property.py +19 -3
- openapi_python_client-0.21.6/openapi_python_client/parser/properties/literal_enum_property.py +191 -0
- openapi_python_client-0.21.6/openapi_python_client/parser/properties/merge_properties.py +198 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/model_property.py +14 -67
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/none.py +1 -1
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/property.py +4 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/protocol.py +12 -4
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/string.py +1 -5
- openapi_python_client-0.21.6/openapi_python_client/parser/properties/uuid.py +80 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/schema.py +1 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/client.py.jinja +1 -1
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/endpoint_module.py.jinja +2 -2
- openapi_python_client-0.21.6/openapi_python_client/templates/literal_enum.py.jinja +10 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/model.py.jinja +3 -1
- openapi_python_client-0.21.6/openapi_python_client/templates/property_templates/const_property.py.jinja +5 -0
- openapi_python_client-0.21.6/openapi_python_client/templates/property_templates/literal_enum_property.py.jinja +38 -0
- openapi_python_client-0.21.6/openapi_python_client/templates/property_templates/uuid_property.py.jinja +38 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/pyproject.toml +6 -5
- openapi_python_client-0.21.4/openapi_python_client/templates/property_templates/const_property.py.jinja +0 -5
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/.gitignore +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/LICENSE +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/__main__.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/cli.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/__init__.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/bodies.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/errors.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/file.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/schemas.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/properties/union.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/parser/responses.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/py.typed +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/3.0.3.md +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/3.1.0.md +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/__init__.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/data_type.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/LICENSE +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/README.md +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/__init__.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/callback.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/components.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/contact.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/discriminator.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/encoding.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/example.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/external_documentation.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/header.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/info.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/license.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/link.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/media_type.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/oauth_flow.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/oauth_flows.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/open_api.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/operation.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/parameter.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/path_item.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/paths.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/reference.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/request_body.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/response.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/responses.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/security_requirement.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/security_scheme.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/server.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/server_variable.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/tag.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/openapi_schema_pydantic/xml.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/schema/parameter_location.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/.gitignore.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/README.md.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/api_init.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/endpoint_init.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/endpoint_macros.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/errors.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/helpers.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/int_enum.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/models_init.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/package_init.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/any_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/boolean_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/date_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/datetime_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/enum_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/file_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/float_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/helpers.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/int_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/list_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/model_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/property_macros.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/property_templates/union_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/pyproject.toml.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/pyproject_ruff.toml.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/setup.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/str_enum.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/templates/types.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: openapi-python-client
|
|
3
|
-
Version: 0.21.
|
|
3
|
+
Version: 0.21.6
|
|
4
4
|
Summary: Generate modern Python clients from OpenAPI
|
|
5
5
|
Project-URL: repository, https://github.com/openapi-generators/openapi-python-client
|
|
6
6
|
Author-email: Dylan Anthony <contact@dylananthony.com>
|
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
20
|
Classifier: Topic :: Software Development :: Code Generators
|
|
20
21
|
Classifier: Typing :: Typed
|
|
21
22
|
Requires-Python: <4.0,>=3.8.1
|
|
@@ -26,7 +27,7 @@ Requires-Dist: jinja2<4.0.0,>=3.0.0
|
|
|
26
27
|
Requires-Dist: pydantic<3.0.0,>=2.1.1
|
|
27
28
|
Requires-Dist: python-dateutil<3.0.0,>=2.8.1
|
|
28
29
|
Requires-Dist: ruamel-yaml<0.19.0,>=0.18.6
|
|
29
|
-
Requires-Dist: ruff<0.
|
|
30
|
+
Requires-Dist: ruff<0.8,>=0.2
|
|
30
31
|
Requires-Dist: shellingham<2.0.0,>=1.3.2
|
|
31
32
|
Requires-Dist: typer<0.13,>0.6
|
|
32
33
|
Requires-Dist: typing-extensions<5.0.0,>=4.8.0
|
|
@@ -131,6 +132,17 @@ class_overrides:
|
|
|
131
132
|
|
|
132
133
|
The easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the `models` folder.
|
|
133
134
|
|
|
135
|
+
### literal_enums
|
|
136
|
+
|
|
137
|
+
By default, `openapi-python-client` generates classes inheriting for `Enum` for enums. It can instead use `Literal`
|
|
138
|
+
values for enums by setting this to `true`:
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
literal_enums: true
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
This is especially useful if enum values, when transformed to their Python names, end up conflicting due to case sensitivity or special symbols.
|
|
145
|
+
|
|
134
146
|
### project_name_override and package_name_override
|
|
135
147
|
|
|
136
148
|
Used to change the name of generated client library project/package. If the project name is changed but an override for the package name
|
|
@@ -97,6 +97,17 @@ class_overrides:
|
|
|
97
97
|
|
|
98
98
|
The easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the `models` folder.
|
|
99
99
|
|
|
100
|
+
### literal_enums
|
|
101
|
+
|
|
102
|
+
By default, `openapi-python-client` generates classes inheriting for `Enum` for enums. It can instead use `Literal`
|
|
103
|
+
values for enums by setting this to `true`:
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
literal_enums: true
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
This is especially useful if enum values, when transformed to their Python names, end up conflicting due to case sensitivity or special symbols.
|
|
110
|
+
|
|
100
111
|
### project_name_override and package_name_override
|
|
101
112
|
|
|
102
113
|
Used to change the name of generated client library project/package. If the project name is changed but an override for the package name
|
{openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/__init__.py
RENAMED
|
@@ -20,6 +20,7 @@ from openapi_python_client import utils
|
|
|
20
20
|
from .config import Config, MetaType
|
|
21
21
|
from .parser import GeneratorData, import_string_from_class
|
|
22
22
|
from .parser.errors import ErrorLevel, GeneratorError
|
|
23
|
+
from .parser.properties import LiteralEnumProperty
|
|
23
24
|
|
|
24
25
|
__version__ = version(__package__)
|
|
25
26
|
|
|
@@ -227,9 +228,12 @@ class Project:
|
|
|
227
228
|
# Generate enums
|
|
228
229
|
str_enum_template = self.env.get_template("str_enum.py.jinja")
|
|
229
230
|
int_enum_template = self.env.get_template("int_enum.py.jinja")
|
|
231
|
+
literal_enum_template = self.env.get_template("literal_enum.py.jinja")
|
|
230
232
|
for enum in self.openapi.enums:
|
|
231
233
|
module_path = models_dir / f"{enum.class_info.module_name}.py"
|
|
232
|
-
if enum
|
|
234
|
+
if isinstance(enum, LiteralEnumProperty):
|
|
235
|
+
module_path.write_text(literal_enum_template.render(enum=enum), encoding=self.config.file_encoding)
|
|
236
|
+
elif enum.value_type is int:
|
|
233
237
|
module_path.write_text(int_enum_template.render(enum=enum), encoding=self.config.file_encoding)
|
|
234
238
|
else:
|
|
235
239
|
module_path.write_text(str_enum_template.render(enum=enum), encoding=self.config.file_encoding)
|
{openapi_python_client-0.21.4 → openapi_python_client-0.21.6}/openapi_python_client/config.py
RENAMED
|
@@ -43,6 +43,7 @@ class ConfigFile(BaseModel):
|
|
|
43
43
|
post_hooks: Optional[List[str]] = None
|
|
44
44
|
field_prefix: str = "field_"
|
|
45
45
|
http_timeout: int = 5
|
|
46
|
+
literal_enums: bool = False
|
|
46
47
|
|
|
47
48
|
@staticmethod
|
|
48
49
|
def load_from_path(path: Path) -> "ConfigFile":
|
|
@@ -70,6 +71,7 @@ class Config:
|
|
|
70
71
|
post_hooks: List[str]
|
|
71
72
|
field_prefix: str
|
|
72
73
|
http_timeout: int
|
|
74
|
+
literal_enums: bool
|
|
73
75
|
document_source: Union[Path, str]
|
|
74
76
|
file_encoding: str
|
|
75
77
|
content_type_overrides: Dict[str, str]
|
|
@@ -109,6 +111,7 @@ class Config:
|
|
|
109
111
|
post_hooks=post_hooks,
|
|
110
112
|
field_prefix=config_file.field_prefix,
|
|
111
113
|
http_timeout=config_file.http_timeout,
|
|
114
|
+
literal_enums=config_file.literal_enums,
|
|
112
115
|
document_source=document_source,
|
|
113
116
|
file_encoding=file_encoding,
|
|
114
117
|
overwrite=overwrite,
|
|
@@ -15,6 +15,7 @@ from .errors import GeneratorError, ParseError, PropertyError
|
|
|
15
15
|
from .properties import (
|
|
16
16
|
Class,
|
|
17
17
|
EnumProperty,
|
|
18
|
+
LiteralEnumProperty,
|
|
18
19
|
ModelProperty,
|
|
19
20
|
Parameters,
|
|
20
21
|
Property,
|
|
@@ -155,7 +156,7 @@ class Endpoint:
|
|
|
155
156
|
ParseError(
|
|
156
157
|
detail=(
|
|
157
158
|
f"Invalid response status code {code} (not a valid HTTP "
|
|
158
|
-
f"status code), response will be
|
|
159
|
+
f"status code), response will be omitted from generated "
|
|
159
160
|
f"client"
|
|
160
161
|
)
|
|
161
162
|
)
|
|
@@ -175,7 +176,7 @@ class Endpoint:
|
|
|
175
176
|
ParseError(
|
|
176
177
|
detail=(
|
|
177
178
|
f"Cannot parse response for status code {status_code}{detail_suffix}, "
|
|
178
|
-
f"response will be
|
|
179
|
+
f"response will be omitted from generated client"
|
|
179
180
|
),
|
|
180
181
|
data=response.data,
|
|
181
182
|
)
|
|
@@ -488,7 +489,7 @@ class GeneratorData:
|
|
|
488
489
|
models: Iterator[ModelProperty]
|
|
489
490
|
errors: List[ParseError]
|
|
490
491
|
endpoint_collections_by_tag: Dict[utils.PythonIdentifier, EndpointCollection]
|
|
491
|
-
enums: Iterator[EnumProperty]
|
|
492
|
+
enums: Iterator[Union[EnumProperty, LiteralEnumProperty]]
|
|
492
493
|
|
|
493
494
|
@staticmethod
|
|
494
495
|
def from_dict(data: Dict[str, Any], *, config: Config) -> Union["GeneratorData", GeneratorError]:
|
|
@@ -517,7 +518,9 @@ class GeneratorData:
|
|
|
517
518
|
data=openapi.paths, schemas=schemas, parameters=parameters, request_bodies=request_bodies, config=config
|
|
518
519
|
)
|
|
519
520
|
|
|
520
|
-
enums = (
|
|
521
|
+
enums = (
|
|
522
|
+
prop for prop in schemas.classes_by_name.values() if isinstance(prop, (EnumProperty, LiteralEnumProperty))
|
|
523
|
+
)
|
|
521
524
|
models = (prop for prop in schemas.classes_by_name.values() if isinstance(prop, ModelProperty))
|
|
522
525
|
|
|
523
526
|
return GeneratorData(
|
|
@@ -4,6 +4,7 @@ __all__ = [
|
|
|
4
4
|
"AnyProperty",
|
|
5
5
|
"Class",
|
|
6
6
|
"EnumProperty",
|
|
7
|
+
"LiteralEnumProperty",
|
|
7
8
|
"ModelProperty",
|
|
8
9
|
"Parameters",
|
|
9
10
|
"Property",
|
|
@@ -30,6 +31,7 @@ from .file import FileProperty
|
|
|
30
31
|
from .float import FloatProperty
|
|
31
32
|
from .int import IntProperty
|
|
32
33
|
from .list_property import ListProperty
|
|
34
|
+
from .literal_enum_property import LiteralEnumProperty
|
|
33
35
|
from .model_property import ModelProperty, process_model
|
|
34
36
|
from .none import NoneProperty
|
|
35
37
|
from .property import Property
|
|
@@ -44,11 +46,12 @@ from .schemas import (
|
|
|
44
46
|
)
|
|
45
47
|
from .string import StringProperty
|
|
46
48
|
from .union import UnionProperty
|
|
49
|
+
from .uuid import UuidProperty
|
|
47
50
|
|
|
48
51
|
|
|
49
52
|
def _string_based_property(
|
|
50
53
|
name: str, required: bool, data: oai.Schema, config: Config
|
|
51
|
-
) -> StringProperty | DateProperty | DateTimeProperty | FileProperty | PropertyError:
|
|
54
|
+
) -> StringProperty | DateProperty | DateTimeProperty | FileProperty | UuidProperty | PropertyError:
|
|
52
55
|
"""Construct a Property from the type "string" """
|
|
53
56
|
string_format = data.schema_format
|
|
54
57
|
python_name = utils.PythonIdentifier(value=name, prefix=config.field_prefix)
|
|
@@ -79,11 +82,19 @@ def _string_based_property(
|
|
|
79
82
|
description=data.description,
|
|
80
83
|
example=data.example,
|
|
81
84
|
)
|
|
85
|
+
if string_format == "uuid":
|
|
86
|
+
return UuidProperty.build(
|
|
87
|
+
name=name,
|
|
88
|
+
required=required,
|
|
89
|
+
default=data.default,
|
|
90
|
+
python_name=python_name,
|
|
91
|
+
description=data.description,
|
|
92
|
+
example=data.example,
|
|
93
|
+
)
|
|
82
94
|
return StringProperty.build(
|
|
83
95
|
name=name,
|
|
84
96
|
default=data.default,
|
|
85
97
|
required=required,
|
|
86
|
-
pattern=data.pattern,
|
|
87
98
|
python_name=python_name,
|
|
88
99
|
description=data.description,
|
|
89
100
|
example=data.example,
|
|
@@ -185,6 +196,15 @@ def property_from_data( # noqa: PLR0911, PLR0912
|
|
|
185
196
|
schemas,
|
|
186
197
|
)
|
|
187
198
|
if data.enum:
|
|
199
|
+
if config.literal_enums:
|
|
200
|
+
return LiteralEnumProperty.build(
|
|
201
|
+
data=data,
|
|
202
|
+
name=name,
|
|
203
|
+
required=required,
|
|
204
|
+
schemas=schemas,
|
|
205
|
+
parent_name=parent_name,
|
|
206
|
+
config=config,
|
|
207
|
+
)
|
|
188
208
|
return EnumProperty.build(
|
|
189
209
|
data=data,
|
|
190
210
|
name=name,
|
|
@@ -281,7 +301,7 @@ def property_from_data( # noqa: PLR0911, PLR0912
|
|
|
281
301
|
AnyProperty.build(
|
|
282
302
|
name=name,
|
|
283
303
|
required=required,
|
|
284
|
-
default=
|
|
304
|
+
default=data.default,
|
|
285
305
|
python_name=utils.PythonIdentifier(value=name, prefix=config.field_prefix),
|
|
286
306
|
description=data.description,
|
|
287
307
|
example=data.example,
|
|
@@ -33,9 +33,13 @@ class AnyProperty(PropertyProtocol):
|
|
|
33
33
|
|
|
34
34
|
@classmethod
|
|
35
35
|
def convert_value(cls, value: Any) -> Value | None:
|
|
36
|
-
|
|
36
|
+
from .string import StringProperty
|
|
37
|
+
|
|
38
|
+
if value is None:
|
|
37
39
|
return value
|
|
38
|
-
|
|
40
|
+
if isinstance(value, str):
|
|
41
|
+
return StringProperty.convert_value(value)
|
|
42
|
+
return Value(python_code=str(value), raw_value=value)
|
|
39
43
|
|
|
40
44
|
name: str
|
|
41
45
|
required: bool
|
|
@@ -59,9 +59,9 @@ class BooleanProperty(PropertyProtocol):
|
|
|
59
59
|
return value
|
|
60
60
|
if isinstance(value, str):
|
|
61
61
|
if value.lower() == "true":
|
|
62
|
-
return Value("True")
|
|
62
|
+
return Value(python_code="True", raw_value=value)
|
|
63
63
|
elif value.lower() == "false":
|
|
64
|
-
return Value("False")
|
|
64
|
+
return Value(python_code="False", raw_value=value)
|
|
65
65
|
if isinstance(value, bool):
|
|
66
|
-
return Value(str(value))
|
|
66
|
+
return Value(python_code=str(value), raw_value=value)
|
|
67
67
|
return PropertyError(f"Invalid boolean value: {value}")
|
|
@@ -63,13 +63,13 @@ class ConstProperty(PropertyProtocol):
|
|
|
63
63
|
return prop
|
|
64
64
|
|
|
65
65
|
def convert_value(self, value: Any) -> Value | None | PropertyError:
|
|
66
|
-
if isinstance(value, Value):
|
|
67
|
-
return value
|
|
68
66
|
value = self._convert_value(value)
|
|
69
67
|
if value is None:
|
|
70
68
|
return value
|
|
71
69
|
if value != self.value:
|
|
72
|
-
return PropertyError(
|
|
70
|
+
return PropertyError(
|
|
71
|
+
detail=f"Invalid value for const {self.name}; {value.raw_value} != {self.value.raw_value}"
|
|
72
|
+
)
|
|
73
73
|
return value
|
|
74
74
|
|
|
75
75
|
@staticmethod
|
|
@@ -85,11 +85,9 @@ class ConstProperty(PropertyProtocol):
|
|
|
85
85
|
def _convert_value(value: Any) -> Value | None:
|
|
86
86
|
if value is None or isinstance(value, Value):
|
|
87
87
|
return value
|
|
88
|
-
if isinstance(value, Value):
|
|
89
|
-
return value # pragma: no cover
|
|
90
88
|
if isinstance(value, str):
|
|
91
89
|
return StringProperty.convert_value(value)
|
|
92
|
-
return Value(str(value))
|
|
90
|
+
return Value(python_code=str(value), raw_value=value)
|
|
93
91
|
|
|
94
92
|
def get_type_string(
|
|
95
93
|
self,
|
|
@@ -99,7 +97,7 @@ class ConstProperty(PropertyProtocol):
|
|
|
99
97
|
multipart: bool = False,
|
|
100
98
|
quoted: bool = False,
|
|
101
99
|
) -> str:
|
|
102
|
-
lit = f"Literal[{self.value}]"
|
|
100
|
+
lit = f"Literal[{self.value.python_code}]"
|
|
103
101
|
if not no_optional and not self.required:
|
|
104
102
|
return f"Union[{lit}, Unset]"
|
|
105
103
|
return lit
|
|
@@ -57,7 +57,7 @@ class DateProperty(PropertyProtocol):
|
|
|
57
57
|
isoparse(value).date() # make sure it's a valid value
|
|
58
58
|
except ValueError as e:
|
|
59
59
|
return PropertyError(f"Invalid date: {e}")
|
|
60
|
-
return Value(f"isoparse({value!r}).date()")
|
|
60
|
+
return Value(python_code=f"isoparse({value!r}).date()", raw_value=value)
|
|
61
61
|
return PropertyError(f"Cannot convert {value} to a date")
|
|
62
62
|
|
|
63
63
|
def get_imports(self, *, prefix: str) -> set[str]:
|
|
@@ -59,7 +59,7 @@ class DateTimeProperty(PropertyProtocol):
|
|
|
59
59
|
isoparse(value) # make sure it's a valid value
|
|
60
60
|
except ValueError as e:
|
|
61
61
|
return PropertyError(f"Invalid datetime: {e}")
|
|
62
|
-
return Value(f"isoparse({value!r})")
|
|
62
|
+
return Value(python_code=f"isoparse({value!r})", raw_value=value)
|
|
63
63
|
return PropertyError(f"Cannot convert {value} to a datetime")
|
|
64
64
|
|
|
65
65
|
def get_imports(self, *, prefix: str) -> set[str]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
__all__ = ["EnumProperty"]
|
|
3
|
+
__all__ = ["EnumProperty", "ValueType"]
|
|
4
4
|
|
|
5
5
|
from typing import Any, ClassVar, List, Union, cast
|
|
6
6
|
|
|
@@ -121,7 +121,7 @@ class EnumProperty(PropertyProtocol):
|
|
|
121
121
|
if parent_name:
|
|
122
122
|
class_name = f"{utils.pascal_case(parent_name)}{utils.pascal_case(class_name)}"
|
|
123
123
|
class_info = Class.from_string(string=class_name, config=config)
|
|
124
|
-
values = EnumProperty.values_from_list(value_list)
|
|
124
|
+
values = EnumProperty.values_from_list(value_list, class_info)
|
|
125
125
|
|
|
126
126
|
if class_info.name in schemas.classes_by_name:
|
|
127
127
|
existing = schemas.classes_by_name[class_info.name]
|
|
@@ -159,7 +159,7 @@ class EnumProperty(PropertyProtocol):
|
|
|
159
159
|
if isinstance(value, self.value_type):
|
|
160
160
|
inverse_values = {v: k for k, v in self.values.items()}
|
|
161
161
|
try:
|
|
162
|
-
return Value(f"{self.class_info.name}.{inverse_values[value]}")
|
|
162
|
+
return Value(python_code=f"{self.class_info.name}.{inverse_values[value]}", raw_value=value)
|
|
163
163
|
except KeyError:
|
|
164
164
|
return PropertyError(detail=f"Value {value} is not valid for enum {self.name}")
|
|
165
165
|
return PropertyError(detail=f"Cannot convert {value} to enum {self.name} of type {self.value_type}")
|
|
@@ -183,7 +183,7 @@ class EnumProperty(PropertyProtocol):
|
|
|
183
183
|
return imports
|
|
184
184
|
|
|
185
185
|
@staticmethod
|
|
186
|
-
def values_from_list(values: list[str] | list[int]) -> dict[str, ValueType]:
|
|
186
|
+
def values_from_list(values: list[str] | list[int], class_info: Class) -> dict[str, ValueType]:
|
|
187
187
|
"""Convert a list of values into dict of {name: value}, where value can sometimes be None"""
|
|
188
188
|
output: dict[str, ValueType] = {}
|
|
189
189
|
|
|
@@ -200,7 +200,10 @@ class EnumProperty(PropertyProtocol):
|
|
|
200
200
|
else:
|
|
201
201
|
key = f"VALUE_{i}"
|
|
202
202
|
if key in output:
|
|
203
|
-
raise ValueError(
|
|
203
|
+
raise ValueError(
|
|
204
|
+
f"Duplicate key {key} in enum {class_info.module_name}.{class_info.name}; "
|
|
205
|
+
f"consider setting literal_enums in your config"
|
|
206
|
+
)
|
|
204
207
|
sanitized_key = utils.snake_case(key).upper()
|
|
205
208
|
output[sanitized_key] = utils.remove_string_escapes(value)
|
|
206
209
|
return output
|
|
@@ -61,11 +61,11 @@ class FloatProperty(PropertyProtocol):
|
|
|
61
61
|
if isinstance(value, str):
|
|
62
62
|
try:
|
|
63
63
|
parsed = float(value)
|
|
64
|
-
return Value(str(parsed))
|
|
64
|
+
return Value(python_code=str(parsed), raw_value=value)
|
|
65
65
|
except ValueError:
|
|
66
66
|
return PropertyError(f"Invalid float value: {value}")
|
|
67
67
|
if isinstance(value, float):
|
|
68
|
-
return Value(str(value))
|
|
68
|
+
return Value(python_code=str(value), raw_value=value)
|
|
69
69
|
if isinstance(value, int) and not isinstance(value, bool):
|
|
70
|
-
return Value(str(float(value)))
|
|
70
|
+
return Value(python_code=str(float(value)), raw_value=value)
|
|
71
71
|
return PropertyError(f"Cannot convert {value} to a float")
|
|
@@ -58,12 +58,16 @@ class IntProperty(PropertyProtocol):
|
|
|
58
58
|
def convert_value(cls, value: Any) -> Value | None | PropertyError:
|
|
59
59
|
if value is None or isinstance(value, Value):
|
|
60
60
|
return value
|
|
61
|
-
|
|
61
|
+
converted = value
|
|
62
|
+
if isinstance(converted, str):
|
|
62
63
|
try:
|
|
63
|
-
|
|
64
|
+
converted = float(converted)
|
|
64
65
|
except ValueError:
|
|
65
|
-
return PropertyError(f"Invalid int value: {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
return PropertyError(f"Invalid int value: {converted}")
|
|
67
|
+
if isinstance(converted, float):
|
|
68
|
+
as_int = int(converted)
|
|
69
|
+
if converted == as_int:
|
|
70
|
+
converted = as_int
|
|
71
|
+
if isinstance(converted, int) and not isinstance(converted, bool):
|
|
72
|
+
return Value(python_code=str(converted), raw_value=value)
|
|
69
73
|
return PropertyError(f"Invalid int value: {value}")
|
|
@@ -58,12 +58,28 @@ class ListProperty(PropertyProtocol):
|
|
|
58
58
|
"""
|
|
59
59
|
from . import property_from_data
|
|
60
60
|
|
|
61
|
-
if data.items is None:
|
|
62
|
-
return
|
|
61
|
+
if data.items is None and not data.prefixItems:
|
|
62
|
+
return (
|
|
63
|
+
PropertyError(
|
|
64
|
+
data=data,
|
|
65
|
+
detail="type array must have items or prefixItems defined",
|
|
66
|
+
),
|
|
67
|
+
schemas,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
items = data.prefixItems or []
|
|
71
|
+
if data.items:
|
|
72
|
+
items.append(data.items)
|
|
73
|
+
|
|
74
|
+
if len(items) == 1:
|
|
75
|
+
inner_schema = items[0]
|
|
76
|
+
else:
|
|
77
|
+
inner_schema = oai.Schema(anyOf=items)
|
|
78
|
+
|
|
63
79
|
inner_prop, schemas = property_from_data(
|
|
64
80
|
name=f"{name}_item",
|
|
65
81
|
required=True,
|
|
66
|
-
data=
|
|
82
|
+
data=inner_schema,
|
|
67
83
|
schemas=schemas,
|
|
68
84
|
parent_name=parent_name,
|
|
69
85
|
config=config,
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
__all__ = ["LiteralEnumProperty"]
|
|
4
|
+
|
|
5
|
+
from typing import Any, ClassVar, List, Union, cast
|
|
6
|
+
|
|
7
|
+
from attr import evolve
|
|
8
|
+
from attrs import define
|
|
9
|
+
|
|
10
|
+
from ... import Config, utils
|
|
11
|
+
from ... import schema as oai
|
|
12
|
+
from ...schema import DataType
|
|
13
|
+
from ..errors import PropertyError
|
|
14
|
+
from .none import NoneProperty
|
|
15
|
+
from .protocol import PropertyProtocol, Value
|
|
16
|
+
from .schemas import Class, Schemas
|
|
17
|
+
from .union import UnionProperty
|
|
18
|
+
|
|
19
|
+
ValueType = Union[str, int]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@define
|
|
23
|
+
class LiteralEnumProperty(PropertyProtocol):
|
|
24
|
+
"""A property that should use a literal enum"""
|
|
25
|
+
|
|
26
|
+
name: str
|
|
27
|
+
required: bool
|
|
28
|
+
default: Value | None
|
|
29
|
+
python_name: utils.PythonIdentifier
|
|
30
|
+
description: str | None
|
|
31
|
+
example: str | None
|
|
32
|
+
values: set[ValueType]
|
|
33
|
+
class_info: Class
|
|
34
|
+
value_type: type[ValueType]
|
|
35
|
+
|
|
36
|
+
template: ClassVar[str] = "literal_enum_property.py.jinja"
|
|
37
|
+
|
|
38
|
+
_allowed_locations: ClassVar[set[oai.ParameterLocation]] = {
|
|
39
|
+
oai.ParameterLocation.QUERY,
|
|
40
|
+
oai.ParameterLocation.PATH,
|
|
41
|
+
oai.ParameterLocation.COOKIE,
|
|
42
|
+
oai.ParameterLocation.HEADER,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def build( # noqa: PLR0911
|
|
47
|
+
cls,
|
|
48
|
+
*,
|
|
49
|
+
data: oai.Schema,
|
|
50
|
+
name: str,
|
|
51
|
+
required: bool,
|
|
52
|
+
schemas: Schemas,
|
|
53
|
+
parent_name: str,
|
|
54
|
+
config: Config,
|
|
55
|
+
) -> tuple[LiteralEnumProperty | NoneProperty | UnionProperty | PropertyError, Schemas]:
|
|
56
|
+
"""
|
|
57
|
+
Create a LiteralEnumProperty from schema data.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
data: The OpenAPI Schema which defines this enum.
|
|
61
|
+
name: The name to use for variables which receive this Enum's value (e.g. model property name)
|
|
62
|
+
required: Whether or not this Property is required in the calling context
|
|
63
|
+
schemas: The Schemas which have been defined so far (used to prevent naming collisions)
|
|
64
|
+
parent_name: The context in which this LiteralEnumProperty is defined, used to create more specific class names.
|
|
65
|
+
config: The global config for this run of the generator
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
A tuple containing either the created property or a PropertyError AND update schemas.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
enum = data.enum or [] # The outer function checks for this, but mypy doesn't know that
|
|
72
|
+
|
|
73
|
+
# OpenAPI allows for null as an enum value, but it doesn't make sense with how enums are constructed in Python.
|
|
74
|
+
# So instead, if null is a possible value, make the property nullable.
|
|
75
|
+
# Mypy is not smart enough to know that the type is right though
|
|
76
|
+
unchecked_value_list = [value for value in enum if value is not None] # type: ignore
|
|
77
|
+
|
|
78
|
+
# It's legal to have an enum that only contains null as a value, we don't bother constructing an enum for that
|
|
79
|
+
if len(unchecked_value_list) == 0:
|
|
80
|
+
return (
|
|
81
|
+
NoneProperty.build(
|
|
82
|
+
name=name,
|
|
83
|
+
required=required,
|
|
84
|
+
default="None",
|
|
85
|
+
python_name=utils.PythonIdentifier(value=name, prefix=config.field_prefix),
|
|
86
|
+
description=None,
|
|
87
|
+
example=None,
|
|
88
|
+
),
|
|
89
|
+
schemas,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
value_types = {type(value) for value in unchecked_value_list}
|
|
93
|
+
if len(value_types) > 1:
|
|
94
|
+
return PropertyError(
|
|
95
|
+
header="Enum values must all be the same type", detail=f"Got {value_types}", data=data
|
|
96
|
+
), schemas
|
|
97
|
+
value_type = next(iter(value_types))
|
|
98
|
+
if value_type not in (str, int):
|
|
99
|
+
return PropertyError(header=f"Unsupported enum type {value_type}", data=data), schemas
|
|
100
|
+
value_list = cast(
|
|
101
|
+
Union[List[int], List[str]], unchecked_value_list
|
|
102
|
+
) # We checked this with all the value_types stuff
|
|
103
|
+
|
|
104
|
+
if len(value_list) < len(enum): # Only one of the values was None, that becomes a union
|
|
105
|
+
data.oneOf = [
|
|
106
|
+
oai.Schema(type=DataType.NULL),
|
|
107
|
+
data.model_copy(update={"enum": value_list, "default": data.default}),
|
|
108
|
+
]
|
|
109
|
+
data.enum = None
|
|
110
|
+
return UnionProperty.build(
|
|
111
|
+
data=data,
|
|
112
|
+
name=name,
|
|
113
|
+
required=required,
|
|
114
|
+
schemas=schemas,
|
|
115
|
+
parent_name=parent_name,
|
|
116
|
+
config=config,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
class_name = data.title or name
|
|
120
|
+
if parent_name:
|
|
121
|
+
class_name = f"{utils.pascal_case(parent_name)}{utils.pascal_case(class_name)}"
|
|
122
|
+
class_info = Class.from_string(string=class_name, config=config)
|
|
123
|
+
values: set[str | int] = set(value_list)
|
|
124
|
+
|
|
125
|
+
if class_info.name in schemas.classes_by_name:
|
|
126
|
+
existing = schemas.classes_by_name[class_info.name]
|
|
127
|
+
if not isinstance(existing, LiteralEnumProperty) or values != existing.values:
|
|
128
|
+
return (
|
|
129
|
+
PropertyError(
|
|
130
|
+
detail=f"Found conflicting enums named {class_info.name} with incompatible values.", data=data
|
|
131
|
+
),
|
|
132
|
+
schemas,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
prop = LiteralEnumProperty(
|
|
136
|
+
name=name,
|
|
137
|
+
required=required,
|
|
138
|
+
class_info=class_info,
|
|
139
|
+
values=values,
|
|
140
|
+
value_type=value_type,
|
|
141
|
+
default=None,
|
|
142
|
+
python_name=utils.PythonIdentifier(value=name, prefix=config.field_prefix),
|
|
143
|
+
description=data.description,
|
|
144
|
+
example=data.example,
|
|
145
|
+
)
|
|
146
|
+
checked_default = prop.convert_value(data.default)
|
|
147
|
+
if isinstance(checked_default, PropertyError):
|
|
148
|
+
checked_default.data = data
|
|
149
|
+
return checked_default, schemas
|
|
150
|
+
prop = evolve(prop, default=checked_default)
|
|
151
|
+
|
|
152
|
+
schemas = evolve(schemas, classes_by_name={**schemas.classes_by_name, class_info.name: prop})
|
|
153
|
+
return prop, schemas
|
|
154
|
+
|
|
155
|
+
def convert_value(self, value: Any) -> Value | PropertyError | None:
|
|
156
|
+
if value is None or isinstance(value, Value):
|
|
157
|
+
return value
|
|
158
|
+
if isinstance(value, self.value_type):
|
|
159
|
+
if value in self.values:
|
|
160
|
+
return Value(python_code=repr(value), raw_value=value)
|
|
161
|
+
else:
|
|
162
|
+
return PropertyError(detail=f"Value {value} is not valid for enum {self.name}")
|
|
163
|
+
return PropertyError(detail=f"Cannot convert {value} to enum {self.name} of type {self.value_type}")
|
|
164
|
+
|
|
165
|
+
def get_base_type_string(self, *, quoted: bool = False) -> str:
|
|
166
|
+
return self.class_info.name
|
|
167
|
+
|
|
168
|
+
def get_base_json_type_string(self, *, quoted: bool = False) -> str:
|
|
169
|
+
return self.value_type.__name__
|
|
170
|
+
|
|
171
|
+
def get_instance_type_string(self) -> str:
|
|
172
|
+
return self.value_type.__name__
|
|
173
|
+
|
|
174
|
+
def get_imports(self, *, prefix: str) -> set[str]:
|
|
175
|
+
"""
|
|
176
|
+
Get a set of import strings that should be included when this property is used somewhere
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
prefix: A prefix to put before any relative (local) module names. This should be the number of . to get
|
|
180
|
+
back to the root of the generated client.
|
|
181
|
+
"""
|
|
182
|
+
imports = super().get_imports(prefix=prefix)
|
|
183
|
+
imports.add("from typing import cast")
|
|
184
|
+
imports.add(f"from {prefix}models.{self.class_info.module_name} import {self.class_info.name}")
|
|
185
|
+
imports.add(
|
|
186
|
+
f"from {prefix}models.{self.class_info.module_name} import check_{self.get_class_name_snake_case()}"
|
|
187
|
+
)
|
|
188
|
+
return imports
|
|
189
|
+
|
|
190
|
+
def get_class_name_snake_case(self) -> str:
|
|
191
|
+
return utils.snake_case(self.class_info.name)
|