2014-12-06 10 views
13

Ho un server pallone che raccoglie dati binari per diversi file da un database e li inserisce in un oggetto "zipfile" python. Voglio inviare il file zip generato con il mio codice usando il metodo "send_file" di flask.Come inviare file zip nel framework Python Flask?

Inizialmente ero in grado di inviare file non zip con successo utilizzando BytesIO (bin) come primo argomento per send_file, ma per qualche motivo non riesco a fare la stessa cosa con il mio file zip generato. Dà l'errore:

'ZipFile' non ha l'interfaccia di buffer.

Come si invia l'oggetto file zip all'utente con Flask?

Questo è il mio codice:

@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') 
+1

** Vedere anche: ** https://stackoverflow.com/questions/26513542/flask-how-to-send-a-dinamically-generate-zipfile-to-the-client – dreftymac

risposta

22

BytesIO() deve essere passato byte di dati, ma un oggetto ZipFile() non è byte-dati; hai effettivamente creato un file sul tuo disco rigido.

È possibile creare un ZipFile() in memoria utilizzando BytesIO()come base:

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) 

La dichiarazione with assicura che l'oggetto ZipFile() sia chiuso correttamente quando si è fatto l'aggiunta di voci, inducendolo a scrivere il richiesto trailer per l'oggetto file in memoria. La chiamata è necessaria per "riavvolgere" la posizione di lettura-scrittura dell'oggetto file fino all'inizio.