openapi-python-client 0.19.0__tar.gz → 0.20.0__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.19.0 → openapi_python_client-0.20.0}/PKG-INFO +15 -5
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/README.md +10 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/__init__.py +5 -3
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/config.py +6 -2
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/bodies.py +1 -1
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/const.py +3 -2
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/model_property.py +22 -8
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/protocol.py +2 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/responses.py +3 -3
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/client.py.jinja +8 -8
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/endpoint_macros.py.jinja +2 -2
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/model.py.jinja +10 -16
- openapi_python_client-0.20.0/openapi_python_client/templates/property_templates/any_property.py.jinja +7 -0
- openapi_python_client-0.20.0/openapi_python_client/templates/property_templates/boolean_property.py.jinja +11 -0
- openapi_python_client-0.20.0/openapi_python_client/templates/property_templates/const_property.py.jinja +5 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/property_templates/date_property.py.jinja +13 -5
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/property_templates/datetime_property.py.jinja +13 -5
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/property_templates/enum_property.py.jinja +12 -4
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/property_templates/file_property.py.jinja +11 -1
- openapi_python_client-0.20.0/openapi_python_client/templates/property_templates/float_property.py.jinja +11 -0
- openapi_python_client-0.20.0/openapi_python_client/templates/property_templates/int_property.py.jinja +11 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/property_templates/list_property.py.jinja +25 -11
- openapi_python_client-0.20.0/openapi_python_client/templates/property_templates/model_property.py.jinja +47 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/property_templates/union_property.py.jinja +27 -3
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/utils.py +4 -1
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/pyproject.toml +5 -4
- openapi_python_client-0.19.0/openapi_python_client/templates/property_templates/any_property.py.jinja +0 -0
- openapi_python_client-0.19.0/openapi_python_client/templates/property_templates/boolean_property.py.jinja +0 -3
- openapi_python_client-0.19.0/openapi_python_client/templates/property_templates/float_property.py.jinja +0 -3
- openapi_python_client-0.19.0/openapi_python_client/templates/property_templates/int_property.py.jinja +0 -3
- openapi_python_client-0.19.0/openapi_python_client/templates/property_templates/model_property.py.jinja +0 -32
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/.gitignore +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/LICENSE +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/__main__.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/cli.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/__init__.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/errors.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/openapi.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/__init__.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/any.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/boolean.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/date.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/datetime.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/enum_property.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/file.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/float.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/int.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/list_property.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/none.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/property.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/schemas.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/string.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/properties/union.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/py.typed +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/3.0.3.md +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/3.1.0.md +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/__init__.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/data_type.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/LICENSE +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/README.md +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/__init__.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/callback.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/components.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/contact.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/discriminator.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/encoding.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/example.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/external_documentation.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/header.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/info.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/license.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/link.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/media_type.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/oauth_flow.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/oauth_flows.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/open_api.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/operation.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/parameter.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/path_item.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/paths.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/reference.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/request_body.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/response.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/responses.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/schema.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/security_requirement.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/security_scheme.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/server.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/server_variable.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/tag.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/openapi_schema_pydantic/xml.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/parameter_location.py +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/.gitignore.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/README.md.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/api_init.py.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/endpoint_init.py.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/endpoint_module.py.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/errors.py.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/helpers.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/int_enum.py.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/models_init.py.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/package_init.py.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/property_templates/helpers.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/property_templates/property_macros.py.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/pyproject.toml.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/pyproject_ruff.toml.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/setup.py.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/str_enum.py.jinja +0 -0
- {openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/templates/types.py.jinja +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: openapi-python-client
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.0
|
|
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>
|
|
@@ -25,10 +25,10 @@ Requires-Dist: httpx<0.28.0,>=0.20.0
|
|
|
25
25
|
Requires-Dist: jinja2<4.0.0,>=3.0.0
|
|
26
26
|
Requires-Dist: pydantic<3.0.0,>=2.1.1
|
|
27
27
|
Requires-Dist: python-dateutil<3.0.0,>=2.8.1
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist: ruff<0.
|
|
28
|
+
Requires-Dist: ruamel-yaml<0.19.0,>=0.18.6
|
|
29
|
+
Requires-Dist: ruff<0.5,>=0.2
|
|
30
30
|
Requires-Dist: shellingham<2.0.0,>=1.3.2
|
|
31
|
-
Requires-Dist: typer<0.
|
|
31
|
+
Requires-Dist: typer<0.13,>0.6
|
|
32
32
|
Requires-Dist: typing-extensions<5.0.0,>=4.8.0
|
|
33
33
|
Description-Content-Type: text/markdown
|
|
34
34
|
|
|
@@ -190,6 +190,16 @@ If this option results in conflicts, you will need to manually override class na
|
|
|
190
190
|
|
|
191
191
|
By default, the timeout for retrieving the schema file via HTTP is 5 seconds. In case there is an error when retrieving the schema, you might try and increase this setting to a higher value.
|
|
192
192
|
|
|
193
|
+
### content_type_overrides
|
|
194
|
+
|
|
195
|
+
Normally, `openapi-python-client` will skip any bodies or responses that it doesn't recognize the content type for.
|
|
196
|
+
This config tells the generator to treat a given content type like another.
|
|
197
|
+
|
|
198
|
+
```yaml
|
|
199
|
+
content_type_overrides:
|
|
200
|
+
application/zip: application/octet-stream
|
|
201
|
+
```
|
|
202
|
+
|
|
193
203
|
[changelog.md]: CHANGELOG.md
|
|
194
204
|
[poetry]: https://python-poetry.org/
|
|
195
205
|
[PDM]: https://pdm-project.org/latest/
|
|
@@ -156,6 +156,16 @@ If this option results in conflicts, you will need to manually override class na
|
|
|
156
156
|
|
|
157
157
|
By default, the timeout for retrieving the schema file via HTTP is 5 seconds. In case there is an error when retrieving the schema, you might try and increase this setting to a higher value.
|
|
158
158
|
|
|
159
|
+
### content_type_overrides
|
|
160
|
+
|
|
161
|
+
Normally, `openapi-python-client` will skip any bodies or responses that it doesn't recognize the content type for.
|
|
162
|
+
This config tells the generator to treat a given content type like another.
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
content_type_overrides:
|
|
166
|
+
application/zip: application/octet-stream
|
|
167
|
+
```
|
|
168
|
+
|
|
159
169
|
[changelog.md]: CHANGELOG.md
|
|
160
170
|
[poetry]: https://python-poetry.org/
|
|
161
171
|
[PDM]: https://pdm-project.org/latest/
|
{openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/__init__.py
RENAMED
|
@@ -11,8 +11,9 @@ from typing import Any, Dict, List, Optional, Sequence, Union
|
|
|
11
11
|
|
|
12
12
|
import httpcore
|
|
13
13
|
import httpx
|
|
14
|
-
import yaml
|
|
15
14
|
from jinja2 import BaseLoader, ChoiceLoader, Environment, FileSystemLoader, PackageLoader
|
|
15
|
+
from ruamel.yaml import YAML
|
|
16
|
+
from ruamel.yaml.error import YAMLError
|
|
16
17
|
|
|
17
18
|
from openapi_python_client import utils
|
|
18
19
|
|
|
@@ -350,8 +351,9 @@ def _load_yaml_or_json(data: bytes, content_type: Optional[str]) -> Union[Dict[s
|
|
|
350
351
|
return GeneratorError(header=f"Invalid JSON from provided source: {err}")
|
|
351
352
|
else:
|
|
352
353
|
try:
|
|
353
|
-
|
|
354
|
-
|
|
354
|
+
yaml = YAML(typ="safe")
|
|
355
|
+
return yaml.load(data)
|
|
356
|
+
except YAMLError as err:
|
|
355
357
|
return GeneratorError(header=f"Invalid YAML from provided source: {err}")
|
|
356
358
|
|
|
357
359
|
|
{openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/config.py
RENAMED
|
@@ -4,9 +4,9 @@ from enum import Enum
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import Dict, List, Optional, Union
|
|
6
6
|
|
|
7
|
-
import yaml
|
|
8
7
|
from attr import define
|
|
9
8
|
from pydantic import BaseModel
|
|
9
|
+
from ruamel.yaml import YAML
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class ClassOverride(BaseModel):
|
|
@@ -35,6 +35,7 @@ class ConfigFile(BaseModel):
|
|
|
35
35
|
"""
|
|
36
36
|
|
|
37
37
|
class_overrides: Optional[Dict[str, ClassOverride]] = None
|
|
38
|
+
content_type_overrides: Optional[Dict[str, str]] = None
|
|
38
39
|
project_name_override: Optional[str] = None
|
|
39
40
|
package_name_override: Optional[str] = None
|
|
40
41
|
package_version_override: Optional[str] = None
|
|
@@ -50,7 +51,8 @@ class ConfigFile(BaseModel):
|
|
|
50
51
|
if mime == "application/json":
|
|
51
52
|
config_data = json.loads(path.read_text())
|
|
52
53
|
else:
|
|
53
|
-
|
|
54
|
+
yaml = YAML(typ="safe")
|
|
55
|
+
config_data = yaml.load(path)
|
|
54
56
|
config = ConfigFile(**config_data)
|
|
55
57
|
return config
|
|
56
58
|
|
|
@@ -70,6 +72,7 @@ class Config:
|
|
|
70
72
|
http_timeout: int
|
|
71
73
|
document_source: Union[Path, str]
|
|
72
74
|
file_encoding: str
|
|
75
|
+
content_type_overrides: Dict[str, str]
|
|
73
76
|
|
|
74
77
|
@staticmethod
|
|
75
78
|
def from_sources(
|
|
@@ -91,6 +94,7 @@ class Config:
|
|
|
91
94
|
config = Config(
|
|
92
95
|
meta_type=meta_type,
|
|
93
96
|
class_overrides=config_file.class_overrides or {},
|
|
97
|
+
content_type_overrides=config_file.content_type_overrides or {},
|
|
94
98
|
project_name_override=config_file.project_name_override,
|
|
95
99
|
package_name_override=config_file.package_name_override,
|
|
96
100
|
package_version_override=config_file.package_version_override,
|
{openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/bodies.py
RENAMED
|
@@ -56,7 +56,7 @@ def body_from_data(
|
|
|
56
56
|
prefix_type_names = len(body_content) > 1
|
|
57
57
|
|
|
58
58
|
for content_type, media_type in body_content.items():
|
|
59
|
-
simplified_content_type = get_content_type(content_type)
|
|
59
|
+
simplified_content_type = get_content_type(content_type, config)
|
|
60
60
|
if simplified_content_type is None:
|
|
61
61
|
bodies.append(
|
|
62
62
|
ParseError(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Any, overload
|
|
3
|
+
from typing import Any, ClassVar, overload
|
|
4
4
|
|
|
5
5
|
from attr import define
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ from .string import StringProperty
|
|
|
12
12
|
|
|
13
13
|
@define
|
|
14
14
|
class ConstProperty(PropertyProtocol):
|
|
15
|
-
"""A property representing a
|
|
15
|
+
"""A property representing a const value"""
|
|
16
16
|
|
|
17
17
|
name: str
|
|
18
18
|
required: bool
|
|
@@ -21,6 +21,7 @@ class ConstProperty(PropertyProtocol):
|
|
|
21
21
|
python_name: PythonIdentifier
|
|
22
22
|
description: str | None
|
|
23
23
|
example: None
|
|
24
|
+
template: ClassVar[str] = "const_property.py.jinja"
|
|
24
25
|
|
|
25
26
|
@classmethod
|
|
26
27
|
def build(
|
|
@@ -7,7 +7,9 @@ from attrs import define, evolve
|
|
|
7
7
|
|
|
8
8
|
from ... import Config, utils
|
|
9
9
|
from ... import schema as oai
|
|
10
|
+
from ...utils import PythonIdentifier
|
|
10
11
|
from ..errors import ParseError, PropertyError
|
|
12
|
+
from .any import AnyProperty
|
|
11
13
|
from .enum_property import EnumProperty
|
|
12
14
|
from .protocol import PropertyProtocol, Value
|
|
13
15
|
from .schemas import Class, ReferencePath, Schemas, parse_reference_path
|
|
@@ -30,7 +32,7 @@ class ModelProperty(PropertyProtocol):
|
|
|
30
32
|
optional_properties: list[Property] | None
|
|
31
33
|
relative_imports: set[str] | None
|
|
32
34
|
lazy_imports: set[str] | None
|
|
33
|
-
additional_properties:
|
|
35
|
+
additional_properties: Property | None
|
|
34
36
|
_json_type_string: ClassVar[str] = "Dict[str, Any]"
|
|
35
37
|
|
|
36
38
|
template: ClassVar[str] = "model_property.py.jinja"
|
|
@@ -78,7 +80,7 @@ class ModelProperty(PropertyProtocol):
|
|
|
78
80
|
optional_properties: list[Property] | None = None
|
|
79
81
|
relative_imports: set[str] | None = None
|
|
80
82
|
lazy_imports: set[str] | None = None
|
|
81
|
-
additional_properties:
|
|
83
|
+
additional_properties: Property | None = None
|
|
82
84
|
if process_properties:
|
|
83
85
|
data_or_err, schemas = _process_property_data(
|
|
84
86
|
data=data, schemas=schemas, class_info=class_info, config=config, roots=model_roots
|
|
@@ -386,6 +388,16 @@ def _process_properties( # noqa: PLR0912, PLR0911
|
|
|
386
388
|
)
|
|
387
389
|
|
|
388
390
|
|
|
391
|
+
ANY_ADDITIONAL_PROPERTY = AnyProperty.build(
|
|
392
|
+
name="additional",
|
|
393
|
+
required=True,
|
|
394
|
+
default=None,
|
|
395
|
+
description="",
|
|
396
|
+
python_name=PythonIdentifier(value="additional", prefix=""),
|
|
397
|
+
example=None,
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
|
|
389
401
|
def _get_additional_properties(
|
|
390
402
|
*,
|
|
391
403
|
schema_additional: None | (bool | (oai.Reference | oai.Schema)),
|
|
@@ -393,18 +405,20 @@ def _get_additional_properties(
|
|
|
393
405
|
class_name: utils.ClassName,
|
|
394
406
|
config: Config,
|
|
395
407
|
roots: set[ReferencePath | utils.ClassName],
|
|
396
|
-
) -> tuple[
|
|
408
|
+
) -> tuple[Property | None | PropertyError, Schemas]:
|
|
397
409
|
from . import property_from_data
|
|
398
410
|
|
|
399
411
|
if schema_additional is None:
|
|
400
|
-
return
|
|
412
|
+
return ANY_ADDITIONAL_PROPERTY, schemas
|
|
401
413
|
|
|
402
414
|
if isinstance(schema_additional, bool):
|
|
403
|
-
|
|
415
|
+
if schema_additional:
|
|
416
|
+
return ANY_ADDITIONAL_PROPERTY, schemas
|
|
417
|
+
return None, schemas
|
|
404
418
|
|
|
405
419
|
if isinstance(schema_additional, oai.Schema) and not any(schema_additional.model_dump().values()):
|
|
406
420
|
# An empty schema
|
|
407
|
-
return
|
|
421
|
+
return ANY_ADDITIONAL_PROPERTY, schemas
|
|
408
422
|
|
|
409
423
|
additional_properties, schemas = property_from_data(
|
|
410
424
|
name="AdditionalProperty",
|
|
@@ -425,7 +439,7 @@ def _process_property_data(
|
|
|
425
439
|
class_info: Class,
|
|
426
440
|
config: Config,
|
|
427
441
|
roots: set[ReferencePath | utils.ClassName],
|
|
428
|
-
) -> tuple[tuple[_PropertyData,
|
|
442
|
+
) -> tuple[tuple[_PropertyData, Property | None] | PropertyError, Schemas]:
|
|
429
443
|
property_data = _process_properties(
|
|
430
444
|
data=data, schemas=schemas, class_name=class_info.name, config=config, roots=roots
|
|
431
445
|
)
|
|
@@ -442,7 +456,7 @@ def _process_property_data(
|
|
|
442
456
|
)
|
|
443
457
|
if isinstance(additional_properties, PropertyError):
|
|
444
458
|
return additional_properties, schemas
|
|
445
|
-
elif
|
|
459
|
+
elif additional_properties is None:
|
|
446
460
|
pass
|
|
447
461
|
else:
|
|
448
462
|
property_data.relative_imports.update(additional_properties.get_imports(prefix=".."))
|
|
@@ -107,6 +107,8 @@ class PropertyProtocol(Protocol):
|
|
|
107
107
|
"""
|
|
108
108
|
if json:
|
|
109
109
|
type_string = self.get_base_json_type_string(quoted=quoted)
|
|
110
|
+
elif multipart:
|
|
111
|
+
type_string = "Tuple[None, bytes, str]"
|
|
110
112
|
else:
|
|
111
113
|
type_string = self.get_base_type_string(quoted=quoted)
|
|
112
114
|
|
|
@@ -37,8 +37,8 @@ class Response:
|
|
|
37
37
|
data: Union[oai.Response, oai.Reference] # Original data which created this response, useful for custom templates
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
def _source_by_content_type(content_type: str) -> Optional[_ResponseSource]:
|
|
41
|
-
parsed_content_type = utils.get_content_type(content_type)
|
|
40
|
+
def _source_by_content_type(content_type: str, config: Config) -> Optional[_ResponseSource]:
|
|
41
|
+
parsed_content_type = utils.get_content_type(content_type, config)
|
|
42
42
|
if parsed_content_type is None:
|
|
43
43
|
return None
|
|
44
44
|
|
|
@@ -114,7 +114,7 @@ def response_from_data(
|
|
|
114
114
|
)
|
|
115
115
|
|
|
116
116
|
for content_type, media_type in content.items():
|
|
117
|
-
source = _source_by_content_type(content_type)
|
|
117
|
+
source = _source_by_content_type(content_type, config)
|
|
118
118
|
if source is not None:
|
|
119
119
|
schema_data = media_type.media_type_schema
|
|
120
120
|
break
|
|
@@ -37,13 +37,13 @@ class Client:
|
|
|
37
37
|
"""
|
|
38
38
|
{% macro attributes() %}
|
|
39
39
|
raise_on_unexpected_status: bool = field(default=False, kw_only=True)
|
|
40
|
-
_base_url: str
|
|
41
|
-
_cookies: Dict[str, str] = field(factory=dict, kw_only=True)
|
|
42
|
-
_headers: Dict[str, str] = field(factory=dict, kw_only=True)
|
|
43
|
-
_timeout: Optional[httpx.Timeout] = field(default=None, kw_only=True)
|
|
44
|
-
_verify_ssl: Union[str, bool, ssl.SSLContext] = field(default=True, kw_only=True)
|
|
45
|
-
_follow_redirects: bool = field(default=False, kw_only=True)
|
|
46
|
-
_httpx_args: Dict[str, Any] = field(factory=dict, kw_only=True)
|
|
40
|
+
_base_url: str = field(alias="base_url")
|
|
41
|
+
_cookies: Dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
|
|
42
|
+
_headers: Dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
|
|
43
|
+
_timeout: Optional[httpx.Timeout] = field(default=None, kw_only=True, alias="timeout")
|
|
44
|
+
_verify_ssl: Union[str, bool, ssl.SSLContext] = field(default=True, kw_only=True, alias="verify_ssl")
|
|
45
|
+
_follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects")
|
|
46
|
+
_httpx_args: Dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args")
|
|
47
47
|
_client: Optional[httpx.Client] = field(default=None, init=False)
|
|
48
48
|
_async_client: Optional[httpx.AsyncClient] = field(default=None, init=False)
|
|
49
49
|
{% endmacro %}{{ attributes() }}
|
|
@@ -163,4 +163,4 @@ class AuthenticatedClient:
|
|
|
163
163
|
auth_header_name: str = "Authorization"
|
|
164
164
|
|
|
165
165
|
{{ builders("AuthenticatedClient") }}
|
|
166
|
-
{{ httpx_stuff("AuthenticatedClient", "self._headers[self.auth_header_name] = f\"{self.prefix} {self.token}\" if self.prefix else self.token") }}
|
|
166
|
+
{{ httpx_stuff("AuthenticatedClient", "self._headers[self.auth_header_name] = f\"{self.prefix} {self.token}\" if self.prefix else self.token") }}
|
|
@@ -83,8 +83,8 @@ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
|
|
|
83
83
|
{% macro multipart_body(body, destination) %}
|
|
84
84
|
{% set property = body.prop %}
|
|
85
85
|
{% import "property_templates/" + property.template as prop_template %}
|
|
86
|
-
{% if prop_template.
|
|
87
|
-
{{ prop_template.
|
|
86
|
+
{% if prop_template.transform_multipart_body %}
|
|
87
|
+
{{ prop_template.transform_multipart_body(property, property.python_name, destination) }}
|
|
88
88
|
{% endif %}
|
|
89
89
|
{% endmacro %}
|
|
90
90
|
|
|
@@ -80,10 +80,10 @@ class {{ class_name }}:
|
|
|
80
80
|
{% macro _to_dict(multipart=False) %}
|
|
81
81
|
{% for property in model.required_properties + model.optional_properties %}
|
|
82
82
|
{% import "property_templates/" + property.template as prop_template %}
|
|
83
|
-
{% if
|
|
84
|
-
{{ prop_template.
|
|
85
|
-
{% elif
|
|
86
|
-
{{ property
|
|
83
|
+
{% if multipart %}
|
|
84
|
+
{{ prop_template.transform_multipart(property, "self." + property.python_name, property.python_name) }}
|
|
85
|
+
{% elif prop_template.transform %}
|
|
86
|
+
{{ prop_template.transform(property=property, source="self." + property.python_name, destination=property.python_name) }}
|
|
87
87
|
{% else %}
|
|
88
88
|
{{ property.python_name }} = self.{{ property.python_name }}
|
|
89
89
|
{% endif %}
|
|
@@ -92,19 +92,13 @@ class {{ class_name }}:
|
|
|
92
92
|
|
|
93
93
|
field_dict: Dict[str, Any] = {}
|
|
94
94
|
{% if model.additional_properties %}
|
|
95
|
-
{%
|
|
96
|
-
|
|
97
|
-
{% else %}
|
|
98
|
-
{% set prop_template = None %}
|
|
99
|
-
{% endif %}
|
|
100
|
-
{% if prop_template and prop_template.transform %}
|
|
95
|
+
{% import "property_templates/" + model.additional_properties.template as prop_template %}
|
|
96
|
+
{% if multipart %}
|
|
101
97
|
for prop_name, prop in self.additional_properties.items():
|
|
102
|
-
{{ prop_template.
|
|
103
|
-
{% elif
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
for key, value in self.additional_properties.items()
|
|
107
|
-
})
|
|
98
|
+
{{ prop_template.transform_multipart(model.additional_properties, "prop", "field_dict[prop_name]") | indent(4) }}
|
|
99
|
+
{% elif prop_template.transform %}
|
|
100
|
+
for prop_name, prop in self.additional_properties.items():
|
|
101
|
+
{{ prop_template.transform(model.additional_properties, "prop", "field_dict[prop_name]", declare_type=false) | indent(4) }}
|
|
108
102
|
{% else %}
|
|
109
103
|
field_dict.update(self.additional_properties)
|
|
110
104
|
{% endif %}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{% macro transform_multipart(property, source, destination) %}
|
|
2
|
+
{% if not property.required %}
|
|
3
|
+
{{ destination }} = {{source}} if isinstance({{source}}, Unset) else (None, str({{source}}).encode(), "text/plain")
|
|
4
|
+
{% else %}
|
|
5
|
+
{{ destination }} = (None, str({{ source }}).encode(), "text/plain")
|
|
6
|
+
{% endif %}
|
|
7
|
+
{% endmacro %}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{% macro transform_header(source) %}
|
|
2
|
+
"true" if {{ source }} else "false"
|
|
3
|
+
{% endmacro %}
|
|
4
|
+
|
|
5
|
+
{% macro transform_multipart(property, source, destination) %}
|
|
6
|
+
{% if not property.required %}
|
|
7
|
+
{{ destination }} = {{source}} if isinstance({{source}}, Unset) else (None, str({{source}}).encode(), "text/plain")
|
|
8
|
+
{% else %}
|
|
9
|
+
{{ destination }} = (None, str({{ source }}).encode(), "text/plain")
|
|
10
|
+
{% endif %}
|
|
11
|
+
{% endmacro %}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{% macro construct(property, source) %}
|
|
2
|
+
{{ property.python_name }} = cast({{ property.get_type_string() }} , {{ source }})
|
|
3
|
+
if {{ property.python_name }} != {{ property.value }}{% if not property.required %}and not isinstance({{ property.python_name }}, Unset){% endif %}:
|
|
4
|
+
raise ValueError(f"{{ property.name }} must match const {{ property.value }}, got '{{'{' + property.python_name + '}' }}'")
|
|
5
|
+
{%- endmacro %}
|
|
@@ -10,17 +10,13 @@ isoparse({{ source }}).date()
|
|
|
10
10
|
|
|
11
11
|
{% macro check_type_for_construct(property, source) %}isinstance({{ source }}, str){% endmacro %}
|
|
12
12
|
|
|
13
|
-
{% macro transform(property, source, destination, declare_type=True
|
|
13
|
+
{% macro transform(property, source, destination, declare_type=True) %}
|
|
14
14
|
{% set transformed = source + ".isoformat()" %}
|
|
15
|
-
{% if multipart %}{# Multipart data must be bytes, not str #}
|
|
16
|
-
{% set transformed = transformed + ".encode()" %}
|
|
17
|
-
{% endif %}
|
|
18
15
|
{% if property.required %}
|
|
19
16
|
{{ destination }} = {{ transformed }}
|
|
20
17
|
{%- else %}
|
|
21
18
|
{% if declare_type %}
|
|
22
19
|
{% set type_annotation = property.get_type_string(json=True) %}
|
|
23
|
-
{% if multipart %}{% set type_annotation = type_annotation | replace("str", "bytes") %}{% endif %}
|
|
24
20
|
{{ destination }}: {{ type_annotation }} = UNSET
|
|
25
21
|
{% else %}
|
|
26
22
|
{{ destination }} = UNSET
|
|
@@ -29,3 +25,15 @@ if not isinstance({{ source }}, Unset):
|
|
|
29
25
|
{{ destination }} = {{ transformed }}
|
|
30
26
|
{%- endif %}
|
|
31
27
|
{% endmacro %}
|
|
28
|
+
|
|
29
|
+
{% macro transform_multipart(property, source, destination) %}
|
|
30
|
+
{% set transformed = source + ".isoformat().encode()" %}
|
|
31
|
+
{% if property.required %}
|
|
32
|
+
{{ destination }} = {{ transformed }}
|
|
33
|
+
{%- else %}
|
|
34
|
+
{% set type_annotation = property.get_type_string(json=True) | replace("str", "bytes") %}
|
|
35
|
+
{{ destination }}: {{ type_annotation }} = UNSET
|
|
36
|
+
if not isinstance({{ source }}, Unset):
|
|
37
|
+
{{ destination }} = {{ transformed }}
|
|
38
|
+
{%- endif %}
|
|
39
|
+
{% endmacro %}
|
|
@@ -10,17 +10,13 @@ isoparse({{ source }})
|
|
|
10
10
|
|
|
11
11
|
{% macro check_type_for_construct(property, source) %}isinstance({{ source }}, str){% endmacro %}
|
|
12
12
|
|
|
13
|
-
{% macro transform(property, source, destination, declare_type=True
|
|
13
|
+
{% macro transform(property, source, destination, declare_type=True) %}
|
|
14
14
|
{% set transformed = source + ".isoformat()" %}
|
|
15
|
-
{% if multipart %}{# Multipart data must be bytes, not str #}
|
|
16
|
-
{% set transformed = transformed + ".encode()" %}
|
|
17
|
-
{% endif %}
|
|
18
15
|
{% if property.required %}
|
|
19
16
|
{{ destination }} = {{ transformed }}
|
|
20
17
|
{%- else %}
|
|
21
18
|
{% if declare_type %}
|
|
22
19
|
{% set type_annotation = property.get_type_string(json=True) %}
|
|
23
|
-
{% if multipart %}{% set type_annotation = type_annotation | replace("str", "bytes") %}{% endif %}
|
|
24
20
|
{{ destination }}: {{ type_annotation }} = UNSET
|
|
25
21
|
{% else %}
|
|
26
22
|
{{ destination }} = UNSET
|
|
@@ -29,3 +25,15 @@ if not isinstance({{ source }}, Unset):
|
|
|
29
25
|
{{ destination }} = {{ transformed }}
|
|
30
26
|
{%- endif %}
|
|
31
27
|
{% endmacro %}
|
|
28
|
+
|
|
29
|
+
{% macro transform_multipart(property, source, destination) %}
|
|
30
|
+
{% set transformed = source + ".isoformat().encode()" %}
|
|
31
|
+
{% if property.required %}
|
|
32
|
+
{{ destination }} = {{ transformed }}
|
|
33
|
+
{%- else %}
|
|
34
|
+
{% set type_annotation = property.get_type_string(json=True) | replace("str", "bytes") %}
|
|
35
|
+
{{ destination }}: {{ type_annotation }} = UNSET
|
|
36
|
+
if not isinstance({{ source }}, Unset):
|
|
37
|
+
{{ destination }} = {{ transformed }}
|
|
38
|
+
{%- endif %}
|
|
39
|
+
{% endmacro %}
|
|
@@ -13,10 +13,6 @@
|
|
|
13
13
|
{% macro transform(property, source, destination, declare_type=True, multipart=False) %}
|
|
14
14
|
{% set transformed = source + ".value" %}
|
|
15
15
|
{% set type_string = property.get_type_string(json=True) %}
|
|
16
|
-
{% if multipart %}
|
|
17
|
-
{% set transformed = "(None, str(" + transformed + ").encode(), \"text/plain\")" %}
|
|
18
|
-
{% set type_string = "Union[Unset, Tuple[None, bytes, str]]" %}
|
|
19
|
-
{% endif %}
|
|
20
16
|
{% if property.required %}
|
|
21
17
|
{{ destination }} = {{ transformed }}
|
|
22
18
|
{%- else %}
|
|
@@ -26,6 +22,18 @@ if not isinstance({{ source }}, Unset):
|
|
|
26
22
|
{% endif %}
|
|
27
23
|
{% endmacro %}
|
|
28
24
|
|
|
25
|
+
{% macro transform_multipart(property, source, destination) %}
|
|
26
|
+
{% set transformed = "(None, str(" + source + ".value" + ").encode(), \"text/plain\")" %}
|
|
27
|
+
{% set type_string = "Union[Unset, Tuple[None, bytes, str]]" %}
|
|
28
|
+
{% if property.required %}
|
|
29
|
+
{{ destination }} = {{ transformed }}
|
|
30
|
+
{%- else %}
|
|
31
|
+
{{ destination }}: {{ type_string }} = UNSET
|
|
32
|
+
if not isinstance({{ source }}, Unset):
|
|
33
|
+
{{ destination }} = {{ transformed }}
|
|
34
|
+
{% endif %}
|
|
35
|
+
{% endmacro %}
|
|
36
|
+
|
|
29
37
|
{% macro transform_header(source) %}
|
|
30
38
|
str({{ source }})
|
|
31
39
|
{% endmacro %}
|
|
@@ -12,7 +12,7 @@ File(
|
|
|
12
12
|
|
|
13
13
|
{% macro check_type_for_construct(property, source) %}isinstance({{ source }}, bytes){% endmacro %}
|
|
14
14
|
|
|
15
|
-
{% macro transform(property, source, destination, declare_type=True
|
|
15
|
+
{% macro transform(property, source, destination, declare_type=True) %}
|
|
16
16
|
{% if property.required %}
|
|
17
17
|
{{ destination }} = {{ source }}.to_tuple()
|
|
18
18
|
{% else %}
|
|
@@ -21,3 +21,13 @@ if not isinstance({{ source }}, Unset):
|
|
|
21
21
|
{{ destination }} = {{ source }}.to_tuple()
|
|
22
22
|
{% endif %}
|
|
23
23
|
{% endmacro %}
|
|
24
|
+
|
|
25
|
+
{% macro transform_multipart(property, source, destination) %}
|
|
26
|
+
{% if property.required %}
|
|
27
|
+
{{ destination }} = {{ source }}.to_tuple()
|
|
28
|
+
{% else %}
|
|
29
|
+
{{ destination }}: {{ property.get_type_string(json=True) }} = UNSET
|
|
30
|
+
if not isinstance({{ source }}, Unset):
|
|
31
|
+
{{ destination }} = {{ source }}.to_tuple()
|
|
32
|
+
{% endif %}
|
|
33
|
+
{% endmacro %}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{% macro transform_header(source) %}
|
|
2
|
+
str({{ source }})
|
|
3
|
+
{% endmacro %}
|
|
4
|
+
|
|
5
|
+
{% macro transform_multipart(property, source, destination) %}
|
|
6
|
+
{% if not property.required %}
|
|
7
|
+
{{ destination }} = {{source}} if isinstance({{source}}, Unset) else (None, str({{source}}).encode(), "text/plain")
|
|
8
|
+
{% else %}
|
|
9
|
+
{{ destination }} = (None, str({{ source }}).encode(), "text/plain")
|
|
10
|
+
{% endif %}
|
|
11
|
+
{% endmacro %}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{% macro transform_header(source) %}
|
|
2
|
+
str({{ source }})
|
|
3
|
+
{% endmacro %}
|
|
4
|
+
|
|
5
|
+
{% macro transform_multipart(property, source, destination) %}
|
|
6
|
+
{% if not property.required %}
|
|
7
|
+
{{ destination }} = {{source}} if isinstance({{source}}, Unset) else (None, str({{source}}).encode(), "text/plain")
|
|
8
|
+
{% else %}
|
|
9
|
+
{{ destination }} = (None, str({{ source }}).encode(), "text/plain")
|
|
10
|
+
{% endif %}
|
|
11
|
+
{% endmacro %}
|
|
@@ -40,24 +40,38 @@ for {{ inner_source }} in {{ source }}:
|
|
|
40
40
|
|
|
41
41
|
{% macro check_type_for_construct(property, source) %}isinstance({{ source }}, list){% endmacro %}
|
|
42
42
|
|
|
43
|
-
{% macro transform(property, source, destination, declare_type=True
|
|
43
|
+
{% macro transform(property, source, destination, declare_type=True) %}
|
|
44
44
|
{% set inner_property = property.inner_property %}
|
|
45
|
-
{%
|
|
46
|
-
{% set type_string = "Union[Unset, Tuple[None, bytes, str]]" %}
|
|
47
|
-
{% else %}
|
|
48
|
-
{% set type_string = property.get_type_string(json=True) %}
|
|
49
|
-
{% endif %}
|
|
45
|
+
{% set type_string = property.get_type_string(json=True) %}
|
|
50
46
|
{% if property.required %}
|
|
51
|
-
{{ _transform(property, source, destination,
|
|
47
|
+
{{ _transform(property, source, destination, False, "to_dict") }}
|
|
52
48
|
{% else %}
|
|
53
49
|
{{ destination }}{% if declare_type %}: {{ type_string }}{% endif %} = UNSET
|
|
54
50
|
if not isinstance({{ source }}, Unset):
|
|
55
|
-
{{ _transform(property, source, destination,
|
|
51
|
+
{{ _transform(property, source, destination, False, "to_dict") | indent(4)}}
|
|
56
52
|
{% endif %}
|
|
57
|
-
|
|
58
|
-
|
|
59
53
|
{% endmacro %}
|
|
60
54
|
|
|
61
55
|
{% macro transform_multipart(property, source, destination) %}
|
|
62
|
-
{
|
|
56
|
+
{% set inner_property = property.inner_property %}
|
|
57
|
+
{% set type_string = "Union[Unset, Tuple[None, bytes, str]]" %}
|
|
58
|
+
{% if property.required %}
|
|
59
|
+
{{ _transform(property, source, destination, True, "to_dict") }}
|
|
60
|
+
{% else %}
|
|
61
|
+
{{ destination }}: {{ type_string }} = UNSET
|
|
62
|
+
if not isinstance({{ source }}, Unset):
|
|
63
|
+
{{ _transform(property, source, destination, True, "to_dict") | indent(4)}}
|
|
64
|
+
{% endif %}
|
|
65
|
+
{% endmacro %}
|
|
66
|
+
|
|
67
|
+
{% macro transform_multipart_body(property, source, destination) %}
|
|
68
|
+
{% set inner_property = property.inner_property %}
|
|
69
|
+
{% set type_string = property.get_type_string(json=True) %}
|
|
70
|
+
{% if property.required %}
|
|
71
|
+
{{ _transform(property, source, destination, False, "to_multipart") }}
|
|
72
|
+
{% else %}
|
|
73
|
+
{{ destination }}: {{ type_string }} = UNSET
|
|
74
|
+
if not isinstance({{ source }}, Unset):
|
|
75
|
+
{{ _transform(property, source, destination, False, "to_multipart") | indent(4)}}
|
|
76
|
+
{% endif %}
|
|
63
77
|
{% endmacro %}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{% macro construct_function(property, source) %}
|
|
2
|
+
{{ property.class_info.name }}.from_dict({{ source }})
|
|
3
|
+
{% endmacro %}
|
|
4
|
+
|
|
5
|
+
{% from "property_templates/property_macros.py.jinja" import construct_template %}
|
|
6
|
+
|
|
7
|
+
{% macro construct(property, source) %}
|
|
8
|
+
{{ construct_template(construct_function, property, source) }}
|
|
9
|
+
{% endmacro %}
|
|
10
|
+
|
|
11
|
+
{% macro check_type_for_construct(property, source) %}isinstance({{ source }}, dict){% endmacro %}
|
|
12
|
+
|
|
13
|
+
{% macro transform(property, source, destination, declare_type=True) %}
|
|
14
|
+
{% set transformed = source + ".to_dict()" %}
|
|
15
|
+
{% set type_string = property.get_type_string(json=True) %}
|
|
16
|
+
{% if property.required %}
|
|
17
|
+
{{ destination }} = {{ transformed }}
|
|
18
|
+
{%- else %}
|
|
19
|
+
{{ destination }}{% if declare_type %}: {{ type_string }}{% endif %} = UNSET
|
|
20
|
+
if not isinstance({{ source }}, Unset):
|
|
21
|
+
{{ destination }} = {{ transformed }}
|
|
22
|
+
{%- endif %}
|
|
23
|
+
{% endmacro %}
|
|
24
|
+
|
|
25
|
+
{% macro transform_multipart_body(property, source, destination) %}
|
|
26
|
+
{% set transformed = source + ".to_multipart()" %}
|
|
27
|
+
{% set type_string = property.get_type_string(multipart=True) %}
|
|
28
|
+
{% if property.required %}
|
|
29
|
+
{{ destination }} = {{ transformed }}
|
|
30
|
+
{%- else %}
|
|
31
|
+
{{ destination }}: {{ type_string }} = UNSET
|
|
32
|
+
if not isinstance({{ source }}, Unset):
|
|
33
|
+
{{ destination }} = {{ transformed }}
|
|
34
|
+
{%- endif %}
|
|
35
|
+
{% endmacro %}
|
|
36
|
+
|
|
37
|
+
{% macro transform_multipart(property, source, destination) %}
|
|
38
|
+
{% set transformed = "(None, json.dumps(" + source + ".to_dict()" + ").encode(), 'application/json')" %}
|
|
39
|
+
{% set type_string = property.get_type_string(multipart=True) %}
|
|
40
|
+
{% if property.required %}
|
|
41
|
+
{{ destination }} = {{ transformed }}
|
|
42
|
+
{%- else %}
|
|
43
|
+
{{ destination }}: {{ type_string }} = UNSET
|
|
44
|
+
if not isinstance({{ source }}, Unset):
|
|
45
|
+
{{ destination }} = {{ transformed }}
|
|
46
|
+
{%- endif %}
|
|
47
|
+
{% endmacro %}
|
|
@@ -39,9 +39,9 @@ def _parse_{{ property.python_name }}(data: object) -> {{ property.get_type_stri
|
|
|
39
39
|
{{ property.python_name }} = _parse_{{ property.python_name }}({{ source }})
|
|
40
40
|
{% endmacro %}
|
|
41
41
|
|
|
42
|
-
{% macro transform(property, source, destination, declare_type=True
|
|
42
|
+
{% macro transform(property, source, destination, declare_type=True) %}
|
|
43
43
|
{% set ns = namespace(contains_properties_without_transform = false, contains_modified_properties = not property.required, has_if = false) %}
|
|
44
|
-
{% if declare_type %}{{ destination }}: {{ property.get_type_string(json=
|
|
44
|
+
{% if declare_type %}{{ destination }}: {{ property.get_type_string(json=True, multipart=False) }}{% endif %}
|
|
45
45
|
|
|
46
46
|
{% if not property.required %}
|
|
47
47
|
if isinstance({{ source }}, Unset):
|
|
@@ -64,7 +64,7 @@ elif isinstance({{ source }}, {{ inner_property.get_instance_type_string() }}):
|
|
|
64
64
|
{% else %}
|
|
65
65
|
else:
|
|
66
66
|
{% endif %}
|
|
67
|
-
{{ inner_template.transform(inner_property, source, destination, declare_type=False
|
|
67
|
+
{{ inner_template.transform(inner_property, source, destination, declare_type=False) | indent(4) }}
|
|
68
68
|
{% endfor %}
|
|
69
69
|
{% if ns.contains_properties_without_transform and ns.contains_modified_properties %}
|
|
70
70
|
else:
|
|
@@ -73,3 +73,27 @@ else:
|
|
|
73
73
|
{{ destination }} = {{ source }}
|
|
74
74
|
{%- endif %}
|
|
75
75
|
{% endmacro %}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
{% macro transform_multipart(property, source, destination) %}
|
|
79
|
+
{% set ns = namespace(has_if = false) %}
|
|
80
|
+
{{ destination }}: {{ property.get_type_string(json=False, multipart=True) }}
|
|
81
|
+
|
|
82
|
+
{% if not property.required %}
|
|
83
|
+
if isinstance({{ source }}, Unset):
|
|
84
|
+
{{ destination }} = UNSET
|
|
85
|
+
{% set ns.has_if = true %}
|
|
86
|
+
{% endif %}
|
|
87
|
+
{% for inner_property in property.inner_properties %}
|
|
88
|
+
{% if not ns.has_if %}
|
|
89
|
+
if isinstance({{ source }}, {{ inner_property.get_instance_type_string() }}):
|
|
90
|
+
{% set ns.has_if = true %}
|
|
91
|
+
{% elif not loop.last %}
|
|
92
|
+
elif isinstance({{ source }}, {{ inner_property.get_instance_type_string() }}):
|
|
93
|
+
{% else %}
|
|
94
|
+
else:
|
|
95
|
+
{% endif %}
|
|
96
|
+
{% import "property_templates/" + inner_property.template as inner_template %}
|
|
97
|
+
{{ inner_template.transform_multipart(inner_property, source, destination) | indent(4) | trim }}
|
|
98
|
+
{% endfor %}
|
|
99
|
+
{% endmacro %}
|
{openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/utils.py
RENAMED
|
@@ -6,6 +6,8 @@ from email.message import Message
|
|
|
6
6
|
from keyword import iskeyword
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
|
+
from .config import Config
|
|
10
|
+
|
|
9
11
|
DELIMITERS = r"\. _-"
|
|
10
12
|
|
|
11
13
|
|
|
@@ -105,10 +107,11 @@ def remove_string_escapes(value: str) -> str:
|
|
|
105
107
|
return value.replace('"', r"\"")
|
|
106
108
|
|
|
107
109
|
|
|
108
|
-
def get_content_type(content_type: str) -> str | None:
|
|
110
|
+
def get_content_type(content_type: str, config: Config) -> str | None:
|
|
109
111
|
"""
|
|
110
112
|
Given a string representing a content type with optional parameters, returns the content type only
|
|
111
113
|
"""
|
|
114
|
+
content_type = config.content_type_overrides.get(content_type, content_type)
|
|
112
115
|
message = Message()
|
|
113
116
|
message.add_header("Content-Type", content_type)
|
|
114
117
|
|
|
@@ -6,19 +6,19 @@ license = { text = "MIT" }
|
|
|
6
6
|
requires-python = ">=3.8,<4.0"
|
|
7
7
|
dependencies = [
|
|
8
8
|
"jinja2>=3.0.0,<4.0.0",
|
|
9
|
-
"typer>0.6,<0.
|
|
9
|
+
"typer>0.6,<0.13",
|
|
10
10
|
"colorama>=0.4.3; sys_platform == \"win32\"",
|
|
11
11
|
"shellingham>=1.3.2,<2.0.0",
|
|
12
12
|
"pydantic>=2.1.1,<3.0.0",
|
|
13
13
|
"attrs>=21.3.0",
|
|
14
14
|
"python-dateutil>=2.8.1,<3.0.0",
|
|
15
15
|
"httpx>=0.20.0,<0.28.0",
|
|
16
|
-
"
|
|
17
|
-
"ruff>=0.2,<0.
|
|
16
|
+
"ruamel.yaml>=0.18.6,<0.19.0",
|
|
17
|
+
"ruff>=0.2,<0.5",
|
|
18
18
|
"typing-extensions>=4.8.0,<5.0.0",
|
|
19
19
|
]
|
|
20
20
|
name = "openapi-python-client"
|
|
21
|
-
version = "0.
|
|
21
|
+
version = "0.20.0"
|
|
22
22
|
description = "Generate modern Python clients from OpenAPI"
|
|
23
23
|
keywords = [
|
|
24
24
|
"OpenAPI",
|
|
@@ -97,6 +97,7 @@ dev = [
|
|
|
97
97
|
"types-PyYAML<7.0.0,>=6.0.3",
|
|
98
98
|
"types-certifi<2021.10.9,>=2020.0.0",
|
|
99
99
|
"types-python-dateutil<3.0.0,>=2.0.0",
|
|
100
|
+
"ruamel-yaml-string>=0.1.1",
|
|
100
101
|
]
|
|
101
102
|
|
|
102
103
|
[tool.pdm.build]
|
|
File without changes
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
{% macro construct_function(property, source) %}
|
|
2
|
-
{{ property.class_info.name }}.from_dict({{ source }})
|
|
3
|
-
{% endmacro %}
|
|
4
|
-
|
|
5
|
-
{% from "property_templates/property_macros.py.jinja" import construct_template %}
|
|
6
|
-
|
|
7
|
-
{% macro construct(property, source) %}
|
|
8
|
-
{{ construct_template(construct_function, property, source) }}
|
|
9
|
-
{% endmacro %}
|
|
10
|
-
|
|
11
|
-
{% macro check_type_for_construct(property, source) %}isinstance({{ source }}, dict){% endmacro %}
|
|
12
|
-
|
|
13
|
-
{% macro transform(property, source, destination, declare_type=True, multipart=False, transform_method="to_dict") %}
|
|
14
|
-
{% set transformed = source + "." + transform_method + "()" %}
|
|
15
|
-
{% if multipart %}
|
|
16
|
-
{% set transformed = "(None, json.dumps(" + transformed + ").encode(), 'application/json')" %}
|
|
17
|
-
{% set type_string = property.get_type_string(multipart=True) %}
|
|
18
|
-
{% else %}
|
|
19
|
-
{% set type_string = property.get_type_string(json=True) %}
|
|
20
|
-
{% endif %}
|
|
21
|
-
{% if property.required %}
|
|
22
|
-
{{ destination }} = {{ transformed }}
|
|
23
|
-
{%- else %}
|
|
24
|
-
{{ destination }}{% if declare_type %}: {{ type_string }}{% endif %} = UNSET
|
|
25
|
-
if not isinstance({{ source }}, Unset):
|
|
26
|
-
{{ destination }} = {{ transformed }}
|
|
27
|
-
{%- endif %}
|
|
28
|
-
{% endmacro %}
|
|
29
|
-
|
|
30
|
-
{% macro transform_multipart(property, source, destination) %}
|
|
31
|
-
{{ transform(property, source, destination, transform_method="to_multipart") }}
|
|
32
|
-
{% endmacro %}
|
|
File without changes
|
|
File without changes
|
{openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/parser/errors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/py.typed
RENAMED
|
File without changes
|
{openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/3.0.3.md
RENAMED
|
File without changes
|
{openapi_python_client-0.19.0 → openapi_python_client-0.20.0}/openapi_python_client/schema/3.1.0.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|