1

I am trying to send to my flask app json data and having it return a CSV file. My ajax request is sending JSON data to the view via POST request and then the view is supposed to return back a csv file. However, it fails to return the csv file in the browser as a download. I'm not sure how to make it work or if its even possible. Thanks!

// AJAX - Send data over to python and return csv 
$("#export").click(
    function(){
        $.ajax({
            url: "/dbCSV",
            type: "POST",
            contentType: 'application/json;charset=UTF-8',
            dataType:"json",
            data: JSON.stringify(datam)
        });
    
        event.preventDefault();
    }
);
@analyzers.route("/dbCSV", methods=["GET","POST"])
def dbCSV():
    if request.method=="POST":
        data = pd.DataFrame(request.get_json())
        resp = make_response(data.to_csv())
        resp.headers["Content-Disposition"] = "attachment; filename=export.csv"
        resp.headers["Content-Type"] = "text/csv"
        return resp 
    return jsonify({"msg":"Could not generate CSV File"})
Raider32
  • 11
  • 1
  • 3

3 Answers3

1

I'd recommend using send_file(...) with a BytesIO (file stream) object:

from io import BytesIO

from flask import send_file
...

response_stream = BytesIO(data.to_csv().encode())
return send_file(
    response_stream,
    mimetype="text/csv",
    attachment_filename="export.csv",
)

Keep in mind that you will not be able to open the download prompt when sending a POST request using AJAX. Instead, you will simply receive the file as an AJAX response. To solve this issue, you will have to take a look at this question:

download file using an ajax request

Maybe your code was already working and this was your problem – I can not tell from looking at it.

Jonas
  • 725
  • 5
  • 23
  • Of course this would have to be added to the function, otherwise the `return` statement would make no sense here ;) – Jonas Jul 21 '20 at 17:28
  • I've tried this and its not letting me download the file still. I even added `window.location="/dbCSV";` to the success portion of the ajax call and its still not working. – Raider32 Jul 21 '20 at 17:39
  • Can you debug that you are actually sending the response (e.g. by adding some `print`'s along the function)? Also, try adding a GET endpoint that does not require any parameters and just returns the CSV of e.g. `pd.DataFrame(numpy.array([1, 2]))`, then you can test it using your browser by navigating to the corresponding URL. – Jonas Jul 21 '20 at 17:46
  • I tried adding a bunch of print statements around the dataframe and the send_file piece and that part where the JSON data gets converted to a dataframe and then converted to a CSV file is working just fine. For whatever reason I still am not seeing the csv download. I also try using an `` tag around the button IE `` which didnt work as well. – Raider32 Jul 21 '20 at 17:57
0

I finally figure it out. Basically I can store the user input using the session object available from the flask library. This allows different functions to access this rather then having to worry about creating global variables or passing them around via functions or objects.

Note 1- If the amount of user data that has to be saved is extensive then using Redis or some other type of in memory data storage would be a better choice in this case.

Raider32
  • 11
  • 1
  • 3
-2

Save the csv file in static path and then use the that static path csv URL to get csv file in download form from browser.