it may because you use multipart/form to upload file.try use data like code below

data = open(localFilePath, 'rb').read()
headers = {
    "Content-Type":"application/binary",
}
upload = requests.put(uploadUrl,data=data,headers=headers)
Answer from shutup on Stack Overflow
🌐
GitHub
gist.github.com › yoavram › 4351498
Example of uploading binary files programmatically in python, including both client and server code. Client implemented with the requests library and the server is implemented with the flask library. · GitHub
Example of uploading binary files programmatically in python, including both client and server code. Client implemented with the requests library and the server is implemented with the flask libra...
Discussions

How do I upload binary files using Python?
▶ System Information on the Upload documentation here: Upload - Strapi Developer Docs The docs give a code snippet for uploading a binary file in JavaScript. How do I do it in Python? This is ... More on forum.strapi.io
🌐 forum.strapi.io
0
1
January 15, 2022
rest - Python POST binary data - Stack Overflow
I am writing some code to interface with redmine and I need to upload some files as part of the process, but I am not sure how to do a POST request from python containing a binary file. I am tryin... More on stackoverflow.com
🌐 stackoverflow.com
python ftplib upload binary file - Stack Overflow
I use python ftplib to upload binary file to remote ftp server, but it always transfers less than its actually size. ps: local env is windows, remote server is linux. I use: 'ftp.storbinary('S... More on stackoverflow.com
🌐 stackoverflow.com
November 29, 2018
How to upload binary file with ftplib in Python? - Stack Overflow
My python2 script uploads files nicely using this method but python3 is presenting problems and I'm stuck as to where to go next (googling hasn't helped). from ftplib import FTP ftp = FTP(ftp_host, More on stackoverflow.com
🌐 stackoverflow.com
🌐
GitHub
github.com › psf › requests › issues › 1266
How to upload binary file using PUT? · Issue #1266 · psf/requests
March 26, 2013 - def filegen(fo): yield fo.read(CHUNK_SIZE) def main(): session = requests.Session() session.auth = HTTPKerberosAuth() upload_headers = {'X-Codesigner-security-token': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'} with open(pathname, 'rb') as infile: response = session.put(upload_url, headers=upload_headers, data=filegen(infile)) ... Request headers: { 'Accept-Encoding': 'gzip, deflate, compress', 'X-Codesigner-security-token': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'Accept': '*/*', 'User-Agent': 'python-requests/1.1.0 CPython/2.7.1 Windows/7', 'Transfer-Encoding': 'chunked', 'Authorization': 'Negotiate <bl
Author   dabono
🌐
Medium
medium.com › codex › chunked-uploads-with-binary-files-in-python-f0c48e373a91
Chunked Uploads with Binary Files in Python | by Erikka Innes | CodeX | Medium
March 3, 2021 - My goal today, is to go over some of the sticking points you might encounter when trying to upload a large file in chunks that isn’t text. If you have something besides a text file, the first sticking point you’ll encounter is accidentally treating your file like a text file. If you find a tutorial that’s accurate for a text file, it will often work for a binary file as long as you include a few tweaks that help Python recognize the difference in your file.
🌐
Strapi Community
forum.strapi.io › questions and answers
How do I upload binary files using Python? - Questions and Answers - Strapi Community Forum
January 15, 2022 - ▶ System Information on the Upload documentation here: Upload - Strapi Developer Docs The docs give a code snippet for uploading a binary file in JavaScript. How do I do it in Python? This is ...
Top answer
1 of 4
104

Basically what you do is correct. Looking at redmine docs you linked to, it seems that suffix after the dot in the url denotes type of posted data (.json for JSON, .xml for XML), which agrees with the response you get - Processing by AttachmentsController#upload as XML. I guess maybe there's a bug in docs and to post binary data you should try using http://redmine/uploads url instead of http://redmine/uploads.xml.

Btw, I highly recommend very good and very popular Requests library for http in Python. It's much better than what's in the standard lib (urllib2). It supports authentication as well but I skipped it for brevity here.

import requests
with open('./x.png', 'rb') as f:
    data = f.read()
res = requests.post(url='http://httpbin.org/post',
                    data=data,
                    headers={'Content-Type': 'application/octet-stream'})

# let's check if what we sent is what we intended to send...
import json
import base64

assert base64.b64decode(res.json()['data'][len('data:application/octet-stream;base64,'):]) == data

UPDATE

To find out why this works with Requests but not with urllib2 we have to examine the difference in what's being sent. To see this I'm sending traffic to http proxy (Fiddler) running on port 8888:

Using Requests

import requests

data = 'test data'
res = requests.post(url='http://localhost:8888',
                    data=data,
                    headers={'Content-Type': 'application/octet-stream'})

we see

POST http://localhost:8888/ HTTP/1.1
Host: localhost:8888
Content-Length: 9
Content-Type: application/octet-stream
Accept-Encoding: gzip, deflate, compress
Accept: */*
User-Agent: python-requests/1.0.4 CPython/2.7.3 Windows/Vista

test data

and using urllib2

import urllib2

data = 'test data'    
req = urllib2.Request('http://localhost:8888', data)
req.add_header('Content-Length', '%d' % len(data))
req.add_header('Content-Type', 'application/octet-stream')
res = urllib2.urlopen(req)

we get

POST http://localhost:8888/ HTTP/1.1
Accept-Encoding: identity
Content-Length: 9
Host: localhost:8888
Content-Type: application/octet-stream
Connection: close
User-Agent: Python-urllib/2.7

test data

I don't see any differences which would warrant different behavior you observe. Having said that it's not uncommon for http servers to inspect User-Agent header and vary behavior based on its value. Try to change headers sent by Requests one by one making them the same as those being sent by urllib2 and see when it stops working.

2 of 4
4

This has nothing to do with a malformed upload. The HTTP error clearly specifies 401 unauthorized, and tells you the CSRF token is invalid. Try sending a valid CSRF token with the upload.

More about csrf tokens here:

What is a CSRF token ? What is its importance and how does it work?

🌐
Stack Abuse
stackabuse.com › how-to-upload-files-with-pythons-requests-library
How to Upload Files with Python's requests Library
September 19, 2021 - The path of the file can be an absolute path or a relative path to where the script is being run. If you're uploading a file in the same directory, you can just use the file's name. The second argument, mode, will take the "read binary" value which is represented by rb.
Find elsewhere
🌐
FastAPI
fastapi.tiangolo.com › tutorial › request-files
Request Files - FastAPI
This means that it will work well for large files like images, videos, large binaries, etc. without consuming all the memory. You can get metadata from the uploaded file. It has a file-like async interface. It exposes an actual Python SpooledTemporaryFile object that you can pass directly to ...
🌐
ActiveState
code.activestate.com › recipes › 576422-python-http-post-binary-file-upload-with-pycurl
Python HTTP POST binary file upload with pycurl « Python recipes « ActiveState Code
August 14, 2008 - I didn't liked/tried solution explained ... http://curl.haxx.se/libcurl/) because it is std. lib for php, and uploading the file is very simple (just add @<path-to-file> to post variable value)....
🌐
ProxiesAPI
proxiesapi.com › articles › uploading-files-in-python-requests-a-guide
Uploading Files in Python Requests: A Guide | ProxiesAPI
Uploading a file is just a matter of attaching the binary data as well as metadata to identify the file contents.
🌐
CodeRivers
coderivers.org › blog › python-write-binary-to-file
Python Write Binary to File: A Comprehensive Guide - CodeRivers
April 6, 2025 - This code opens the filename.bin file in binary append mode and writes the data_to_append to the end of the file. The with statement in Python provides a more concise and safer way to work with files.
🌐
Intelligent-d2
intelligent-d2.com › python › use-python-requests-library-post-multipart-encoded-file
Use the python Requests library to post Multipart-Encoded file | Intelligent-d2
October 20, 2017 - 2.) On line 4 we are opening a file(test.txt) in binary mode, which is recommended by the Requests docs because opening it in text mode may cause an error because Requests attempts to provide a Content-Length header for you, which is in bytes.
🌐
GeeksforGeeks
geeksforgeeks.org › how-to-upload-files-using-python-requests-library
How to Upload Files Using Python Requests Library - GeeksforGeeks
March 27, 2024 - Before diving into file upload examples, let's ensure you have the requests library installed. If not, you can install it using pip: ... In this example, below code uses the Python requests library to upload a file (file.txt) to the specified URL (https://httpbin.org/post) using a POST request with the files parameter, and then prints the response text.
🌐
OutSystems
outsystems.com › forums › discussion › 39830 › rest-put-binary-content
REST Put binary content | OutSystems
September 17, 2018 - I need to call a put operation of an API in order to upload a binary file · Using js this should be implemented as below