iamgda
iamgda

Reputation: 13

How to use dataframe from a function and return response to download csv file - Flask

I'm trying to create a download/export csv file button, but I'm having issues with it. I get this errror "TypeError: csv_download() missing 1 required positional argument: 'CSV'" when I try to return response. I have test it without calling the function and it work so I guess I missed something...I have also added a print ("print('this is CSV file:', test)") and it work but when I click on the Download button I get the error mentionned above..

@app.route("/result", methods=['POST','GET'])
def result():

mapping_query = """select * from test"""

from datetime import datetime
start_time = datetime.now().replace(microsecond=0)

Query = pd.read_sql_query(mapping_query, conn)

dataset = pd.DataFrame(Query)
dataset.set_index('itemID', inplace=True)
print(dataset)

csv_data = dataset.to_csv(index=False, encoding='utf-8')
# print(csv_data)
csv_download(csv_data)

Size_mapped = len(dataset)
print('Size Mapped with YP :', Size_mapped)
flash(Size_mapped)

results = list(dataset.values.tolist())

fieldnames = dataset.columns.values

end_time = datetime.now().replace(microsecond=0)

elapsed_time_known = end_time - start_time
print("\n")
print('>>>>> Time elapsed from beginning: <<<<<', elapsed_time_known)

return render_template('result.html', times=[elapsed_time_known], results=results, fieldnames=fieldnames, zip=zip)


@app.route("/csv_download", methods=['GET'])
def csv_download(CSV):
test = (CSV)

print("\n")
print('this is CSV file:', test)
response = Response(test,mimetype='text/csv')

response.headers.set("Content-Disposition", "attachment", filename="Export_Merchant_Validator_Tool.csv")

return response

Here is the button in result.html

<form style="margin-left: 38%" method="GET" action="/csv_download" enctype="multipart/form-data">

 <button style="height: 50%; width: 38%; color: white; background-color: #696969; border-color: #696969; "  type="submit" value="Submit"  class="btn btn-primary btn-lg" > Download dataset as csv </button>   

</form>

Thanks in advance for your time and help !

Upvotes: 0

Views: 766

Answers (1)

Detlef
Detlef

Reputation: 8552

I think the following example should meet your needs.
The data is queried again in the route and transmitted as a download using a stream and the send_file function.

import io 
from flask import send_file

@app.route('/csv_download')
def csv_download():
    sql = """select * from test"""
    df = pd.read_sql_query(sql, conn, index_col='itemID')
    return send_file(
        io.BytesIO(df.to_csv(index=False, encoding='utf-8').encode()),
        as_attachment=True,
        attachment_filename='Export_Merchant_Validator_Tool.csv',
        mimetype='text/csv')

You do not necessarily need a form if you do not want to pass any further parameters in a GET request.

<a href="{{ url_for('csv_download') }}" download>Download</a>

Upvotes: 1

Related Questions