web-dev-qa-db-ja.com

python FlaskフレームワークでZipファイルを送信する方法は?

私はflaskサーバーがあり、データベースからいくつかの異なるファイルのバイナリデータを取得し、それらをpython 'zipfile'オブジェクトに入れます。送信したいフラスコの「send_file」メソッドを使用して、私のコードでZipファイルを生成しました。

最初はBytesIO(bin)をsend_fileの最初の引数として使用することで、Zip以外のファイルを正常に送信できましたが、何らかの理由で、生成された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')
23
idungotnosn

BytesIO()を渡す必要がありますbytes dataですが、ZipFile()オブジェクトはbytes-dataではありません。実際にファイルを作成しましたハードディスク上

メモリ内に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)呼び出しは、ファイルオブジェクトの読み取り/書き込み位置を先頭に「巻き戻す」ために必要です。

39
Martijn Pieters