As far as requests is concerned, there is no difference between a zip file and any other binary blob of data.

Your server is broken here; it is cutting of the connection when you send it a zip file. That is not something requests can do anything about.

You may want to test against http://httpbin.org/ when you run into problems like these; it is a testing service built by the author of the requests library.

Another tip: you don't need to read the whole file object into memory when sending. Just pass the object itself to requests instead:

fileobj = open('/Users/.../test.zip', 'rb')
r = requests.post(url, auth=HTTPDigestAuth('dev', 'dev'), data = {"mysubmit":"Go"}, files={"archive": ("test.zip", fileobj)})

Demo against httpbin.org:

>>> import requests
>>> fileobj = open('/tmp/test.zip', 'rb')
>>> r = requests.post('http://httpbin.org/post', data={"mysubmit":"Go"}, files={"archive": ("test.zip", fileobj)})
>>> r
<Response [200]>
>>> r.json()
{u'origin': u'217.32.203.188', u'files': {u'archive': u'data:application/zip;base64,<long base64 body omitted>'}, u'form': {u'mysubmit': u'Go'}, u'url': u'http://httpbin.org/post', u'args': {}, u'headers': {u'Content-Length': u'57008', u'Accept-Encoding': u'gzip, deflate, compress', u'Connection': u'close', u'Accept': u'*/*', u'User-Agent': u'python-requests/1.2.3 CPython/2.7.5 Darwin/12.4.0', u'Host': u'httpbin.org', u'Content-Type': u'multipart/form-data; boundary=9aec1d03a1794177a38b48416dd4c811'}, u'json': None, u'data': u''}
Answer from Martijn Pieters on Stack Overflow
🌐
Reddit
reddit.com › r/learnpython › uploading zip file with requests adds content to the archive
r/learnpython on Reddit: Uploading zip file with requests adds content to the archive
March 30, 2017 -

I all,

I'm having a headache trying to upload a zipfile to my pydio webserver using this api endpoint
The zipfile is generated by my python script and can be extracted on the source machine.
The source machine is an old Windows XP running the latest release of python 2.7.

When uploading the zip file, the file on the destination server contains the following text at the top :

--9efb552ea5024e6eacabbf15ec02376a
Content-Disposition: form-data; name="archive"; filename="b1ch102.zip"
Content-Type: application/zip

This text is not present on the source file. Of course, the zip file can't be extracted once modified like this.
Here is the code i'm running :

with open(zipname, 'rb') as f:  
    response = requests.put('https://myserver.com/api/my-files/upload/',  
                                      auth=(user, pwd),   
                                      files={'archive': (zipname, f, 'application/zip')},  
                                      headers={'X-File-Name' : zipname})  

I'm trying for 2 days and can't figure out how to make this working.
Any help would be appreciated.

edit: formating

Top answer
1 of 2
16

As far as requests is concerned, there is no difference between a zip file and any other binary blob of data.

Your server is broken here; it is cutting of the connection when you send it a zip file. That is not something requests can do anything about.

You may want to test against http://httpbin.org/ when you run into problems like these; it is a testing service built by the author of the requests library.

Another tip: you don't need to read the whole file object into memory when sending. Just pass the object itself to requests instead:

fileobj = open('/Users/.../test.zip', 'rb')
r = requests.post(url, auth=HTTPDigestAuth('dev', 'dev'), data = {"mysubmit":"Go"}, files={"archive": ("test.zip", fileobj)})

Demo against httpbin.org:

>>> import requests
>>> fileobj = open('/tmp/test.zip', 'rb')
>>> r = requests.post('http://httpbin.org/post', data={"mysubmit":"Go"}, files={"archive": ("test.zip", fileobj)})
>>> r
<Response [200]>
>>> r.json()
{u'origin': u'217.32.203.188', u'files': {u'archive': u'data:application/zip;base64,<long base64 body omitted>'}, u'form': {u'mysubmit': u'Go'}, u'url': u'http://httpbin.org/post', u'args': {}, u'headers': {u'Content-Length': u'57008', u'Accept-Encoding': u'gzip, deflate, compress', u'Connection': u'close', u'Accept': u'*/*', u'User-Agent': u'python-requests/1.2.3 CPython/2.7.5 Darwin/12.4.0', u'Host': u'httpbin.org', u'Content-Type': u'multipart/form-data; boundary=9aec1d03a1794177a38b48416dd4c811'}, u'json': None, u'data': u''}
2 of 2
1

