Skip to content

Commit 5d1e163

Browse files
committed
Add running to regular callbacks.
1 parent 6b31a8f commit 5d1e163

File tree

4 files changed

+51
-17
lines changed

4 files changed

+51
-17
lines changed

dash/_callback.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,6 @@ def callback(
166166
"Progress and progress default needs to be of same length"
167167
)
168168

169-
if running:
170-
long_spec["running"] = coerce_to_list(running)
171-
validate_long_inputs(x[0] for x in long_spec["running"])
172-
173169
if cancel:
174170
cancel_inputs = coerce_to_list(cancel)
175171
validate_long_inputs(cancel_inputs)
@@ -188,6 +184,7 @@ def callback(
188184
**_kwargs,
189185
long=long_spec,
190186
manager=manager,
187+
running=running,
191188
)
192189

193190

@@ -227,6 +224,7 @@ def insert_callback(
227224
prevent_initial_call,
228225
long=None,
229226
manager=None,
227+
running=None,
230228
dynamic_creator=False,
231229
):
232230
if prevent_initial_call is None:
@@ -251,6 +249,8 @@ def insert_callback(
251249
},
252250
"dynamic_creator": dynamic_creator,
253251
}
252+
if running:
253+
callback_spec["running"] = running
254254

255255
callback_map[callback_id] = {
256256
"inputs": callback_spec["inputs"],
@@ -289,6 +289,14 @@ def register_callback( # pylint: disable=R0914
289289

290290
long = _kwargs.get("long")
291291
manager = _kwargs.get("manager")
292+
running = _kwargs.get("running")
293+
if running is not None:
294+
if not isinstance(running[0], (list, tuple)):
295+
running = [running]
296+
running = {
297+
"running": {str(r[0]): r[1] for r in running},
298+
"runningOff": {str(r[0]): r[2] for r in running},
299+
}
292300
allow_dynamic_callbacks = _kwargs.get("_allow_dynamic_callbacks")
293301

294302
output_indices = make_grouping_by_index(output, list(range(grouping_len(output))))
@@ -305,6 +313,7 @@ def register_callback( # pylint: disable=R0914
305313
long=long,
306314
manager=manager,
307315
dynamic_creator=allow_dynamic_callbacks,
316+
running=running,
308317
)
309318

310319
# pylint: disable=too-many-locals
@@ -389,11 +398,6 @@ def add_context(*args, **kwargs):
389398
"job": job,
390399
}
391400

392-
running = long.get("running")
393-
394-
if running:
395-
data["running"] = {str(r[0]): r[1] for r in running}
396-
data["runningOff"] = {str(r[0]): r[2] for r in running}
397401
cancel = long.get("cancel")
398402
if cancel:
399403
data["cancel"] = cancel

dash/dash-renderer/src/actions/callbacks.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,8 @@ function handleServerside(
349349
long: LongCallbackInfo | undefined,
350350
additionalArgs: [string, string, boolean?][] | undefined,
351351
getState: any,
352-
output: string
352+
output: string,
353+
running: any
353354
): Promise<CallbackResponse> {
354355
if (hooks.request_pre) {
355356
hooks.request_pre(payload);
@@ -363,6 +364,11 @@ function handleServerside(
363364
let progressDefault: any;
364365
let moreArgs = additionalArgs;
365366

367+
if (running) {
368+
sideUpdate(running.running, dispatch, paths);
369+
runningOff = running.runningOff;
370+
}
371+
366372
const fetchCallback = () => {
367373
const headers = getCSRFHeader() as any;
368374
let url = `${urlBase(config)}_dash-update-component`;
@@ -497,12 +503,6 @@ function handleServerside(
497503
if (data.progress) {
498504
sideUpdate(data.progress, dispatch, paths);
499505
}
500-
if (data.running) {
501-
sideUpdate(data.running, dispatch, paths);
502-
}
503-
if (!runningOff && data.runningOff) {
504-
runningOff = data.runningOff;
505-
}
506506
if (!progressDefault && data.progressDefault) {
507507
progressDefault = data.progressDefault;
508508
}
@@ -717,7 +717,8 @@ export function executeCallback(
717717
long,
718718
additionalArgs.length ? additionalArgs : undefined,
719719
getState,
720-
cb.callback.output
720+
cb.callback.output,
721+
cb.callback.running
721722
);
722723

723724
if (newHeaders) {

dash/dash-renderer/src/types/callbacks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface ICallbackDefinition {
1313
state: ICallbackProperty[];
1414
long?: LongCallbackInfo;
1515
dynamic_creator?: boolean;
16+
running: any;
1617
}
1718

1819
export interface ICallbackProperty {

tests/integration/callbacks/test_basic_callback.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,3 +791,31 @@ def on_click(_):
791791
dash_duo.start_server(app)
792792

793793
assert dash_duo.get_logs() == []
794+
795+
796+
def test_cbsc019_callback_running(dash_duo):
797+
app = Dash(__name__)
798+
799+
app.layout = html.Div(
800+
[
801+
html.Div("off", id="running"),
802+
html.Button("start", id="start"),
803+
html.Div(id="output"),
804+
]
805+
)
806+
807+
@app.callback(
808+
Output("output", "children"),
809+
Input("start", "n_clicks"),
810+
running=[[Output("running", "children"), "on", "off"]],
811+
prevent_initial_call=True,
812+
)
813+
def on_click(_):
814+
time.sleep(1.0)
815+
return "done"
816+
817+
dash_duo.start_server(app)
818+
dash_duo.find_element("#start").click()
819+
dash_duo.wait_for_text_to_equal("#running", "on")
820+
dash_duo.wait_for_text_to_equal("#output", "done")
821+
dash_duo.wait_for_text_to_equal("#running", "off")

0 commit comments

Comments
 (0)