feat(python): handle multiple file parameters (#19329)

* test: fix broken python test

* fix: handle multiple file parameters

Previously an array of files was not handled correctly, despite the type
annotation implying it was.

* feat: handle filename,filedata tuples in file param

This allows for users to pass filenames with their data in file params,
which is useful for multipart formdata requests. Without this, the list
of files added in the previous commit would have the same filename for
all files (the parameter name).
This commit is contained in:
Rory Schadler
2024-08-21 03:09:10 -04:00
committed by GitHub
parent c2472b03b6
commit cc98333d87
38 changed files with 673 additions and 235 deletions

View File

@@ -239,7 +239,9 @@ class AuthApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -483,7 +485,9 @@ class AuthApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters

View File

@@ -18,7 +18,7 @@ from typing import Any, Dict, List, Optional, Tuple, Union
from typing_extensions import Annotated
from pydantic import Field, StrictBytes, StrictStr
from typing import Any, Dict, List, Optional, Union
from typing import Any, Dict, List, Optional, Tuple, Union
from typing_extensions import Annotated
from openapi_client.models.pet import Pet
from openapi_client.models.string_enum_ref import StringEnumRef
@@ -244,7 +244,9 @@ class BodyApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -288,7 +290,7 @@ class BodyApi:
@validate_call
def test_body_application_octetstream_binary(
self,
body: Optional[Union[StrictBytes, StrictStr]] = None,
body: Optional[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -355,7 +357,7 @@ class BodyApi:
@validate_call
def test_body_application_octetstream_binary_with_http_info(
self,
body: Optional[Union[StrictBytes, StrictStr]] = None,
body: Optional[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -422,7 +424,7 @@ class BodyApi:
@validate_call
def test_body_application_octetstream_binary_without_preload_content(
self,
body: Optional[Union[StrictBytes, StrictStr]] = None,
body: Optional[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -500,7 +502,9 @@ class BodyApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -513,6 +517,9 @@ class BodyApi:
if isinstance(body, str):
with open(body, "rb") as _fp:
_body_params = _fp.read()
elif isinstance(body, tuple):
# drop the filename from the tuple
_body_params = body[1]
else:
_body_params = body
@@ -564,7 +571,7 @@ class BodyApi:
@validate_call
def test_body_multipart_formdata_array_of_binary(
self,
files: List[Union[StrictBytes, StrictStr]],
files: List[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -631,7 +638,7 @@ class BodyApi:
@validate_call
def test_body_multipart_formdata_array_of_binary_with_http_info(
self,
files: List[Union[StrictBytes, StrictStr]],
files: List[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -698,7 +705,7 @@ class BodyApi:
@validate_call
def test_body_multipart_formdata_array_of_binary_without_preload_content(
self,
files: List[Union[StrictBytes, StrictStr]],
files: List[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]],
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -777,7 +784,9 @@ class BodyApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -836,7 +845,7 @@ class BodyApi:
@validate_call
def test_body_multipart_formdata_single_binary(
self,
my_file: Optional[Union[StrictBytes, StrictStr]] = None,
my_file: Optional[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -903,7 +912,7 @@ class BodyApi:
@validate_call
def test_body_multipart_formdata_single_binary_with_http_info(
self,
my_file: Optional[Union[StrictBytes, StrictStr]] = None,
my_file: Optional[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -970,7 +979,7 @@ class BodyApi:
@validate_call
def test_body_multipart_formdata_single_binary_without_preload_content(
self,
my_file: Optional[Union[StrictBytes, StrictStr]] = None,
my_file: Optional[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]] = None,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
@@ -1048,7 +1057,9 @@ class BodyApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -1319,7 +1330,9 @@ class BodyApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -1590,7 +1603,9 @@ class BodyApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -1861,7 +1876,9 @@ class BodyApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -2132,7 +2149,9 @@ class BodyApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -2403,7 +2422,9 @@ class BodyApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -2674,7 +2695,9 @@ class BodyApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters

View File

@@ -280,7 +280,9 @@ class FormApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -555,7 +557,9 @@ class FormApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -891,7 +895,9 @@ class FormApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters

View File

@@ -306,7 +306,9 @@ class HeaderApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters

View File

@@ -292,7 +292,9 @@ class PathApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters

View File

@@ -270,7 +270,9 @@ class QueryApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -560,7 +562,9 @@ class QueryApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -872,7 +876,9 @@ class QueryApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -1140,7 +1146,9 @@ class QueryApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -1400,7 +1408,9 @@ class QueryApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -1661,7 +1671,9 @@ class QueryApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -1922,7 +1934,9 @@ class QueryApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -2182,7 +2196,9 @@ class QueryApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -2442,7 +2458,9 @@ class QueryApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters
@@ -2702,7 +2720,9 @@ class QueryApi:
_query_params: List[Tuple[str, str]] = []
_header_params: Dict[str, Optional[str]] = _headers or {}
_form_params: List[Tuple[str, str]] = []
_files: Dict[str, Union[str, bytes]] = {}
_files: Dict[
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
] = {}
_body_params: Optional[bytes] = None
# process the path parameters

View File

@@ -536,7 +536,10 @@ class ApiClient:
return "&".join(["=".join(map(str, item)) for item in new_params])
def files_parameters(self, files: Dict[str, Union[str, bytes]]):
def files_parameters(
self,
files: Dict[str, Union[str, bytes, List[str], List[bytes], Tuple[str, bytes]]],
):
"""Builds form parameters.
:param files: File parameters.
@@ -551,6 +554,12 @@ class ApiClient:
elif isinstance(v, bytes):
filename = k
filedata = v
elif isinstance(v, tuple):
filename, filedata = v
elif isinstance(v, list):
for file_param in v:
params.extend(self.files_parameters({k: file_param}))
continue
else:
raise ValueError("Unsupported file value")
mimetype = (