Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Background callbacks not working with pages #2219

Closed
brianleslie opened this issue Sep 6, 2022 · 2 comments · Fixed by #2226
Closed

[BUG] Background callbacks not working with pages #2219

brianleslie opened this issue Sep 6, 2022 · 2 comments · Fixed by #2226

Comments

@brianleslie
Copy link

brianleslie commented Sep 6, 2022

Describe your context
Dash Callback Example 4: Progress Bar from https://dash.plotly.com/background-callbacks

dash                      2.6.1                                                                                         
dash-bootstrap-components 1.2.1                                                                                        
dash-core-components      2.0.0                                                                                         
dash-daq                  0.5.0                                                                                         
dash-html-components      2.0.0                                                                                        
 dash-table                5.0.0
- OS: Windows
- Browser Chrome
- Version 104.0.5112.81

Describe the bug

using background callbacks does not work with pages.

not using pages the code runs correctly

app.py


import os
import dash
from dash import DiskcacheManager, CeleryManager, html, page_container

# code to test without pages
# import pages.page as page

if 'REDIS_URL' in os.environ:
    # Use Redis & Celery if REDIS_URL set as an env variable
    from celery import Celery
    celery_app = Celery(__name__, broker=os.environ['REDIS_URL'], backend=os.environ['REDIS_URL'])
    background_callback_manager = CeleryManager(celery_app)

else:
    # Diskcache for non-production apps when developing locally
    import diskcache
    cache = diskcache.Cache("./cache")
    background_callback_manager = DiskcacheManager(cache)

app = dash.Dash(__name__,
                use_pages=True,
                # code to test without pages
                # use_pages=False,
                background_callback_manager=background_callback_manager)

app.layout = html.Div(
    page_container

    # code to test without pages
    # page.layout()
)

if __name__ == "__main__":
    app.run_server(debug=True)

pages/page.py


import dash
from dash import Input, Output, html
import time

dash.register_page(__name__, path='/page')


def layout():
    return html.Div([
        html.Div(
            [
                html.P(id="paragraph_id", children=["Button not clicked"]),
                html.Progress(id="progress_bar", value="0"),
            ]
        ),
        html.Button(id="button_id", children="Run Job!"),
        html.Button(id="cancel_button_id", children="Cancel Running Job!"),
    ])


@dash.callback(
    output=Output("paragraph_id", "children"),
    inputs=Input("button_id", "n_clicks"),
    background=True,
    running=[
        (Output("button_id", "disabled"), True, False),
        (Output("cancel_button_id", "disabled"), False, True),
        (
                Output("paragraph_id", "style"),
                {"visibility": "hidden"},
                {"visibility": "visible"},
        ),
        (
                Output("progress_bar", "style"),
                {"visibility": "visible"},
                {"visibility": "hidden"},
        ),
    ],
    cancel=Input("cancel_button_id", "n_clicks"),
    progress=[Output("progress_bar", "value"), Output("progress_bar", "max")],
    prevent_initial_call=True
)
def update_progress(set_progress, n_clicks):
    total = 5
    for i in range(total + 1):
        set_progress((str(i), str(total)))
        time.sleep(1)

    return f"Clicked {n_clicks} times"

Expected behavior

Ability to use background callbacks AND pages

Screenshots

image

@T4rk1n
Copy link
Contributor

T4rk1n commented Sep 7, 2022

Seems like the pickling calls register_page when unpickling the function definition on the workers, adding a context var to check if inside a background callback could fix this.

@roykoand
Copy link

roykoand commented Apr 3, 2024

@T4rk1n You've done a great work on solving this issue! It helped a lot :)
Do you have any documentation on ignoring a register page?
Is it correct that as of now the only solution is dash.testing.ignore_register_page context manager?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants