How to send zip file with send_file flask framework

Viewed 2748

I am having an issue trying to download download in-memory ZIP-FILE object using Flask send_file. my zip exists in memory and is full of text documents but when I try with this code the result I get is: it downloads like it is supposed to but it downloads an empty zip file! it's like it is copying nothing ... I have no idea how to solve this problem.

 @app.route('/downloads/', methods=['GET'])
    def download():
        from flask import send_file
        import io
        import zipfile
        import time
        FILEPATH = r"C:\Users\JD\Downloads\trydownload.zip"
        fileobj = io.BytesIO()
        with zipfile.ZipFile(fileobj, 'w') as zip_file:
            zip_info = zipfile.ZipInfo(FILEPATH)
            zip_info.date_time = time.localtime(time.time())[:6]
            zip_info.compress_type = zipfile.ZIP_DEFLATED
            with open(FILEPATH, 'rb') as fd:
                zip_file.writestr(zip_info, fd.read())
        fileobj.seek(0)
    
        return send_file(fileobj, mimetype='zip', as_attachment=True,
                         attachment_filename='%s.zip' % os.path.basename(FILEPATH))
1 Answers

I had the exact same issue with the Flask send_file method.

Details:
Flask version 2.0.1
OS: Windows 10

Solution
I figured out a workaround to this i.e. instead of the send_file method, this can be done by returning a Response object with the data. Replace the return statement in your code with the following and this should work.

@app.route('/downloads/', methods=['GET'])
    def download():
        from flask import Response # Changed line
        import io
        import zipfile
        import time
        FILEPATH = r"C:\Users\JD\Downloads\trydownload.zip"
        fileobj = io.BytesIO()
        with zipfile.ZipFile(fileobj, 'w') as zip_file:
            zip_info = zipfile.ZipInfo(FILEPATH)
            zip_info.date_time = time.localtime(time.time())[:6]
            zip_info.compress_type = zipfile.ZIP_DEFLATED
            with open(FILEPATH, 'rb') as fd:
                zip_file.writestr(zip_info, fd.read())
        fileobj.seek(0)

        # Changed line below
        return Response(fileobj.getvalue(),
                        mimetype='application/zip',
                        headers={'Content-Disposition': 'attachment;filename=your_filename.zip'})
Related