Create and download a CSV file from a Flask view

I am trying to allow the user to download a CSV file with data defined by their actions. The file doesn’t exist, it’s created dynamically. How can I do this in Flask?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Generate the data with csv.writer and stream the response. Use StringIO to write to an in-memory buffer rather than generating an intermediate file.

import csv
from datetime import datetime
from io import StringIO
from flask import Flask
from werkzeug.wrappers import Response

app = Flask(__name__)

# example data, this could come from wherever you are storing logs
log = [
    ('login', datetime(2015, 1, 10, 5, 30)),
    ('deposit', datetime(2015, 1, 10, 5, 35)),
    ('order', datetime(2015, 1, 10, 5, 50)),
    ('withdraw', datetime(2015, 1, 10, 6, 10)),
    ('logout', datetime(2015, 1, 10, 6, 15))
]

@app.route('/')
def download_log():
    def generate():
        data = StringIO()
        w = csv.writer(data)

        # write header
        w.writerow(('action', 'timestamp'))
        yield data.getvalue()
        data.seek(0)
        data.truncate(0)

        # write each log item
        for item in log:
            w.writerow((
                item[0],
                item[1].isoformat()  # format datetime as string
            ))
            yield data.getvalue()
            data.seek(0)
            data.truncate(0)

    # stream the response as the data is generated
    response = Response(generate(), mimetype='text/csv')
    # add a filename
    response.headers.set("Content-Disposition", "attachment", filename="log.csv")
    return response

If the generate function will need information from the current request, it should be decorated with stream_with_context, otherwise you will get a “working outside request context” error. Everything else remains the same.

from flask import stream_with context

@stream_with_context
def generate():
    ...

Method 2

The Flask-Excel library uses PyExcel to generate a CSV or other spreadsheet format and produces a Flask response. The docs list how to produce other formats and the full API for what data can be used.

pip install flask-excel
import flask_excel as excel

@app.route('/download', methods=['GET'])
def download_data():
    sample_data=[0, 1, 2]
    excel.init_excel(app)
    extension_type = "csv"
    filename = "test123" + "." extension_type
    d = {'colName': sample_data}
    return excel.make_response_from_dict(d, file_type=extension_type, file_name=filename)


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x