Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send zip files in the python Flask framework?

I have a flask server that grabs binary data for several different files from a database and puts them into a python 'zipfile' object. I want to send the generated zip file with my code using flask's "send_file" method.

I was originally able to send non-zip files successfully by using the BytesIO(bin) as the first argument to send_file, but for some reason I can't do the same thing with my generated zip file. It gives the error:

'ZipFile' does not have the buffer interface.

How do I send this zip file object to the user with Flask?

This is my code:

@app.route("/getcaps",methods=['GET','POST']) def downloadFiles():     if request.method == 'POST':         mongo = MongoDAO('localhost',27017)         identifier = request.form['CapsuleName']         password = request.form['CapsulePassword']         result = mongo.getCapsuleByIdentifier(identifier,password)         zf = zipfile.ZipFile('capsule.zip','w')         files = result['files']         for individualFile in files:             data = zipfile.ZipInfo(individualFile['fileName'])             data.date_time = time.localtime(time.time())[:6]             data.compress_type = zipfile.ZIP_DEFLATED             zf.writestr(data,individualFile['fileData'])         return send_file(BytesIO(zf), attachment_filename='capsule.zip', as_attachment=True)     return render_template('download.html') 
like image 692
idungotnosn Avatar asked Dec 06 '14 21:12

idungotnosn


People also ask

How do I send files using flask?

Python for web development using Flask Handling file upload in Flask is very easy. It needs an HTML form with its enctype attribute set to 'multipart/form-data', posting the file to a URL. The URL handler fetches file from request. files[] object and saves it to the desired location.

Can you read a zipped file Python?

Yes you can. If you want to read a zipped or a tar. gz file into pandas dataframe, the read_csv methods includes this particular implementation. For on-the-fly decompression of on-disk data.


1 Answers

BytesIO() needs to be passed bytes data, but a ZipFile() object is not bytes-data; you actually created a file on your harddisk.

You can create a ZipFile() in memory by using BytesIO() as the base:

memory_file = BytesIO() with zipfile.ZipFile(memory_file, 'w') as zf:     files = result['files']     for individualFile in files:         data = zipfile.ZipInfo(individualFile['fileName'])         data.date_time = time.localtime(time.time())[:6]         data.compress_type = zipfile.ZIP_DEFLATED         zf.writestr(data, individualFile['fileData']) memory_file.seek(0) return send_file(memory_file, attachment_filename='capsule.zip', as_attachment=True) 

The with statement ensures that the ZipFile() object is properly closed when you are done adding entries, causing it to write the required trailer to the in-memory file object. The memory_file.seek(0) call is needed to 'rewind' the read-write position of the file object back to the start.

like image 96
Martijn Pieters Avatar answered Sep 23 '22 19:09

Martijn Pieters