Skip to content

Commit 172921d

Browse files
author
Constantinos Symeonides
committed
fix: Non-JSON non-file multipart props need to be text/plain
1 parent 646355e commit 172921d

File tree

6 files changed

+143
-8
lines changed

6 files changed

+143
-8
lines changed

end_to_end_tests/golden-record/my_test_api_client/models/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from .an_int_enum import AnIntEnum
99
from .another_all_of_sub_model import AnotherAllOfSubModel
1010
from .body_upload_file_tests_upload_post import BodyUploadFileTestsUploadPost
11+
from .body_upload_file_tests_upload_post_additional_property import BodyUploadFileTestsUploadPostAdditionalProperty
1112
from .body_upload_file_tests_upload_post_some_nullable_object import BodyUploadFileTestsUploadPostSomeNullableObject
1213
from .body_upload_file_tests_upload_post_some_object import BodyUploadFileTestsUploadPostSomeObject
1314
from .body_upload_file_tests_upload_post_some_optional_object import BodyUploadFileTestsUploadPostSomeOptionalObject

end_to_end_tests/golden-record/my_test_api_client/models/body_upload_file_tests_upload_post.py

+59-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@
44

55
import attr
66

7+
from ..models.body_upload_file_tests_upload_post_additional_property import (
8+
BodyUploadFileTestsUploadPostAdditionalProperty,
9+
)
710
from ..models.body_upload_file_tests_upload_post_some_nullable_object import (
811
BodyUploadFileTestsUploadPostSomeNullableObject,
912
)
1013
from ..models.body_upload_file_tests_upload_post_some_object import BodyUploadFileTestsUploadPostSomeObject
1114
from ..models.body_upload_file_tests_upload_post_some_optional_object import (
1215
BodyUploadFileTestsUploadPostSomeOptionalObject,
1316
)
17+
from ..models.different_enum import DifferentEnum
1418
from ..types import UNSET, File, FileJsonType, Unset
1519

1620
T = TypeVar("T", bound="BodyUploadFileTestsUploadPost")
@@ -28,6 +32,10 @@ class BodyUploadFileTestsUploadPost:
2832
some_number: Union[Unset, float] = UNSET
2933
some_array: Union[Unset, List[float]] = UNSET
3034
some_optional_object: Union[Unset, BodyUploadFileTestsUploadPostSomeOptionalObject] = UNSET
35+
some_enum: Union[Unset, DifferentEnum] = UNSET
36+
additional_properties: Dict[str, BodyUploadFileTestsUploadPostAdditionalProperty] = attr.ib(
37+
init=False, factory=dict
38+
)
3139

3240
def to_dict(self) -> Dict[str, Any]:
3341
some_file = self.some_file.to_tuple()
@@ -50,7 +58,14 @@ def to_dict(self) -> Dict[str, Any]:
5058

5159
some_nullable_object = self.some_nullable_object.to_dict() if self.some_nullable_object else None
5260

