Skip to content

Dash background callbacks fire as regular callbacks, "running" attrib doesnt fire #537

@KCommits

Description

@KCommits

I couldnt find info in the docs about this but it appears that dash's very helpful background callback feature doesn't fire the Output from the running= attrib with django plotly dash. Since many AI tasks take >30s its an important feature for me and others with long-running tasks.

The callback fires, but appears to do so as a normal callback. The Output in the running doesnt seem to do anything. I attached a video and a reproducible example below.

Video w/inspector showing the disabled class isn't set.: https://i.imgur.com/A6MZ8OR.mp4

This example is from the dash docs where you can see what should happen: https://dash.plotly.com/background-callbacks#disable-button-while-callback-is-running

I notice in dash_wrapper.py the only arguments for callback are def callback(self, output, inputs, state, prevent_initial_call):, am I right in inferring this mans the other ares arent passed? Is it as simple as passing along the kwargs?

I see this warning on app start

[...]/.venv/lib/python3.12/site-packages/django_plotly_dash/dash_wrapper.py:167: UserWarning:

You are passing extra arguments {'background_callback_manager': <dash.background_callback.managers.diskcache_manager.DiskcacheManager object at 0x79bab2dd2600>} that will be passed to Dash(...) but may not be properly handled by django-plotly-dash.

Here's a simple example to reproduce, taken from the dash docs linked above and modified for DPD:

# dashapps/background_callback_test.py
import time
import os
import time

from dash import DiskcacheManager, CeleryManager, Input, Output, html
from django_plotly_dash import DjangoDash

import diskcache
cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)

# Register the app with a name that matches the template tag
app = DjangoDash(
    name="background-callback-test",
    background_callback_manager=background_callback_manager,
)

app.layout = html.Div(
    [
        html.Div([html.P(id="paragraph_id", children=["Button not clicked"])]),
        html.Button(id="button_id", children="Run Job!"),
    ]
)

@app.callback(
    output=Output("paragraph_id", "children"),
    inputs=Input("button_id", "n_clicks"),
    background=True,
    running=[(Output("button_id", "disabled"), True, False)],
)
def update_clicks(n_clicks):
    time.sleep(2.0)
    return [f"Clicked {n_clicks} times"]

Here's a requirements.txt:

Django~=5.2.5
psycopg2-binary~=2.9.10
dj-database-url~=3.0.1
python-dotenv~=1.1.1
gunicorn~=23.0.0
daphne~=4.2.1
channels~=4.3.1
django-plotly-dash~=2.5.0
dash~=3.2.0
dash-bootstrap-components~=2.0.4
dash[diskcache]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions