Python web application framework for building reactive analytical web apps without JavaScript
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The callback system is the heart of Dash's reactive programming model, enabling automatic updates of components based on user interactions. Callbacks define relationships between component properties through Input, Output, and State dependencies.
Define relationships between components for reactive updates.
class Input:
def __init__(self, component_id: ComponentIdType, component_property: str):
"""
Define input dependency that triggers callback execution.
Parameters:
- component_id: ID of the component to watch
- component_property: Property of the component to watch
"""
class Output:
def __init__(self, component_id: ComponentIdType, component_property: str):
"""
Define output dependency that gets updated by callback.
Parameters:
- component_id: ID of the component to update
- component_property: Property of the component to update
"""
class State:
def __init__(self, component_id: ComponentIdType, component_property: str):
"""
Define state dependency that provides values without triggering.
Parameters:
- component_id: ID of the component to read
- component_property: Property of the component to read
"""Register reactive functions that respond to component interactions.
def callback(
output: Union[Output, List[Output]],
inputs: Union[Input, List[Input]] = None,
state: Union[State, List[State]] = None,
prevent_initial_call: bool = None,
prevent_initial_callbacks: bool = None,
background: bool = None,
manager: Any = None,
running: List[Tuple[Output, Any]] = None,
progress: List[Output] = None,
progress_default: List[Any] = None,
cancel: List[Input] = None,
cache_by: List[Union[Input, State]] = None,
long_callback_manager: Any = None
) -> Callable:
"""
Decorator for registering callback functions.
Parameters:
- output: Output dependencies (what gets updated)
- inputs: Input dependencies (what triggers the callback)
- state: State dependencies (additional values)
- prevent_initial_call: Skip callback on initial load
- background: Execute in background thread
- manager: Background callback manager
- running: Components to update while callback runs
- progress: Components for progress reporting
- cancel: Inputs that can cancel background callbacks
"""
def clientside_callback(
clientside_function: Union[ClientsideFunction, str],
output: Union[Output, List[Output]],
inputs: Union[Input, List[Input]] = None,
state: Union[State, List[State]] = None,
prevent_initial_call: bool = None
):
"""
Register JavaScript callback for client-side execution.
Parameters:
- clientside_function: JavaScript function or ClientsideFunction
- output: Output dependencies
- inputs: Input dependencies
- state: State dependencies
"""Execute callbacks in the browser using JavaScript for improved performance.
class ClientsideFunction:
def __init__(self, namespace: str, function_name: str):
"""
Reference to JavaScript function for clientside callbacks.
Parameters:
- namespace: JavaScript namespace containing the function
- function_name: Name of the JavaScript function
"""Use wildcards to create callbacks that respond to dynamic component patterns.
MATCH: Any = _Wildcard("MATCH") # Match any component ID
ALL: Any = _Wildcard("ALL") # Match all component IDs
ALLSMALLER: Any = _Wildcard("ALLSMALLER") # Match all smaller indices
# Usage in component IDs
{"type": "button", "index": MATCH} # Match any button
{"type": "button", "index": ALL} # Match all buttons
{"type": "button", "index": ALLSMALLER} # Match buttons with smaller indicesAccess information about callback execution and trigger events.
callback_context: CallbackContext # Global callback context
ctx: CallbackContext # Alias for callback_context
class CallbackContext:
@property
def triggered(self) -> List[Dict[str, Any]]:
"""List of triggered inputs with their values."""
@property
def inputs(self) -> Dict[str, Any]:
"""Dictionary of all input values."""
@property
def states(self) -> Dict[str, Any]:
"""Dictionary of all state values."""
@property
def outputs_list(self) -> List[Dict[str, Any]]:
"""List of output specifications."""
@property
def inputs_list(self) -> List[Dict[str, Any]]:
"""List of input specifications."""
@property
def states_list(self) -> List[Dict[str, Any]]:
"""List of state specifications."""
@property
def response(self) -> Dict[str, Any]:
"""Response information for the callback."""Programmatically update component properties outside of callbacks.
def set_props(component_id: str, props: Dict[str, Any]):
"""
Update component properties programmatically.
Parameters:
- component_id: ID of component to update
- props: Dictionary of properties to update
"""from dash import Dash, html, dcc, callback, Input, Output
app = Dash(__name__)
app.layout = html.Div([
dcc.Input(id='input', value='Initial'),
html.Div(id='output')
])
@callback(
Output('output', 'children'),
Input('input', 'value')
)
def update_output(value):
return f'You entered: {value}'@callback(
[Output('output1', 'children'), Output('output2', 'children')],
[Input('input1', 'value'), Input('input2', 'value')],
State('state-input', 'value')
)
def update_multiple(input1, input2, state_value):
return f'Input 1: {input1}', f'Input 2: {input2}, State: {state_value}'@callback(
Output({'type': 'output', 'index': MATCH}, 'children'),
Input({'type': 'button', 'index': MATCH}, 'n_clicks'),
prevent_initial_call=True
)
def update_matched_output(n_clicks):
return f'Button clicked {n_clicks} times'from dash import clientside_callback, ClientsideFunction
# JavaScript function in assets/custom.js:
# window.dash_clientside = Object.assign({}, window.dash_clientside, {
# clientside: {
# large_params_function: function(value) {
# return 'Client says: ' + value;
# }
# }
# });
clientside_callback(
ClientsideFunction(namespace='clientside', function_name='large_params_function'),
Output('output', 'children'),
Input('input', 'value')
)from dash import callback_context
@callback(
Output('output', 'children'),
[Input('btn1', 'n_clicks'), Input('btn2', 'n_clicks')]
)
def update_output(btn1, btn2):
if not callback_context.triggered:
return "No button clicked yet"
button_id = callback_context.triggered[0]['prop_id'].split('.')[0]
return f'Button {button_id} was clicked'from dash.long_callback import DiskcacheManager
import diskcache
cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)
@callback(
Output('output', 'children'),
Input('button', 'n_clicks'),
background=True,
manager=background_callback_manager,
running=[
(Output('loading', 'children'), 'Loading...'),
(Output('button', 'disabled'), True)
],
progress=[Output('progress', 'value'), Output('progress', 'max')],
progress_default=[0, 100]
)
def long_running_callback(set_progress, n_clicks):
import time
for i in range(100):
time.sleep(0.1)
set_progress((i, 100))
return f'Completed after {n_clicks} clicks'ComponentIdType = Union[str, Dict, Component]
DependencyType = Union[Input, Output, State]
DependencyList = List[DependencyType]
CallbackFunction = Callable[..., Any]
CallbackReturnType = Union[Any, List[Any], Dict[str, Any]]
CallbackContext = Any
ClientsideFunction = Any
BackgroundCallbackManager = AnyInstall with Tessl CLI
npx tessl i tessl/pypi-dash