web-dev-qa-db-fra.com

Python Flask send_file StringIO fichiers vides

J'utilise python 3.5 et flask 0.10.1 et j'aime ça, mais j'ai un peu de mal avec send_file. Je souhaite finalement traiter un cadre de données pandas (à partir des données du formulaire, qui n'est pas utilisé dans cet exemple mais nécessaire à l'avenir) et l'envoyer au téléchargement en tant que csv (sans fichier temporaire). La meilleure façon d'y parvenir que j'ai vue est pour nous StringIO.

Voici le code que j'essaie d'utiliser:

@app.route('/test_download', methods = ['POST'])
def test_download():
    buffer = StringIO()
    buffer.write('Just some letters.')
    buffer.seek(0)
    return send_file(buffer, as_attachment = True,\
    attachment_filename = 'a_file.txt', mimetype = 'text/csv')

Un fichier est téléchargé avec le nom correct, mais le fichier est complètement vide.

Des idées? Des problèmes d'encodage? A-t-on répondu ailleurs? Merci!

21
Daniel Hitchcock

Le problème ici est que dans Python 3, vous devez utiliser StringIO avec csv.write et send_file nécessite BytesIO, vous devez donc faire les deux.

@app.route('/test_download')
def test_download():
    row = ['hello', 'world']
    proxy = io.StringIO()

    writer = csv.writer(proxy)
    writer.writerow(row)

    # Creating the byteIO object from the StringIO Object
    mem = io.BytesIO()
    mem.write(proxy.getvalue().encode('utf-8'))
    # seeking was necessary. Python 3.5.2, Flask 0.12.2
    mem.seek(0)
    proxy.close()

    return send_file(
        mem,
        as_attachment=True,
        attachment_filename='test.csv',
        mimetype='text/csv'
    )
33
Radu

Je suppose que vous devriez écrire des octets.

from io import BytesIO    

from flask import Flask, send_file


app = Flask(__name__)


@app.route('/test_download', methods=['POST'])
def test_download():
    # Use BytesIO instead of StringIO here.
    buffer = BytesIO()
    buffer.write(b'jJust some letters.')
    # Or you can encode it to bytes.
    # buffer.write('Just some letters.'.encode('utf-8'))
    buffer.seek(0)
    return send_file(buffer, as_attachment=True,
                     attachment_filename='a_file.txt',
                     mimetype='text/csv')


if __name__ == '__main__':
    app.run(debug=True)
14
lord63. j

si quelqu'un utilise python 2.7 avec Flask et a obtenu l'erreur sur le module StringIO en l'important. Ce message peut vous aider à résoudre votre problème.

Si vous importez String IO, vous pouvez simplement changer la syntaxe d'importation en utilisant ceci: de io import StringIO à la place de StringIO import StringIO =.

Vous pouvez également utiliser de io import BytesIO si vous utilisez une image ou une autre ressource.

Je vous remercie

0
Lamine BA