Issues switching from .callback to .long_callback

Hello all!

I am new to Dash/Plotly but I’ve run into this error I can’t wrap my head around and am looking for some assistance. I have a fully functional dash script with a certain callback that is called when a ‘run’ button is clicked, and I am trying to change this to a long_callback in order to have a cancel button and progress bar. I have all the packages, caches, managers set up properly because I can run all the examples from the long_callback page, however when I change “callback” to “long_callback” in my own script, I am getting weird errors.

For example, (without getting into too many details just yet) there is one line: if 'Generic Table' in tables_to_compute:, where tables_to_compute=[‘Generic Table’]. With long_callback, I get the error "TypeError: argument of type ‘int’ is not iterable’, however there is no problem with the regular ‘callback’. If helpful, I can share more code.

I suppose there are two questions: (1) what is going on here? and (2) when switching from callbacks to long_callbacks, are there structural changes in the actual function contents that have to made to accommodate this switch?

Thanks!

Hi,

Welcome to the community!

It would be very helpful if you share your callback or a minimal reproducible error.

Of course!

Here is my code that works:

import webbrowser
import diskcache

from threading import Timer
from dash import Dash, dcc, html, Input, Output, State
from dash.long_callback import DiskcacheLongCallbackManager

cache=diskcache.Cache("./cache")
long_callback_manager=DiskcacheLongCallbackManager(cache)

list_of_tables=[['Generic Table',['Table Columns']]]

app = Dash(__name__)

app.layout = html.Div([
    dcc.Checklist([table[0] for table in list_of_tables],id='table checklist'),
    html.H3(children='Run simulation: '),
    html.Button(id='run simulation button',n_clicks=0,children='Run'),
    html.Div(id='my-output'),
])

@app.callback(
    Output('my-output', 'children'),
    State('table checklist','value'),
    Input('run simulation button', 'n_clicks'),
    prevent_initial_call=True
    )
def test(tables_to_compute,n_clicks):

    if 'Generic Table' in tables_to_compute:
        string='Generic table is checked'
    else:
        string='Generic table is not checked'

    return string

if __name__ == '__main__':
    Timer(1, webbrowser.open('http://127.0.0.1:8054/')).start();
    app.run_server(debug=True,use_reloader=False,port=8054)

But when I change the callback to

@app.long_callback(
    Output('my-output', 'children'),
    State('table checklist','value'),
    Input('run simulation button', 'n_clicks'),
    manager=long_callback_manager,
    prevent_initial_call=True
    )

I get the error.

Thanks for the reproducible example!

My suspicion before running was that it was mixing the order between Input and State and assigning the click count to tables_to_compute (therefore your error). I can confirm that this is exactly what happened and the error disappears if you switch the order in the decorator and in the function signature.

I think you can consider this a bug, although it is a good practice to have the Input before State in callbacks… I would recommend you to open an issue on GH to report it just in case.

welcome to the community @nbolohan and thanks for your question.

@jlfsjunior is correct. The Input should come before the State in the callback decorator. Such as:

@app.callback(
    Output('my-output', 'children'),
    Input('run simulation button', 'n_clicks'),
    State('table checklist','value'),
    prevent_initial_call=True
    )
def test(n_clicks, tables_to_compute):

Try that and let us know if you get an error.

Also, did you see the Dash 2.6 announcement post. We talk about a new version of long_callback called background callback.
The explanation in the post and in the docs might make what you’re trying to do a little easier.

1 Like

The proper ordering does eliminate all of my errors! Dash 2.6 was mentioned to me here, where the issue persisted with the background callback but it seems to be being looked after!

1 Like