This all made me wonder whether your original question can be answered using basic Dash functionality, without background callbacks or advanced functionality like to_plotly_json() in a clientside callback.
The example code below is all basic Dash functionality, and I think shows the kind of thing you want. The first and second buttons are disabled (and a ‘loading’ is shown) during the pause triggered by the first button. The third button remains enabled, and appears to happily respond to clicks during the pause. (I’m unsure how reliably this kind of thing can be done though).
(To answer your other question, a callback can use the same dcc.Store as both an Input and an Output, though it’s not needed in this example)
from dash import html, Dash, callback, Input, Output, dcc
from time import sleep
app = Dash(__name__)
app.layout = html.Div(
[
dcc.Store(id='store-trigger'),
html.Button("Pause for a while", id="button-pause"),
dcc.Loading(
id="loading-1",
type="default",
children=html.Div(id="pause-nclicks", children=['0']),
),
html.Button("Disabled during pause", id="button-dependent"),
html.Div(id="dependent-nclicks", children=['0']),
html.Button("Enabled during pause", id="button-independent"),
html.Div(id="independent-nclicks", children=['0']),
]
)
# -- Pause button clicked: Disable 'pause' and 'dependent' buttons and update store
@callback(
Output("store-trigger", "data"),
Output("button-pause","disabled", allow_duplicate=True),
Output("button-dependent","disabled", allow_duplicate=True),
Input("button-pause", "n_clicks"),
prevent_initial_call=True
)
def start_pause(nclicks):
return nclicks, True, True
# -- Store updated: do the long calculation. Enable 'pause' and 'dependent' button when it is finished
@callback(
Output("pause-nclicks", "children"),
Output("button-pause","disabled", allow_duplicate=True),
Output("button-dependent","disabled", allow_duplicate=True),
Input("store-trigger", "data"),
prevent_initial_call=True
)
def do_pause(nclicks):
sleep(5)
return str(nclicks), False, False
# -- 'Dependent' button clicked
@callback(
Output("dependent-nclicks", "children"),
Input("button-dependent", "n_clicks"),
prevent_initial_call=True
)
def update_dependent(nclicks):
return str(nclicks)
# -- 'Independent' button clicked
@callback(
Output("independent-nclicks", "children"),
Input("button-independent", "n_clicks"),
prevent_initial_call=True
)
def update_independent(nclicks):
return str(nclicks)
if __name__ == '__main__':
app.run_server(debug=False, host='0.0.0.0')