54

I just got started with Flask/Python. What I want to achieve is that I have a download button in my HTML and it calls the following function:

function downloadPlotCSV() {
        $.ajax({
            url: "/getPlotCSV",
            type: "post",
            success: function(data) {
                dataPlot = JSON.parse(data);
                console.log(dataPlot);
            }
        });
    }

The incomplete flask code is:

@app.route('/getPlotCSV', methods = ['POST'])
def plotCSV():
    data = open("outputs/Adjacency.csv")

The problem I am facing is that I cannot find a way to download this csv file or return it as a JSON string so I can download it using Javascript. Any idea how I can send it as JSON or maybe download it via Flask itself? What's the best way?

Tarun Dugar
  • 8,451
  • 6
  • 38
  • 68
  • As a side note, irrelevant but useful to the post, if what you really want is to get a csv which is really a json to parse it into a javascript object, `mimetype='text/json'` allows to skip the parsing part. – Jacquot Dec 10 '17 at 16:47
  • And I would change the `type` argument of the `downloadPlotCSV` method to `GET` (idem in the Python code part). – Jacquot Dec 10 '17 at 16:48

3 Answers3

80

Here is one way to download a CSV file with no Javascript:

#!/usr/bin/python

from flask import Flask, Response
app = Flask(__name__)

@app.route("/")
def hello():
    return '''
        <html><body>
        Hello. <a href="/getPlotCSV">Click me.</a>
        </body></html>
        '''

@app.route("/getPlotCSV")
def getPlotCSV():
    # with open("outputs/Adjacency.csv") as fp:
    #     csv = fp.read()
    csv = '1,2,3\n4,5,6\n'
    return Response(
        csv,
        mimetype="text/csv",
        headers={"Content-disposition":
                 "attachment; filename=myplot.csv"})


app.run(debug=True)
Robᵩ
  • 143,876
  • 16
  • 205
  • 276
  • 1
    Hi Bob I met a problem when I implemented your solution. the rows are concatenation of strings, like row_1 = string_1 + ',' + string_2 + ',' + ..... If strings have comma inside, the characters behind the comma will be moved to next column. How can I solve it? Thx. – LeonF Jun 06 '16 at 23:03
  • Excelent and simple solution, I'm search a little time for a solution like this. congrats! – Lucas Vinicius Apr 12 '19 at 13:24
  • Hi Rob, if I want to redirect to success page or error page after downloading of file. how this can be done? Can you pls explain. – vaibhavnayan Jul 09 '20 at 11:50
48

You can use flask.send_file() to send a static file:

from flask import send_file

@app.route('/getPlotCSV') # this is a job for GET, not POST
def plot_csv():
    return send_file('outputs/Adjacency.csv',
                     mimetype='text/csv',
                     attachment_filename='Adjacency.csv',
                     as_attachment=True)
kay
  • 23,543
  • 10
  • 89
  • 128
  • This works. As a side note, if the user want to get a csv which is really a json to parse it into a javascript object, `mimetype='text/json'` allows to skip the parsing part. – Jacquot Dec 10 '17 at 16:46
-3

Firstly you need to import from flask make_response, that will generate your response and create variable, something like response. Secondly, make response.content_type = "text/csv" Thirdly - return your response.

wanderlust
  • 1,556
  • 1
  • 17
  • 22