Hello everyone.
I have an app which has to download a lot of data. For convenience I’m trying to download the data bit by bit and store itermediate results in dcc.Store element.
The data is a python dictionary, and my idea was to download one key at a time.
After “submit” button is clicked, the app downloads first key and updates Store coponent. After that, as I hoped, the callback “update_index” would be fired again, because the “data” parameter has changed. However, this callback is not fired for the second time. Another callback – “test_callback”, that has the same “data” input, does get fired.
The only thing I could think about is the fact that these callbacks fire each other. Am I identifying the issue correctly and what can be done to achieve the result I want? Thanks!
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from flask import Flask
import time
server = Flask('app')
app = dash.Dash(__name__,
server=server)
app.layout = html.Div([
dcc.Store(id='data'),
html.Div(id='current_index'),
html.Button(id='submit', n_clicks=0, children='Submit'),
html.Div(id='test_div')
])
@app.callback(
Output('data', 'data'),
[Input('current_index', 'children')],
[State('data', 'data')]
)
def download_data(current_index, stored):
data = {
'0': [1, 2, 3],
'1': [2, 3, 4],
'2': [3, 4, 5]
}
if current_index is not None:
if stored is None:
stored = {}
print('downloading', current_index)
time.sleep(1)
stored[str(current_index)] = data[str(current_index)]
return stored
@app.callback(
Output('current_index', 'children'),
[Input('submit', 'n_clicks'),
Input('data', 'data')],
[State('current_index', 'children')]
)
def update_index(n_clicks, data, current_index):
ctx = dash.callback_context
print(ctx.triggered)
if n_clicks > 0:
new_index = 0
else:
if data is not None:
new_index = current_index + 1
if new_index > 2:
raise PreventUpdate
else:
new_index = None
return new_index
@app.callback(
Output('test_div', 'children'),
[Input('data', 'data')],
)
def test_callback(data):
if data is not None:
return 'Test callback fired'
if __name__ == '__main__':
app.run_server(debug=True, host='0.0.0.0', port=4202)