Search code examples
pythonflaskzipbytesio

How to create zipFile from arrays of BytesIO - Flask


I create an array of BytesIO - each object is file (text) that save in memory. I try to compress them to zip and download. I get an error '_io.BytesIO' object is not subscriptable'. this is the code:

@app.route('/home', methods =['GET','POST'])
def home():
    form = Form()
    if form.validate_on_submit():
       new_file = create_file(form, index)
       return send_file(new_file, attachment_filename=name, as_attachment=True) 
    return render_template('ot.html', title='new', form=form)

def create_file(form, index):
    pick_up_file = create_file_base(form, index, 'start.text')
    drop_tip_file = create_file_base(form, index, 'end.text')
    working_file = create_file_base(form, index, 'workFile.text')
    files = [working_file]
    memory_file = BytesIO()
    with zipfile.ZipFile(memory_file, 'w') as fileobj:
        for curFile in files:
            data = zipfile.ZipInfo(curFile['fileName'])
            data.date_time = time.localtime(time.time())[:6]
            data.compress_type = zipfile.ZIP_DEFLATED
            fileobj.writestr(data, curFile['fileData'])
    memory_file.seek(0)
    return memory_file

def create_file_base(form, index, name):
    myData = 'abc'
    new_file = BytesIO()
    new_file.write(myData.encode('utf-8'))
    src_file = open('otFile/static/'+name, 'r')
    src_text = src_file.read()
    src_file.close()
    new_file.write(src_text.encode('utf-8'))
    new_file.seek(0)
    return new_file

Complete traceback of the error:

File "C:\Users\lirons\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 2464, in __call__
Open an interactive python shell in this framereturn self.wsgi_app(environ, start_response)
File "C:\Users\lirons\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\lirons\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\lirons\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\lirons\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\lirons\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\lirons\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\lirons\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\lirons\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\lirons\AppData\Local\Programs\Python\Python39\Lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\lirons\Documents\ot2\otFile\routes.py", line 35, in home
new_file = create_file(form, index)
File "C:\Users\lirons\Documents\ot2\otFile\routes.py", line 54, in create_file
data = zipfile.ZipInfo(curFile['fileName'])

Solution

  • I found how to solve it. Changed this:

    files = [working_file]
    memory_file = BytesIO()
    with zipfile.ZipFile(memory_file, 'w') as fileobj:
        for curFile in files:
            data = zipfile.ZipInfo(curFile['fileName'])
            data.date_time = time.localtime(time.time())[:6]
            data.compress_type = zipfile.ZIP_DEFLATED
            fileobj.writestr(data, curFile['fileData'])
    

    To:

    with zipfile.ZipFile(memory_file, 'w', compression=zipfile.ZIP_DEFLATED) as zipObject:
        zipObject.writestr("pick_up_file " , pick_up_file.read())
        zipObject.writestr("drop_tip_file" , drop_tip_file.read())
        zipObject.writestr("working_file" , working_file.read())