If you are facing any errors while uploading the zip: This problem could be caused by 'Content-Type': 'multipart/form-data' setting on the header. The problem can be solved by deleting this setting, as in this example:

header = {'Content-Type': 'multipart/form-data', 'Authorization': 'Bearer {}'.format(bearerToken)}

change it to:

header = {'Authorization': 'Bearer {}'.format(bearerToken)}

Code which worked for me:

 header = {"INFA-SESSION-ID":self._v3SessionID}
 files = {'package': ("response.zip", open("C:\Users\myUser\Downloads\response.zip", 'rb'),'application/zip')}
 response = re.post(url, headers=header, files=files)
Discussions

PUT (requests.put) specifying the source file location for zip file error 10054
C:\svn\libraries\cpp>python req_put.py default.zip Traceback (most recent call last): File "req_put.py", line 102, in resp = requests.put(uri, headers=headers, data=data) # data=data , params=payload) File "C:\Python27\lib\site-packages\requests\api.py", line 124, in put return ... More on github.com
🌐 github.com
5
January 31, 2017
Using request package: Requested zipfiles are not opening and scripts are getting downloaded as HTML
Hi guys! I am using the requests package to download zip files and scripts from a URL with authentication. I’m using the following code. import requests user, password = 'ID', 'Password' for year in range(1… More on discuss.python.org
🌐 discuss.python.org
0
0
March 21, 2022
POST zip file to ArcGIS Server using an API (Python) - Geographic Information Systems Stack Exchange
How can I this script, so that I can upload a single item (in this case a zip file) onto ArcGIS Enterprise Server? #import modules import requests import os from flask import Flask, request, redirect, render_template, flash from werkzeug.utils import secure_filename try: # bypass SSL certificate ... More on gis.stackexchange.com
🌐 gis.stackexchange.com
April 20, 2022
python - Download Returned Zip file from URL - Stack Overflow
If I have a URL that, when submitted ... this zip file in Python? ... I tried section Downloading a binary file and writing it to disk of this page which worked as a chram. ... For anyone else looking for a solution with only the standard library stuff, then check out this answer - stackoverflow.com/a/31706921/8604951 and save yourself a couple of minutes of reading and scrolling through the rest of the answers which uses requests (which btw ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
ProxiesAPI
proxiesapi.com › articles › uploading-zip-files-via-http-post-with-python-requests
Uploading Zip Files via HTTP POST with Python Requests | ProxiesAPI
import requests import io import zipfile # Create in-memory zip file data = io.BytesIO() with zipfile.ZipFile(data, mode="w") as z: z.write("file1.txt") z.write("folder/file2.txt") data.seek(0)
🌐
GitHub
github.com › psf › requests › issues › 3842
PUT (requests.put) specifying the source file location for zip file error 10054 · Issue #3842 · psf/requests
January 31, 2017 - C:\svn\libraries\cpp>python req_put.py default.zip Traceback (most recent call last): File "req_put.py", line 102, in <module> resp = requests.put(uri, headers=headers, data=data) # data=data , params=payload) File "C:\Python27\lib\site-pac...
Author   Twoflower2
🌐
Python Forum
python-forum.io › thread-10152.html
Posting zip file on HTTP network using Python2.7
Hi, We need to post a zip file on HTTP using Python 2.7. We are using the below code which throwing exception: post_data = open(zipPath,u'rb') request = urllib2.Request(url,post_data.read().encode(u'utf-8')) request.add_header(u'Content-Type', u'a...
🌐
Dynatrace Community
community.dynatrace.com › t5 › Extensions › Uploading-extention-zip-through-Python-API-script › m-p › 172363
Solved: Uploading extention.zip through Python API script - Dynatrace Community
May 18, 2023 - import requests import json # ... # Other blocks of code here that works fine # ... for tenant_id, token in zip(tenant_id_list, token_list): url = "https://dtmanaged.com/e/" + tenant_id + "/api/config/v1/extensions?overrideAlerts=false" payload = {'file': '@custom.python.ssl_cert_check.zip;type=application/x-zip-compressed'} files = {'file': open('custom.python.ssl_cert_check.zip', 'rb')} headers = { 'accept': 'application/json; charset=utf-8', 'Authorization': 'Api-Token ' + token, 'Content-Type': 'multipart/form-data' } response = requests.request("POST", url, headers=headers, data=payload, files=files) print(response.text) print(response.status_code)
🌐
Stack Abuse
stackabuse.com › how-to-upload-files-with-pythons-requests-library
How to Upload Files with Python's requests Library
September 19, 2021 - In this tutorial, we will take a look at how to upload files using Python's requests library. The article will start by covering the requests library and the post() function signature. Next, we will cover how to upload a single file using the requests package. Last but not least, we upload multiple files in one request.
Find elsewhere
🌐
Python.org
discuss.python.org › python help
Using request package: Requested zipfiles are not opening and scripts are getting downloaded as HTML - Python Help - Discussions on Python.org
March 21, 2022 - Hi guys! I am using the requests package to download zip files and scripts from a URL with authentication. I’m using the following code. import requests user, password = 'ID', 'Password' for year in range(1…
🌐
Dynatrace Community
community.dynatrace.com › t5 › Extensions › Uploading-extention-zip-through-Python-API-script › m-p › 172368
Solved: Re: Uploading extention.zip through Python API script - Dynatrace Community
May 18, 2023 - import requests import json # ... # Other blocks of code here that works fine # ... for tenant_id, token in zip(tenant_id_list, token_list): url = "https://dtmanaged.com/e/" + tenant_id + "/api/config/v1/extensions?overrideAlerts=false" payload = {'file': '@custom.python.ssl_cert_check.zip;type=application/x-zip-compressed'} files = {'file': open('custom.python.ssl_cert_check.zip', 'rb')} headers = { 'accept': 'application/json; charset=utf-8', 'Authorization': 'Api-Token ' + token, 'Content-Type': 'multipart/form-data' } response = requests.request("POST", url, headers=headers, data=payload, files=files) print(response.text) print(response.status_code)
🌐
Stack Exchange
gis.stackexchange.com › questions › 429371 › post-zip-file-to-arcgis-server-using-an-api-python
POST zip file to ArcGIS Server using an API (Python) - Geographic Information Systems Stack Exchange
April 20, 2022 - How can I this script, so that I can upload a single item (in this case a zip file) onto ArcGIS Enterprise Server? #import modules import requests import os from flask import Flask, request, redirect, render_template, flash from werkzeug.utils import secure_filename try: # bypass SSL certificate requests.post(url='https://domain/server/rest/services/', data={'bar':'baz'}, verify=False) try: #set local variables service = 'https://domain/server/rest/services/' #upload folder contains one zip file that has a shapefile UPLOAD_FOLDER = r'E:\API_creation\upload' ALLOWED_EXTENSIONS = {'txt', 'pdf',
🌐
TutorialsPoint
tutorialspoint.com › requests › requests_file_upload.htm
File Upload with Requests in Python
import requests myurl = 'https://httpbin.org/post' files = {'file': ('test1.txt', 'Welcome to TutorialsPoint')} getdata = requests.post(myurl, files=files) print(getdata.text) E:\prequests>python makeRequest.py { "args": {}, "data": "", "files": { "file": "Welcome to TutorialsPoint" }, "form": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Content-Length": "170", "Content-Type": "multipart/form-data; boundary=f2837238286fe40e32080aa7e172be4f", "Host": "httpbin.org", "User-Agent": "python-requests/2.22.0" }, "json": null, "origin": "117.223.63.135, 117.223.63.135", "url": "https://httpbin.org/post" }
Top answer
1 of 9
320

As far as I can tell, the proper way to do this in Python 2 is:

import requests, zipfile, StringIO
r = requests.get(zip_file_url, stream=True)
z = zipfile.ZipFile(StringIO.StringIO(r.content))
z.extractall()

of course you'd want to check that the GET was successful with r.ok.

For python 3+, sub the StringIO module with the io module and use BytesIO instead of StringIO: Here are release notes that mention this change.

import requests, zipfile, io
r = requests.get(zip_file_url)
z = zipfile.ZipFile(io.BytesIO(r.content))
z.extractall("/path/to/destination_directory")
2 of 9
85

Most people recommend using requests if it is available, and the requests documentation recommends this for downloading and saving raw data from a url:

import requests 

def download_url(url, save_path, chunk_size=128):
    r = requests.get(url, stream=True)
    with open(save_path, 'wb') as fd:
        for chunk in r.iter_content(chunk_size=chunk_size):
            fd.write(chunk)

Since the answer asks about downloading and saving the zip file, I haven't gone into details regarding reading the zip file. See one of the many answers below for possibilities.

If for some reason you don't have access to requests, you can use urllib.request instead. It may not be quite as robust as the above.

import urllib.request

def download_url(url, save_path):
    with urllib.request.urlopen(url) as dl_file:
        with open(save_path, 'wb') as out_file:
            out_file.write(dl_file.read())

Finally, if you are using Python 2 still, you can use urllib2.urlopen.

from contextlib import closing

def download_url(url, save_path):
    with closing(urllib2.urlopen(url)) as dl_file:
        with open(save_path, 'wb') as out_file:
            out_file.write(dl_file.read())
🌐
Compciv
compciv.org › practicum › shakefiles › b-downloading-the-shakespeare-zip
Downloading and saving the Shakespeare zip with requests | Computational Methods in the Civic Sphere at Stanford University
It's just easier to use Python's helper functions to deal with it, in the long run. Revisiting our download-and-save code from the previous example, except using the join() method, and saving it to the tempdata directory (assuming that it's been created): import requests import os zipurl = 'http://stash.compciv.org/scrapespeare/matty.shakespeare.tar.gz' resp = requests.get(zipurl) # assuming the subdirectory tempdata has been created: zname = os.path.join('tempdata', "matty.shakespeare.tar.gz") zfile = open(zname, 'wb') zfile.write(resp.content) zfile.close()
🌐
Java Code Geeks
examples.javacodegeeks.com › home › web development › python
Upload Files with Python's Requests Library - Examples Java Code Geeks
June 2, 2021 - Add the following code to the python script. The script consists of a dictionary object to hold multiple names and files. Once the file list is ready we will send the HTTP POST request to a free bin service that can simulate the post-operation and return an HTTP response. The dummy files (named – file1.txt and file2.txt) used in this script can be download from the Downloads section. ... # Upload file using python requests library # import module import requests # url - http://httpbin.org/ # making use of a free httpbin service post_url = 'http://httpbin.org/post' # method to upload files de
🌐
FastAPI
fastapi.tiangolo.com › tutorial › request-files
Request Files - FastAPI
You can declare multiple File and Form parameters in a path operation, but you can't also declare Body fields that you expect to receive as JSON, as the request will have the body encoded using multipart/form-data instead of application/json. This is not a limitation of FastAPI, it's part of the HTTP protocol. You can make a file optional by using standard type annotations and setting a default value of None: ... from typing import Annotated from fastapi import FastAPI, File, UploadFile app = FastAPI() @app.post("/files/") async def create_file(file: Annotated[bytes | None, File()] = None): if not file: return {"message": "No file sent"} else: return {"file_size": len(file)} @app.post("/uploadfile/") async def create_upload_file(file: UploadFile | None = None): if not file: return {"message": "No upload file sent"} else: return {"filename": file.filename}
🌐
GeeksforGeeks
geeksforgeeks.org › python › how-to-upload-files-using-python-requests-library
How to Upload Files Using Python Requests Library - GeeksforGeeks
July 23, 2025 - 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.
🌐
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
Save yoavram/4351498 to your computer and use it in GitHub Desktop. ... 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.
🌐
Stack Overflow
stackoverflow.com › questions › 34006080 › uploading-a-zip-file-in-python-flask-without-form
Uploading a zip file in python flask without form - Stack Overflow
I'm trying to upload a zip file to my server using python flask request and then unzip it using zipfile module. Here is my code: @app.route('/uoload', methods=['POST']) def upload (): data =