Allowing users to download CSV on click

I had some trouble getting this to work in Python 3. After some searching I found out that some minor changes were needed (ref https://stackoverflow.com/questions/35710361/python-flask-send-file-stringio-blank-files). Taking together the above gave me the following working example:

import io

import flask
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input

app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Dropdown(id='my-dropdown', value='default',
                 options=[
                     {'label': 'New York City', 'value': 'NYC'},
                     {'label': 'Montréal', 'value': 'MTL'},
                     {'label': 'San Francisco', 'value': 'SF'}
                 ]
                 ),
    html.A('Download CSV', id='my-link'),

])


@app.callback(Output('my-link', 'href'), [Input('my-dropdown', 'value')])
def update_link(value):
    return '/dash/urlToDownload?value={}'.format(value)


@app.server.route('/dash/urlToDownload')
def download_csv():
    value = flask.request.args.get('value')
    # create a dynamic csv or file here using `StringIO`
    # (instead of writing to the file system)
    str_io = io.StringIO()
    str_io.write('You have selected {}'.format(value))
    mem = io.BytesIO()
    mem.write(str_io.getvalue().encode('utf-8'))
    mem.seek(0)
    str_io.close()
    return flask.send_file(mem,
                           mimetype='text/csv',
                           attachment_filename='downloadFile.csv',
                           as_attachment=True)


if __name__ == '__main__':
    app.run_server(debug=True)
6 Likes