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')
BytesIO()
needs to be passed bytes data, but aZipFile()
object is not bytes-data; you actually created a file on your harddisk.You can create a
ZipFile()
in memory by usingBytesIO()
as the base:The
with
statement ensures that theZipFile()
object is properly closed when you are done adding entries, causing it to write the required trailer to the in-memory file object. Thememory_file.seek(0)
call is needed to 'rewind' the read-write position of the file object back to the start.