Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions dash/_callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def callback(
cache_args_to_ignore: Optional[list] = None,
cache_ignore_triggered=True,
on_error: Optional[Callable[[Exception], Any]] = None,
optional: Optional[bool] = False,
**_kwargs,
) -> Callable[..., Any]:
"""
Expand Down Expand Up @@ -159,6 +160,8 @@ def callback(
Function to call when the callback raises an exception. Receives the
exception object as first argument. The callback_context can be used
to access the original callback inputs, states and output.
:param optional:
Mark all dependencies as not required on the initial layout checks.
"""

background_spec = None
Expand Down Expand Up @@ -213,6 +216,7 @@ def callback(
manager=manager,
running=running,
on_error=on_error,
optional=optional,
)


Expand Down Expand Up @@ -258,6 +262,7 @@ def insert_callback(
running=None,
dynamic_creator: Optional[bool] = False,
no_output=False,
optional=False,
):
if prevent_initial_call is None:
prevent_initial_call = config_prevent_initial_callbacks
Expand All @@ -281,6 +286,7 @@ def insert_callback(
},
"dynamic_creator": dynamic_creator,
"no_output": no_output,
"optional": optional,
}
if running:
callback_spec["running"] = running
Expand Down Expand Up @@ -624,6 +630,7 @@ def register_callback(
dynamic_creator=allow_dynamic_callbacks,
running=running,
no_output=not has_output,
optional=_kwargs.get("optional", False),
)

# pylint: disable=too-many-locals
Expand Down
18 changes: 12 additions & 6 deletions dash/dash-renderer/src/actions/dependencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -570,12 +570,18 @@ export function validateCallbacksToLayout(state_, dispatchError) {
for (const id in map) {
const idProps = map[id];
const fcb = flatten(values(idProps));
const optional = all(
({allow_optional}) => allow_optional,
flatten(
fcb.map(cb => concat(cb.outputs, cb.inputs, cb.states))
).filter(dep => dep.id === id)
);
const optional = fcb.reduce((acc, cb) => {
if (acc === false || cb.optional) {
return acc;
}
const deps = concat(cb.outputs, cb.inputs, cb.states).filter(
dep => dep.id === id
);
return (
!deps.length ||
all(({allow_optional}) => allow_optional, deps)
);
}, true);
if (optional) {
continue;
}
Expand Down