Skip to content

Commit 1586c69

Browse files
authored
[python] Fix multipart requests with type file fails with binary data (#18079)
* [python] fix Multipart requests with type file fails with binary data #18073 * [python] update sample
1 parent 5975e6c commit 1586c69

33 files changed

Lines changed: 283 additions & 276 deletions

File tree

modules/openapi-generator/src/main/resources/python/api.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class {{classname}}:
101101
_query_params: List[Tuple[str, str]] = []
102102
_header_params: Dict[str, Optional[str]] = _headers or {}
103103
_form_params: List[Tuple[str, str]] = []
104-
_files: Dict[str, str] = {}
104+
_files: Dict[str, Union[str, bytes]] = {}
105105
_body_params: Optional[bytes] = None
106106

107107
# process the path parameters

modules/openapi-generator/src/main/resources/python/api_client.mustache

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import re
1212
import tempfile
1313

1414
from urllib.parse import quote
15-
from typing import Tuple, Optional, List, Dict
15+
from typing import Tuple, Optional, List, Dict, Union
1616
{{#tornado}}
1717
import tornado.gen
1818
{{/tornado}}
@@ -212,7 +212,8 @@ class ApiClient:
212212
post_params,
213213
collection_formats
214214
)
215-
post_params.extend(self.files_parameters(files))
215+
if files:
216+
post_params.extend(self.files_parameters(files))
216217

217218
# auth setting
218219
self.update_params_for_auth(
@@ -515,31 +516,30 @@ class ApiClient:
515516

516517
return "&".join(["=".join(map(str, item)) for item in new_params])
517518

518-
def files_parameters(self, files=None):
519+
def files_parameters(self, files: Dict[str, Union[str, bytes]]):
519520
"""Builds form parameters.
520521

521522
:param files: File parameters.
522523
:return: Form parameters with files.
523524
"""
524525
params = []
525-
526-
if files:
527-
for k, v in files.items():
528-
if not v:
529-
continue
530-
file_names = v if type(v) is list else [v]
531-
for n in file_names:
532-
with open(n, 'rb') as f:
533-
filename = os.path.basename(f.name)
534-
filedata = f.read()
535-
mimetype = (
536-
mimetypes.guess_type(filename)[0]
537-
or 'application/octet-stream'
538-
)
539-
params.append(
540-
tuple([k, tuple([filename, filedata, mimetype])])
541-
)
542-
526+
for k, v in files.items():
527+
if isinstance(v, str):
528+
with open(v, 'rb') as f:
529+
filename = os.path.basename(f.name)
530+
filedata = f.read()
531+
elif isinstance(v, bytes):
532+
filename = k
533+
filedata = v
534+
else:
535+
raise ValueError("Unsupported file value")
536+
mimetype = (
537+
mimetypes.guess_type(filename)[0]
538+
or 'application/octet-stream'
539+
)
540+
params.append(
541+
tuple([k, tuple([filename, filedata, mimetype])])
542+
)
543543
return params
544544

545545
def select_header_accept(self, accepts: List[str]) -> Optional[str]:

samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/auth_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ def _test_auth_http_basic_serialize(
238238
_query_params: List[Tuple[str, str]] = []
239239
_header_params: Dict[str, Optional[str]] = _headers or {}
240240
_form_params: List[Tuple[str, str]] = []
241-
_files: Dict[str, str] = {}
241+
_files: Dict[str, Union[str, bytes]] = {}
242242
_body_params: Optional[bytes] = None
243243

244244
# process the path parameters
@@ -481,7 +481,7 @@ def _test_auth_http_bearer_serialize(
481481
_query_params: List[Tuple[str, str]] = []
482482
_header_params: Dict[str, Optional[str]] = _headers or {}
483483
_form_params: List[Tuple[str, str]] = []
484-
_files: Dict[str, str] = {}
484+
_files: Dict[str, Union[str, bytes]] = {}
485485
_body_params: Optional[bytes] = None
486486

487487
# process the path parameters

samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/body_api.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ def _test_binary_gif_serialize(
244244
_query_params: List[Tuple[str, str]] = []
245245
_header_params: Dict[str, Optional[str]] = _headers or {}
246246
_form_params: List[Tuple[str, str]] = []
247-
_files: Dict[str, str] = {}
247+
_files: Dict[str, Union[str, bytes]] = {}
248248
_body_params: Optional[bytes] = None
249249

250250
# process the path parameters
@@ -499,7 +499,7 @@ def _test_body_application_octetstream_binary_serialize(
499499
_query_params: List[Tuple[str, str]] = []
500500
_header_params: Dict[str, Optional[str]] = _headers or {}
501501
_form_params: List[Tuple[str, str]] = []
502-
_files: Dict[str, str] = {}
502+
_files: Dict[str, Union[str, bytes]] = {}
503503
_body_params: Optional[bytes] = None
504504

505505
# process the path parameters
@@ -775,7 +775,7 @@ def _test_body_multipart_formdata_array_of_binary_serialize(
775775
_query_params: List[Tuple[str, str]] = []
776776
_header_params: Dict[str, Optional[str]] = _headers or {}
777777
_form_params: List[Tuple[str, str]] = []
778-
_files: Dict[str, str] = {}
778+
_files: Dict[str, Union[str, bytes]] = {}
779779
_body_params: Optional[bytes] = None
780780

781781
# process the path parameters
@@ -1045,7 +1045,7 @@ def _test_body_multipart_formdata_single_binary_serialize(
10451045
_query_params: List[Tuple[str, str]] = []
10461046
_header_params: Dict[str, Optional[str]] = _headers or {}
10471047
_form_params: List[Tuple[str, str]] = []
1048-
_files: Dict[str, str] = {}
1048+
_files: Dict[str, Union[str, bytes]] = {}
10491049
_body_params: Optional[bytes] = None
10501050

10511051
# process the path parameters
@@ -1315,7 +1315,7 @@ def _test_echo_body_all_of_pet_serialize(
13151315
_query_params: List[Tuple[str, str]] = []
13161316
_header_params: Dict[str, Optional[str]] = _headers or {}
13171317
_form_params: List[Tuple[str, str]] = []
1318-
_files: Dict[str, str] = {}
1318+
_files: Dict[str, Union[str, bytes]] = {}
13191319
_body_params: Optional[bytes] = None
13201320

13211321
# process the path parameters
@@ -1585,7 +1585,7 @@ def _test_echo_body_free_form_object_response_string_serialize(
15851585
_query_params: List[Tuple[str, str]] = []
15861586
_header_params: Dict[str, Optional[str]] = _headers or {}
15871587
_form_params: List[Tuple[str, str]] = []
1588-
_files: Dict[str, str] = {}
1588+
_files: Dict[str, Union[str, bytes]] = {}
15891589
_body_params: Optional[bytes] = None
15901590

15911591
# process the path parameters
@@ -1855,7 +1855,7 @@ def _test_echo_body_pet_serialize(
18551855
_query_params: List[Tuple[str, str]] = []
18561856
_header_params: Dict[str, Optional[str]] = _headers or {}
18571857
_form_params: List[Tuple[str, str]] = []
1858-
_files: Dict[str, str] = {}
1858+
_files: Dict[str, Union[str, bytes]] = {}
18591859
_body_params: Optional[bytes] = None
18601860

18611861
# process the path parameters
@@ -2125,7 +2125,7 @@ def _test_echo_body_pet_response_string_serialize(
21252125
_query_params: List[Tuple[str, str]] = []
21262126
_header_params: Dict[str, Optional[str]] = _headers or {}
21272127
_form_params: List[Tuple[str, str]] = []
2128-
_files: Dict[str, str] = {}
2128+
_files: Dict[str, Union[str, bytes]] = {}
21292129
_body_params: Optional[bytes] = None
21302130

21312131
# process the path parameters
@@ -2395,7 +2395,7 @@ def _test_echo_body_string_enum_serialize(
23952395
_query_params: List[Tuple[str, str]] = []
23962396
_header_params: Dict[str, Optional[str]] = _headers or {}
23972397
_form_params: List[Tuple[str, str]] = []
2398-
_files: Dict[str, str] = {}
2398+
_files: Dict[str, Union[str, bytes]] = {}
23992399
_body_params: Optional[bytes] = None
24002400

24012401
# process the path parameters
@@ -2665,7 +2665,7 @@ def _test_echo_body_tag_response_string_serialize(
26652665
_query_params: List[Tuple[str, str]] = []
26662666
_header_params: Dict[str, Optional[str]] = _headers or {}
26672667
_form_params: List[Tuple[str, str]] = []
2668-
_files: Dict[str, str] = {}
2668+
_files: Dict[str, Union[str, bytes]] = {}
26692669
_body_params: Optional[bytes] = None
26702670

26712671
# process the path parameters

samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/form_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def _test_form_integer_boolean_string_serialize(
279279
_query_params: List[Tuple[str, str]] = []
280280
_header_params: Dict[str, Optional[str]] = _headers or {}
281281
_form_params: List[Tuple[str, str]] = []
282-
_files: Dict[str, str] = {}
282+
_files: Dict[str, Union[str, bytes]] = {}
283283
_body_params: Optional[bytes] = None
284284

285285
# process the path parameters
@@ -618,7 +618,7 @@ def _test_form_oneof_serialize(
618618
_query_params: List[Tuple[str, str]] = []
619619
_header_params: Dict[str, Optional[str]] = _headers or {}
620620
_form_params: List[Tuple[str, str]] = []
621-
_files: Dict[str, str] = {}
621+
_files: Dict[str, Union[str, bytes]] = {}
622622
_body_params: Optional[bytes] = None
623623

624624
# process the path parameters

samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/header_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ def _test_header_integer_boolean_string_enums_serialize(
306306
_query_params: List[Tuple[str, str]] = []
307307
_header_params: Dict[str, Optional[str]] = _headers or {}
308308
_form_params: List[Tuple[str, str]] = []
309-
_files: Dict[str, str] = {}
309+
_files: Dict[str, Union[str, bytes]] = {}
310310
_body_params: Optional[bytes] = None
311311

312312
# process the path parameters

samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/path_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ def _tests_path_string_path_string_integer_path_integer_enum_nonref_string_path_
292292
_query_params: List[Tuple[str, str]] = []
293293
_header_params: Dict[str, Optional[str]] = _headers or {}
294294
_form_params: List[Tuple[str, str]] = []
295-
_files: Dict[str, str] = {}
295+
_files: Dict[str, Union[str, bytes]] = {}
296296
_body_params: Optional[bytes] = None
297297

298298
# process the path parameters

samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/query_api.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ def _test_enum_ref_string_serialize(
270270
_query_params: List[Tuple[str, str]] = []
271271
_header_params: Dict[str, Optional[str]] = _headers or {}
272272
_form_params: List[Tuple[str, str]] = []
273-
_files: Dict[str, str] = {}
273+
_files: Dict[str, Union[str, bytes]] = {}
274274
_body_params: Optional[bytes] = None
275275

276276
# process the path parameters
@@ -559,7 +559,7 @@ def _test_query_datetime_date_string_serialize(
559559
_query_params: List[Tuple[str, str]] = []
560560
_header_params: Dict[str, Optional[str]] = _headers or {}
561561
_form_params: List[Tuple[str, str]] = []
562-
_files: Dict[str, str] = {}
562+
_files: Dict[str, Union[str, bytes]] = {}
563563
_body_params: Optional[bytes] = None
564564

565565
# process the path parameters
@@ -870,7 +870,7 @@ def _test_query_integer_boolean_string_serialize(
870870
_query_params: List[Tuple[str, str]] = []
871871
_header_params: Dict[str, Optional[str]] = _headers or {}
872872
_form_params: List[Tuple[str, str]] = []
873-
_files: Dict[str, str] = {}
873+
_files: Dict[str, Union[str, bytes]] = {}
874874
_body_params: Optional[bytes] = None
875875

876876
# process the path parameters
@@ -1137,7 +1137,7 @@ def _test_query_style_deep_object_explode_true_object_serialize(
11371137
_query_params: List[Tuple[str, str]] = []
11381138
_header_params: Dict[str, Optional[str]] = _headers or {}
11391139
_form_params: List[Tuple[str, str]] = []
1140-
_files: Dict[str, str] = {}
1140+
_files: Dict[str, Union[str, bytes]] = {}
11411141
_body_params: Optional[bytes] = None
11421142

11431143
# process the path parameters
@@ -1396,7 +1396,7 @@ def _test_query_style_deep_object_explode_true_object_all_of_serialize(
13961396
_query_params: List[Tuple[str, str]] = []
13971397
_header_params: Dict[str, Optional[str]] = _headers or {}
13981398
_form_params: List[Tuple[str, str]] = []
1399-
_files: Dict[str, str] = {}
1399+
_files: Dict[str, Union[str, bytes]] = {}
14001400
_body_params: Optional[bytes] = None
14011401

14021402
# process the path parameters
@@ -1656,7 +1656,7 @@ def _test_query_style_form_explode_false_array_integer_serialize(
16561656
_query_params: List[Tuple[str, str]] = []
16571657
_header_params: Dict[str, Optional[str]] = _headers or {}
16581658
_form_params: List[Tuple[str, str]] = []
1659-
_files: Dict[str, str] = {}
1659+
_files: Dict[str, Union[str, bytes]] = {}
16601660
_body_params: Optional[bytes] = None
16611661

16621662
# process the path parameters
@@ -1916,7 +1916,7 @@ def _test_query_style_form_explode_false_array_string_serialize(
19161916
_query_params: List[Tuple[str, str]] = []
19171917
_header_params: Dict[str, Optional[str]] = _headers or {}
19181918
_form_params: List[Tuple[str, str]] = []
1919-
_files: Dict[str, str] = {}
1919+
_files: Dict[str, Union[str, bytes]] = {}
19201920
_body_params: Optional[bytes] = None
19211921

19221922
# process the path parameters
@@ -2175,7 +2175,7 @@ def _test_query_style_form_explode_true_array_string_serialize(
21752175
_query_params: List[Tuple[str, str]] = []
21762176
_header_params: Dict[str, Optional[str]] = _headers or {}
21772177
_form_params: List[Tuple[str, str]] = []
2178-
_files: Dict[str, str] = {}
2178+
_files: Dict[str, Union[str, bytes]] = {}
21792179
_body_params: Optional[bytes] = None
21802180

21812181
# process the path parameters
@@ -2434,7 +2434,7 @@ def _test_query_style_form_explode_true_object_serialize(
24342434
_query_params: List[Tuple[str, str]] = []
24352435
_header_params: Dict[str, Optional[str]] = _headers or {}
24362436
_form_params: List[Tuple[str, str]] = []
2437-
_files: Dict[str, str] = {}
2437+
_files: Dict[str, Union[str, bytes]] = {}
24382438
_body_params: Optional[bytes] = None
24392439

24402440
# process the path parameters
@@ -2693,7 +2693,7 @@ def _test_query_style_form_explode_true_object_all_of_serialize(
26932693
_query_params: List[Tuple[str, str]] = []
26942694
_header_params: Dict[str, Optional[str]] = _headers or {}
26952695
_form_params: List[Tuple[str, str]] = []
2696-
_files: Dict[str, str] = {}
2696+
_files: Dict[str, Union[str, bytes]] = {}
26972697
_body_params: Optional[bytes] = None
26982698

26992699
# process the path parameters

samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api_client.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import tempfile
2424

2525
from urllib.parse import quote
26-
from typing import Tuple, Optional, List, Dict
26+
from typing import Tuple, Optional, List, Dict, Union
2727

2828
from openapi_client.configuration import Configuration
2929
from openapi_client.api_response import ApiResponse, T as ApiResponseT
@@ -208,7 +208,8 @@ def param_serialize(
208208
post_params,
209209
collection_formats
210210
)
211-
post_params.extend(self.files_parameters(files))
211+
if files:
212+
post_params.extend(self.files_parameters(files))
212213

213214
# auth setting
214215
self.update_params_for_auth(
@@ -508,31 +509,30 @@ def parameters_to_url_query(self, params, collection_formats):
508509

509510
return "&".join(["=".join(map(str, item)) for item in new_params])
510511

511-
def files_parameters(self, files=None):
512+
def files_parameters(self, files: Dict[str, Union[str, bytes]]):
512513
"""Builds form parameters.
513514
514515
:param files: File parameters.
515516
:return: Form parameters with files.
516517
"""
517518
params = []
518-
519-
if files:
520-
for k, v in files.items():
521-
if not v:
522-
continue
523-
file_names = v if type(v) is list else [v]
524-
for n in file_names:
525-
with open(n, 'rb') as f:
526-
filename = os.path.basename(f.name)
527-
filedata = f.read()
528-
mimetype = (
529-
mimetypes.guess_type(filename)[0]
530-
or 'application/octet-stream'
531-
)
532-
params.append(
533-
tuple([k, tuple([filename, filedata, mimetype])])
534-
)
535-
519+
for k, v in files.items():
520+
if isinstance(v, str):
521+
with open(v, 'rb') as f:
522+
filename = os.path.basename(f.name)
523+
filedata = f.read()
524+
elif isinstance(v, bytes):
525+
filename = k
526+
filedata = v
527+
else:
528+
raise ValueError("Unsupported file value")
529+
mimetype = (
530+
mimetypes.guess_type(filename)[0]
531+
or 'application/octet-stream'
532+
)
533+
params.append(
534+
tuple([k, tuple([filename, filedata, mimetype])])
535+
)
536536
return params
537537

538538
def select_header_accept(self, accepts: List[str]) -> Optional[str]:

samples/client/echo_api/python/openapi_client/api/auth_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ def _test_auth_http_basic_serialize(
238238
_query_params: List[Tuple[str, str]] = []
239239
_header_params: Dict[str, Optional[str]] = _headers or {}
240240
_form_params: List[Tuple[str, str]] = []
241-
_files: Dict[str, str] = {}
241+
_files: Dict[str, Union[str, bytes]] = {}
242242
_body_params: Optional[bytes] = None
243243

244244
# process the path parameters
@@ -481,7 +481,7 @@ def _test_auth_http_bearer_serialize(
481481
_query_params: List[Tuple[str, str]] = []
482482
_header_params: Dict[str, Optional[str]] = _headers or {}
483483
_form_params: List[Tuple[str, str]] = []
484-
_files: Dict[str, str] = {}
484+
_files: Dict[str, Union[str, bytes]] = {}
485485
_body_params: Optional[bytes] = None
486486

487487
# process the path parameters

0 commit comments

Comments
 (0)