Struggling with long callbacks

Hello all,

This is my first post so I’m sorry is this topic is duplicated, I couldn’t see anything similar in the forum. I’m quite new on dash and I’m following Charming Data tutorials on youtube.

In one of this tutorials, I came up with this code which works perfectly:

import dash  # pip install dash
from dash import dcc, html, Dash, DiskcacheManager
from dash.dependencies import Input, Output, State
import plotly.express as px
import dash_bootstrap_components as dbc  # pip install dash-bootstrap-components
import pandas as pd

df = pd.read_csv("green_tripdata_2019-01.csv") # https://drive.google.com/file/d/13_zdqPKoj5ahIZ5g7CXRE5CNkiO9P_vP/view?usp=sharing
df = df[df["total_amount"] > 0]
df = df[:150000]

app = dash.Dash(__name__, external_stylesheets=[dbc.themes.LUMEN])  # https://bootswatch.com/default/ for more themes

app.layout = html.Div(
    children=[
        dbc.Row(dbc.Col(
            dcc.Loading(id="loading-1", type="default", children=[dcc.Graph(id="loading-output")], fullscreen=False),
            #dbc.Spinner(children=[dcc.Graph(id="loading-output")], size="lg", color="primary", type="border", fullscreen=False,),
            # spinner_style={"width": "10rem", "height": "10rem"}),
            # spinnerClassName="spinner"),
            # dcc.Loading(children=[dcc.Graph(id="loading-output")], color="#119DFF", type="dot", fullscreen=True,),

            width={'size': 12, 'offset': 0}),
        ),

        dbc.Row([
            dbc.Col(dbc.Input(id="passenger_count", type="number", min=1, max=6, step=1, value=1),
                    width={'size': 2, 'offset': 1}),
            dbc.Col(dbc.Button(id="loading-button", n_clicks=0, children=["Passengers"]),
                    width={'size': 1, 'offset': 0})
        ]), # no_gutters is no longer possible with the new Dash Bootstrap components version upgrade

    ]
)


@app.callback(
    Output("loading-output", "figure"),
    [Input("loading-button", "n_clicks")], 
    [State("passenger_count", "value")]
)
def load_output(n_clicks, psg_num):
    if n_clicks:
        dff = df[df["passenger_count"] == psg_num]
        fig = px.histogram(dff, x="total_amount", title="NYC Green Taxi Rides").update_layout(title_x=0.5)
        return fig
    return px.histogram(df.query(f"passenger_count=={psg_num}"), x="total_amount",
                        title="NYC Green Taxi Rides").update_layout(title_x=0.5)


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

However, when I’m trying to switch into long_callback because I don’t really know how much time could take to do the things that we find in the callback function, I’m struggling because it says that df is not defined. I’m trying that switch with this code:

import dash  # pip install dash
from dash import dcc, html, Dash, DiskcacheManager
from dash.dependencies import Input, Output, State
import plotly.express as px
import dash_bootstrap_components as dbc  # pip install dash-bootstrap-components
import pandas as pd
from dash.long_callback import DiskcacheLongCallbackManager
import diskcache

df = pd.read_csv("green_tripdata_2019-01.csv") # https://drive.google.com/file/d/13_zdqPKoj5ahIZ5g7CXRE5CNkiO9P_vP/view?usp=sharing
df = df[df["total_amount"] > 0]
df = df[:150000]

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

app = dash.Dash(__name__, long_callback_manager=lcm, external_stylesheets=[dbc.themes.LUMEN])  # https://bootswatch.com/default/ for more themes

app.layout = html.Div(
    children=[
        dbc.Row(dbc.Col(
            dcc.Loading(id="loading-1", type="default", children=[dcc.Graph(id="loading-output")], fullscreen=False),
            width={'size': 12, 'offset': 0}),
        ),

        dbc.Row([
            dbc.Col(dbc.Input(id="passenger_count", type="number", min=1, max=6, step=1, value=1),
                    width={'size': 2, 'offset': 1}),
            dbc.Col(dbc.Button(id="loading-button", n_clicks=0, children=["Passengers"]),
                    width={'size': 1, 'offset': 0})
        ]), 

    ]
)


@app.long_callback(
    output=Output("loading-output", "figure"),
    inputs=dict(n_clicks=Input("loading-button", "n_clicks")), 
    state=dict(psg_num=State("passenger_count", "value")),
    running=[(Output("loading-button", "disabled"), True, False),],
    #prevent_initial_call = True,
)
def load_output(n_clicks, psg_num):
    if n_clicks:
        dff = df[df["passenger_count"] == psg_num]
        fig = px.histogram(dff, x="total_amount", title="NYC Green Taxi Rides").update_layout(title_x=0.5)
        return fig
    return px.histogram(df.query(f"passenger_count=={psg_num}"), x="total_amount",
                        title="NYC Green Taxi Rides").update_layout(title_x=0.5)


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

Probably I’ve understood something bad, but don’t know why.

Thanks all in advance,
Kind regards :slight_smile:

EDIT: If this is useful for anyone, I don’t know why but this error only appears when using jupyterlab. I tried to execute the code with pycharm and worked perfectly.

Hey @Jonathan23 , welcome to the community.

Long callback is deprecated. Use background callbacks instead.

That said, it most likely won’t fix your problem.

I’ve never used dash in a notebook, so I can’t really help.

1 Like