Datatable csv download throwing error in Dash app / browser

Hello all,

I have an app that downloads some data, displays it using the datatable component, and provides a link for the user to download the data as a .csv file. This has been working very smoothly up until recently, the .csv download component causes the app to error out. I’m having trouble resolving this because it doesn’t seem like an unwieldy amount of data but the browser/app can’t handle it.

Here’s a simplified reproducible example:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
import dash_table_experiments as dt

import flask
from flask import Flask

import urllib.parse
import pandas as pd
import os

server = Flask('test')

app = dash.Dash(server=server)

app.layout = html.Div([
        html.Button(id='start-button', n_clicks=0, children='Start'),
        html.A('Download Test Data', id='dl-test-data', download="testData.csv", href="", target="_blank"),
        dt.DataTable(id='test-dt', rows=[{}], editable=False, filterable=True, sortable=True, selected_row_indices=[])
    ])

@app.callback(
    Output('test-dt', 'rows'),
    [Input('start-button','n_clicks')])
def make_table(n_clicks):
    if n_clicks==0: return[{}]
    testData = pd.DataFrame(
        {'a': list(range(1, 1000)), 'b': list(range(1, 1000)), 'c': list(range(1, 1000)), 'd': list(range(1, 1000)),
         'e': list(range(1, 1000)), 'f': list(range(1, 1000)), 'g': list(range(1, 1000)), 'h': list(range(1, 1000)),
         'i': list(range(1, 1000)), 'j': list(range(1, 1000)), 'k': list(range(1, 1000)), 'l': list(range(1, 1000)),
         'm': list(range(1, 1000)), 'n': list(range(1, 1000)), 'o': list(range(1, 1000)), 'p': list(range(1, 1000))})

    return testData.to_dict('records')

@app.callback(
    Output('dl-test-data', 'href'),
    [Input('test-dt', 'rows')])
def update_travStats_dl_link(data):
    if data == [{}]: return
    testData = pd.DataFrame.from_dict(data)

    csv_string = testData.to_csv(index=False, encoding='utf-8')
    csv_string = "data:text/csv;charset=utf-8," + urllib.parse.quote(csv_string)
    return csv_string

if __name__ == '__main__':
    app.run_server(host='0.0.0.0')

This fails to update my link with the data from the datatable. Looking at the network backend of the app, it confirms that this component throws an error:

Any help or suggestions are much appreciate!

1 Like

I was using the same method and now it doesn’t work as well. I’ll let you know if I come up with anything, please post if you do in the meantime.