How to make long_callback work with MultiPageDashApp?

I tried to create a multi-page Dash app which use “@long_callback” in a separated file under pages fold, code copied from example from dash-labs/histograms.py at main · plotly/dash-labs · GitHub

I want to replace @callback with @long_callback to make the function run asynchronously, but I don’t know how to achieve it. Any help?

@callback(
Output(“histograms-graph”, “figure”),
Input(“histograms-mean”, “value”),
Input(“histograms-std”, “value”),
)
def display_color(mean, std):
# data = np.random.normal(mean, std, size=500)
data = fetch_from_database()
fig = px.histogram(data, nbins=30, range_x=[-10, 10])
return fig

Hi @vnnw and welcome to the Dash community :slight_smile:

Currently long_callback requires the app object, ie @app.long_callback. It will cause circular imports if you try to include it in the pages/ folder. However, it’s still possible to use it in this multi-page environment.

The workaround is to put the @app.long_callback in the app.py file. The layout and any other @callbacks can be in the pages/ folder.

I’ll post an example to dash-labs shortly.

2 Likes

How can i find this example? @AnnMarieW

Hi @icescreamsandwic I removed the example because app.long_callback had some bugs. The good news is that it was fixed in the latest dash release 2.6.0.

long_callback has been completely refactored - you can see a preview in the pull request. The announcement and docs are coming soon. :tada:

1 Like

@AnnMarieW there is a small issue that i noticed in the link u passed.

  • #2039 Long callback changes:
    • Add long=False to dash.callback to use instead of app.long_callback

But in the examples u use long=True and it makes sense to do so.

Secondly, this isn’t available in 2.6.0 right?

Because that’s what i am using right now but i get

TypeError: dash._callback.register_callback() got multiple values for keyword argument 'long'

Sorry, I’m not too familiar with this new feature yet - I’m waiting for the docs to be available.

The release notes clarify things for 2.6.0.

You can use a dash.callback and add background=True to convert it to a long callback. The previous long callback arguments (like cancel, running, etc) can now be moved to dash.callback

See the notes here: Release Dash v2.6.0 · plotly/dash · GitHub

There are a couple other changes to be aware of that haven’t been updated in the docs yet, as I’ve just discovered. Configuration of the celery manager should now look like this:

from celery import Celery
from dash import CeleryManager, Dash

celery_app = Celery(
  __name__,
  broker='redis://localhost:6379/0',
  backend='redis://localhost:6379/1',
)
background_callback_manager = CeleryManager(celery_app)

app = Dash(
  __name__,
  background_callback_manager=background_callback_manager,
)
1 Like

Thanks for sharing @james_cultivarium . The updated docs for the long callback and the rest of Dash 2.6.0 are being written as we speak. We hope to publish them by end of next week.

Any news on the docs? I couldn’t figure it out with the docs currently available

See the new background callback feature in 📣 Dash 2.6 Released - Background Callbacks, Unit Testing, Persistent Selections, Dropdown Features which moves app.long_callback to dash.callback(background=True) :slightly_smiling_face: Since it’s part of the dash namespace, you won’t face the same circular import issues. Also, some of the issues reported around using this feature in dynamic layouts have been fixed.

See the new docs here: Background Callbacks | Dash for Python Documentation | Plotly

1 Like

I was able to use background callbacks in a multipage Dash App and posted my solution in Stackoverflow here, if anyone is interested:

1 Like