From a0f2006aa51918028b07c0e4bffb142081059496 Mon Sep 17 00:00:00 2001 From: Raj Kumar Date: Sun, 2 Mar 2025 21:38:20 -0800 Subject: [PATCH 1/2] Support multiple @Part arguments with the same name --- examples/file1.txt | 0 examples/file_upload.py | 20 ++++++++++++++++++++ uplink/arguments.py | 11 ++++++++--- 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 examples/file1.txt create mode 100644 examples/file_upload.py diff --git a/examples/file1.txt b/examples/file1.txt new file mode 100644 index 00000000..e69de29b diff --git a/examples/file_upload.py b/examples/file_upload.py new file mode 100644 index 00000000..0f3fb3e2 --- /dev/null +++ b/examples/file_upload.py @@ -0,0 +1,20 @@ +import uplink + + +class HttpBin(uplink.Consumer): + @uplink.multipart + @uplink.post("post") + def post(self, attachments: uplink.PartMap): + pass + + +client = HttpBin(base_url="https://httpbin.org/") + + +print( + client.post( + attachments={ + "file1.txt": [open("file1.txt", "rb"), open("file1.txt", "rb")] + } + ) +) diff --git a/uplink/arguments.py b/uplink/arguments.py index b38e6b39..c86a26d2 100644 --- a/uplink/arguments.py +++ b/uplink/arguments.py @@ -604,7 +604,9 @@ def converter_key(self): def _modify_request(self, request_builder, value): """Updates the request body with the form part.""" - request_builder.info["files"][self.name] = value + if "files" not in request_builder.info: + request_builder.info["files"] = [] + request_builder.info["files"].append((self.name, value)) class PartMap(TypedArgument): @@ -628,9 +630,12 @@ def converter_key(self): """Converts each part to the request body.""" return keys.Map(keys.CONVERT_TO_REQUEST_BODY) - def _modify_request(self, request_builder, value): + def _modify_request(self, request_builder, filemap): """Updates request body to with the form parts.""" - request_builder.info["files"].update(value) + if "files" not in request_builder.info: + request_builder.info["files"] = [] + for key in filemap: + request_builder.info["files"].append((key, filemap[key])) class Body(TypedArgument): From 5bdd6ce1def84bab96c9c70525e752f4bbbd6a57 Mon Sep 17 00:00:00 2001 From: Raj Kumar Date: Sun, 2 Mar 2025 21:38:20 -0800 Subject: [PATCH 2/2] Support multiple @Part arguments with the same name --- examples/file1.txt | 0 examples/file_upload.py | 20 ++++++++++++++++++++ uplink/arguments.py | 11 ++++++++--- 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 examples/file1.txt create mode 100644 examples/file_upload.py diff --git a/examples/file1.txt b/examples/file1.txt new file mode 100644 index 00000000..e69de29b diff --git a/examples/file_upload.py b/examples/file_upload.py new file mode 100644 index 00000000..0f3fb3e2 --- /dev/null +++ b/examples/file_upload.py @@ -0,0 +1,20 @@ +import uplink + + +class HttpBin(uplink.Consumer): + @uplink.multipart + @uplink.post("post") + def post(self, attachments: uplink.PartMap): + pass + + +client = HttpBin(base_url="https://httpbin.org/") + + +print( + client.post( + attachments={ + "file1.txt": [open("file1.txt", "rb"), open("file1.txt", "rb")] + } + ) +) diff --git a/uplink/arguments.py b/uplink/arguments.py index b38e6b39..c86a26d2 100644 --- a/uplink/arguments.py +++ b/uplink/arguments.py @@ -604,7 +604,9 @@ def converter_key(self): def _modify_request(self, request_builder, value): """Updates the request body with the form part.""" - request_builder.info["files"][self.name] = value + if "files" not in request_builder.info: + request_builder.info["files"] = [] + request_builder.info["files"].append((self.name, value)) class PartMap(TypedArgument): @@ -628,9 +630,12 @@ def converter_key(self): """Converts each part to the request body.""" return keys.Map(keys.CONVERT_TO_REQUEST_BODY) - def _modify_request(self, request_builder, value): + def _modify_request(self, request_builder, filemap): """Updates request body to with the form parts.""" - request_builder.info["files"].update(value) + if "files" not in request_builder.info: + request_builder.info["files"] = [] + for key in filemap: + request_builder.info["files"].append((key, filemap[key])) class Body(TypedArgument):