5858 HttpxSendArgs ,
5959 AsyncTransport ,
6060 RequestOptions ,
61+ HttpxRequestFiles ,
6162 ModelBuilderProtocol ,
6263)
6364from ._utils import is_dict , is_list , asyncify , is_given , lru_cache , is_mapping
@@ -460,6 +461,7 @@ def _build_request(
460461 headers = self ._build_headers (options )
461462 params = _merge_mappings (self .default_query , options .params )
462463 content_type = headers .get ("Content-Type" )
464+ files = options .files
463465
464466 # If the given Content-Type header is multipart/form-data then it
465467 # has to be removed so that httpx can generate the header with
@@ -473,14 +475,23 @@ def _build_request(
473475 headers .pop ("Content-Type" )
474476
475477 # As we are now sending multipart/form-data instead of application/json
476- # we need to tell httpx to use it, https://www.python-httpx.org/advanced/#multipart-file-encoding
478+ # we need to tell httpx to use it, https://www.python-httpx.org/advanced/clients/ #multipart-file-encoding
477479 if json_data :
478480 if not is_dict (json_data ):
479481 raise TypeError (
480482 f"Expected query input to be a dictionary for multipart requests but got { type (json_data )} instead."
481483 )
482484 kwargs ["data" ] = self ._serialize_multipartform (json_data )
483485
486+ # httpx determines whether or not to send a "multipart/form-data"
487+ # request based on the truthiness of the "files" argument.
488+ # This gets around that issue by generating a dict value that
489+ # evaluates to true.
490+ #
491+ # https://github.com/encode/httpx/discussions/2399#discussioncomment-3814186
492+ if not files :
493+ files = cast (HttpxRequestFiles , ForceMultipartDict ())
494+
484495 # TODO: report this error to httpx
485496 return self ._client .build_request ( # pyright: ignore[reportUnknownMemberType]
486497 headers = headers ,
@@ -493,7 +504,7 @@ def _build_request(
493504 # https://github.com/microsoft/pyright/issues/3526#event-6715453066
494505 params = self .qs .stringify (cast (Mapping [str , Any ], params )) if params else None ,
495506 json = json_data ,
496- files = options . files ,
507+ files = files ,
497508 ** kwargs ,
498509 )
499510
@@ -1890,6 +1901,11 @@ def make_request_options(
18901901 return options
18911902
18921903
1904+ class ForceMultipartDict (Dict [str , None ]):
1905+ def __bool__ (self ) -> bool :
1906+ return True
1907+
1908+
18931909class OtherPlatform :
18941910 def __init__ (self , name : str ) -> None :
18951911 self .name = name
0 commit comments