Подтвердить что ты не робот

Как отправить zip файлы в фреймворк python?

У меня есть фляжный сервер, который захватывает двоичные данные для нескольких разных файлов из базы данных и помещает их в объект zipfile python. Я хочу отправить сгенерированный zip файл с моим кодом, используя метод "send_file" в колбе.

Я изначально мог отправлять файлы без zip, используя BytesIO (bin) в качестве первого аргумента send_file, но по какой-то причине я не могу сделать то же самое с моим сгенерированным zip файлом. Он дает ошибку:

'ZipFile' не имеет интерфейса буфера.

Как отправить этот объект zip файла пользователю с помощью Flask?

Это мой код:

@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')
4b9b3361

Ответ 1

BytesIO() необходимо передать данные байтов, но объект ZipFile() не является байтовыми данными; вы на самом деле создали файл на вашем жестком диске.

Вы можете создать ZipFile() в памяти, используя BytesIO() в качестве базы:

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)

Оператор with гарантирует, что объект ZipFile() будет правильно закрыт, когда вы закончите добавление записей, заставив его записать требуемый трейлер в файл файл в памяти. Вызов memory_file.seek(0) необходим для "перемотки" позиции чтения и записи объекта файла обратно в начало.

Ответ 2

Также не забудьте закрыть zipfile: zf.close() перед его отправкой.