Andrew Venson
Andrew Venson

Reputation: 213

Download CSV File in Flask Best Practice

Right now I have a flask app in which part of the functionality allows me to select a date range and see data from a sql database from that selected date range. I then can click a button and it exports this to a csv file which is just saved in the flask project directory. I want the user to be able to download this csv file. I want to know what the best practice for a user to download a dynamic csv file. Should I send_file() and then delete the file after user has downloaded since this data shouldn't be saved and the user won't be using that file again. Should the file be saved to the database and then deleted out of the db? Or can I just keep it within the flask directory? Please provide insight if possible, thank you so much.

Upvotes: 1

Views: 7691

Answers (2)

David Mendes
David Mendes

Reputation: 367

Based on @xxbinxx's answer, used with pandas

from io import StringIO
import csv
from flask import make_response

@app.route('/download')
def download_csv(self, df: pd.DataFrame):
        si = StringIO()
        cw = csv.writer(si)
        cw.writerows(df.columns.tolist())
        cw.writerows(df.values.tolist())
        output = make_response(si.getvalue())
        output.headers["Content-Disposition"] = "attachment; filename=export.csv"
        output.headers["Content-type"] = "text/csv"
        return output

Upvotes: 0

xxbinxx
xxbinxx

Reputation: 1553

@brunns pointed it in very right direction.

You don't have to save the file in your database or in your file structure or anywhere. It will get created in memory on user request.

I've done this with django for pdf and for csv files it'll work in the same way with flask too. Basics are all same.

for python3 use io.StringIO, for python2 use StringIO

from io import StringIO
import csv
from flask import make_response

@app.route('/download')
def post(self):
    si = StringIO.StringIO()
    cw = csv.writer(si)
    cw.writerows(csvList)
    output = make_response(si.getvalue())
    output.headers["Content-Disposition"] = "attachment; filename=export.csv"
    output.headers["Content-type"] = "text/csv"
    return output

Courtesy: vectorfrog

Upvotes: 4

Related Questions