61+
some_enum: Union[Unset, str] = UNSET
62+
if not isinstance(self.some_enum, Unset):
63+
some_enum = self.some_enum.value
64+
5365
field_dict: Dict[str, Any] = {}
66+
for prop_name, prop in self.additional_properties.items():
67+
field_dict[prop_name] = prop.to_dict()
68+
5469
field_dict.update(
5570
{
5671
"some_file": some_file,
@@ -68,6 +83,8 @@ def to_dict(self) -> Dict[str, Any]:
6883
field_dict["some_array"] = some_array
6984
if some_optional_object is not UNSET:
7085
field_dict["some_optional_object"] = some_optional_object
86+
if some_enum is not UNSET:
87+
field_dict["some_enum"] = some_enum
7188

7289
return field_dict
7390

@@ -80,8 +97,8 @@ def to_multipart(self) -> Dict[str, Any]:
8097
if not isinstance(self.some_optional_file, Unset):
8198
some_optional_file = self.some_optional_file.to_tuple()
8299

83-
some_string = self.some_string
84-
some_number = self.some_number
100+
some_string = self.some_string if self.some_string is UNSET else (None, str(self.some_string), "text/plain")
101+
some_number = self.some_number if self.some_number is UNSET else (None, str(self.some_number), "text/plain")
85102
some_array: Union[Unset, Tuple[None, str, str]] = UNSET
86103
if not isinstance(self.some_array, Unset):
87104
_temp_some_array = self.some_array
@@ -97,7 +114,14 @@ def to_multipart(self) -> Dict[str, Any]:
97114
else None
98115
)
99116

117+
some_enum: Union[Unset, Tuple[None, str, str]] = UNSET
118+
if not isinstance(self.some_enum, Unset):
119+
some_enum = (None, str(self.some_enum.value), "text/plain")
120+
100121
field_dict: Dict[str, Any] = {}
122+
for prop_name, prop in self.additional_properties.items():
123+
field_dict[prop_name] = (None, json.dumps(prop.to_dict()), "application/json")
124+
101125
field_dict.update(
102126
{
103127
"some_file": some_file,
@@ -115,6 +139,8 @@ def to_multipart(self) -> Dict[str, Any]:
115139
field_dict["some_array"] = some_array
116140
if some_optional_object is not UNSET:
117141
field_dict["some_optional_object"] = some_optional_object
142+
if some_enum is not UNSET:
143+
field_dict["some_enum"] = some_enum
118144

119145
return field_dict
120146

@@ -152,6 +178,13 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
152178
else:
153179
some_nullable_object = BodyUploadFileTestsUploadPostSomeNullableObject.from_dict(_some_nullable_object)
154180

181+
_some_enum = d.pop("some_enum", UNSET)
182+
some_enum: Union[Unset, DifferentEnum]
183+
if isinstance(_some_enum, Unset):
184+
some_enum = UNSET
185+
else:
186+
some_enum = DifferentEnum(_some_enum)
187+
155188
body_upload_file_tests_upload_post = cls(
156189
some_file=some_file,
157190
some_object=some_object,
@@ -161,6 +194,30 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
161194
some_array=some_array,
162195
some_optional_object=some_optional_object,
163196
some_nullable_object=some_nullable_object,
197+
some_enum=some_enum,
164198
)
165199

200+
additional_properties = {}
201+
for prop_name, prop_dict in d.items():
202+
additional_property = BodyUploadFileTestsUploadPostAdditionalProperty.from_dict(prop_dict)
203+
204+
additional_properties[prop_name] = additional_property
205+
206+
body_upload_file_tests_upload_post.additional_properties = additional_properties
166207
return body_upload_file_tests_upload_post
208+
209+
@property
210+
def additional_keys(self) -> List[str]:
211+
return list(self.additional_properties.keys())
212+
213+
def __getitem__(self, key: str) -> BodyUploadFileTestsUploadPostAdditionalProperty:
214+
return self.additional_properties[key]
215+
216+
def __setitem__(self, key: str, value: BodyUploadFileTestsUploadPostAdditionalProperty) -> None:
217+
self.additional_properties[key] = value
218+
219+
def __delitem__(self, key: str) -> None:
220+
del self.additional_properties[key]
221+
222+
def __contains__(self, key: str) -> bool:
223+
return key in self.additional_properties
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from typing import Any, Dict, List, Type, TypeVar, Union
2+
3+
import attr
4+
5+
from ..types import UNSET, Unset
6+
7+
T = TypeVar("T", bound="BodyUploadFileTestsUploadPostAdditionalProperty")
8+
9+
10+
@attr.s(auto_attribs=True)
11+
class BodyUploadFileTestsUploadPostAdditionalProperty:
12+
""" """
13+
14+
foo: Union[Unset, str] = UNSET
15+
additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)
16+
17+
def to_dict(self) -> Dict[str, Any]:
18+
foo = self.foo
19+
20+
field_dict: Dict[str, Any] = {}
21+
field_dict.update(self.additional_properties)
22+
field_dict.update({})
23+
if foo is not UNSET:
24+
field_dict["foo"] = foo
25+
26+
return field_dict
27+
28+
@classmethod
29+
def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
30+
d = src_dict.copy()
31+
foo = d.pop("foo", UNSET)
32+
33+
body_upload_file_tests_upload_post_additional_property = cls(
34+
foo=foo,
35+
)
36+
37+
body_upload_file_tests_upload_post_additional_property.additional_properties = d
38+
return body_upload_file_tests_upload_post_additional_property
39+
40+
@property
41+
def additional_keys(self) -> List[str]:
42+
return list(self.additional_properties.keys())
43+
44+
def __getitem__(self, key: str) -> Any:
45+
return self.additional_properties[key]
46+
47+
def __setitem__(self, key: str, value: Any) -> None:
48+
self.additional_properties[key] = value
49+
50+
def __delitem__(self, key: str) -> None:
51+
del self.additional_properties[key]
52+
53+
def __contains__(self, key: str) -> bool:
54+
return key in self.additional_properties

end_to_end_tests/openapi.json

+11-1
Original file line numberDiff line numberDiff line change
@@ -1070,9 +1070,19 @@
10701070
"type": "string"
10711071
}
10721072
}
1073+
},
1074+
"some_enum": {
1075+
"$ref": "#/components/schemas/DifferentEnum"
10731076
}
10741077
},
1075-
"additionalProperties": false
1078+
"additionalProperties": {
1079+
"type": "object",
1080+
"properties": {
1081+
"foo": {
1082+
"type": "string"
1083+
}
1084+
}
1085+
}
10761086
},
10771087
"DifferentEnum": {
10781088
"title": "DifferentEnum",

openapi_python_client/templates/model.py.jinja

+7
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class {{ class_name }}:
4848
{% if property.template %}
4949
{% from "property_templates/" + property.template import transform %}
5050
{{ transform(property, "self." + property.python_name, property.python_name, stringify=multipart) }}
51+
{% elif multipart %}
52+
{{ property.python_name }} = self.{{ property.python_name }} if self.{{ property.python_name }} is UNSET else (None, str(self.{{ property.python_name }}), "text/plain")
5153
{% else %}
5254
{{ property.python_name }} = self.{{ property.python_name }}
5355
{% endif %}
@@ -59,6 +61,11 @@ field_dict: Dict[str, Any] = {}
5961
{% from "property_templates/" + model.additional_properties.template import transform %}
6062
for prop_name, prop in self.additional_properties.items():
6163
{{ transform(model.additional_properties, "prop", "field_dict[prop_name]", stringify=multipart) | indent(4) }}
64+
{% elif multipart %}
65+
field_dict.update({
66+
key: (None, str(value), "text/plain")
67+
for key, value in self.additional_properties.items()
68+
})
6269
{% else %}
6370
field_dict.update(self.additional_properties)
6471
{% endif %}

openapi_python_client/templates/property_templates/enum_property.py.jinja

+11-5
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,25 @@
1111
{% macro check_type_for_construct(property, source) %}isinstance({{ source }}, {{ property.value_type.__name__ }}){% endmacro %}
1212

1313
{% macro transform(property, source, destination, declare_type=True, stringify=False) %}
14+
{% set transformed = source + ".value" %}
15+
{% set type_string = property.get_type_string(json=True) %}
16+
{% if stringify %}
17+
{% set transformed = "(None, str(" + transformed + "), 'text/plain')" %}
18+
{% set type_string = "Union[Unset, Tuple[None, str, str]]" %}
19+
{% endif %}
1420
{% if property.required %}
1521
{% if property.nullable %}
16-
{{ destination }} = {{ source }}.value if {{ source }} else None
22+
{{ destination }} = {{ transformed }} if {{ source }} else None
1723
{% else %}
18-
{{ destination }} = {{ source }}.value
24+
{{ destination }} = {{ transformed }}
1925
{% endif %}
2026
{% else %}
21-
{{ destination }}{% if declare_type %}: {{ property.get_type_string(json=True) }}{% endif %} = UNSET
27+
{{ destination }}{% if declare_type %}: {{ type_string }}{% endif %} = UNSET
2228
if not isinstance({{ source }}, Unset):
2329
{% if property.nullable %}
24-
{{ destination }} = {{ source }}.value if {{ source }} else None
30+
{{ destination }} = {{ transformed }} if {{ source }} else None
2531
{% else %}
26-
{{ destination }} = {{ source }}.value
32+
{{ destination }} = {{ transformed }}
2733
{% endif %}
2834
{% endif %}
2935
{% endmacro %}

0 commit comments

Comments
 (0)