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
@@ -459,6 +460,7 @@ def _build_request(
459460 headers = self ._build_headers (options )
460461 params = _merge_mappings (self .default_query , options .params )
461462 content_type = headers .get ("Content-Type" )
463+ files = options .files
462464
463465 # If the given Content-Type header is multipart/form-data then it
464466 # has to be removed so that httpx can generate the header with
@@ -472,14 +474,23 @@ def _build_request(
472474 headers .pop ("Content-Type" )
473475
474476 # As we are now sending multipart/form-data instead of application/json
475- # we need to tell httpx to use it, https://www.python-httpx.org/advanced/#multipart-file-encoding
477+ # we need to tell httpx to use it, https://www.python-httpx.org/advanced/clients/ #multipart-file-encoding
476478 if json_data :
477479 if not is_dict (json_data ):
478480 raise TypeError (
479481 f"Expected query input to be a dictionary for multipart requests but got { type (json_data )} instead."
480482 )
481483 kwargs ["data" ] = self ._serialize_multipartform (json_data )
482484
485+ # httpx determines whether or not to send a "multipart/form-data"
486+ # request based on the truthiness of the "files" argument.
487+ # This gets around that issue by generating a dict value that
488+ # evaluates to true.
489+ #
490+ # https://github.com/encode/httpx/discussions/2399#discussioncomment-3814186
491+ if not files :
492+ files = cast (HttpxRequestFiles , ForceMultipartDict ())
493+
483494 # TODO: report this error to httpx
484495 return self ._client .build_request ( # pyright: ignore[reportUnknownMemberType]
485496 headers = headers ,
@@ -492,7 +503,7 @@ def _build_request(
492503 # https://github.com/microsoft/pyright/issues/3526#event-6715453066
493504 params = self .qs .stringify (cast (Mapping [str , Any ], params )) if params else None ,
494505 json = json_data ,
495- files = options . files ,
506+ files = files ,
496507 ** kwargs ,
497508 )
498509
@@ -1863,6 +1874,11 @@ def make_request_options(
18631874 return options
18641875
18651876
1877+ class ForceMultipartDict (Dict [str , None ]):
1878+ def __bool__ (self ) -> bool :
1879+ return True
1880+
1881+
18661882class OtherPlatform :
18671883 def __init__ (self , name : str ) -> None :
18681884 self .name = name
0 commit comments