def test_scalar_output_arg_dependencies(app, test_template): inputs = dl.Input(html.Button(), "n_clicks") state = dl.State(dcc.Input()) output = dl.Output(dcc.DatePickerRange(), ("start_date", "end_date")) # Build mock function fn = mock_fn_with_return((datetime.date(2010, 1, 1), datetime.date(2010, 1, 10))) fn_wrapper = app.callback( output=output, inputs=inputs, state=state, template=test_template )(fn) # call flat version (like dash would) assert fn_wrapper._flat_fn(12, "Some Text") == [ datetime.date(2010, 1, 1), datetime.date(2010, 1, 10), ] # Check how mock function was called args, kwargs = fn.call_args assert args == (12, "Some Text") assert not kwargs # Check order of dependencies assert_deps_eq(fn_wrapper._flat_input_deps, [inputs.dependencies()]) assert_deps_eq(fn_wrapper._flat_state_deps, [state.dependencies()]) assert_deps_eq(fn_wrapper._flat_output_deps, list(output.dependencies()))
def test_arg_dependencies(app, test_template, input_form): inputs = input_form( [ dl.Input(dcc.Slider(), label="Slider"), dl.Input(dcc.Dropdown(), label="Dropdown"), ] ) state = dl.State(dcc.Input(), label="State Input") output = dl.Output(dcc.Markdown(), "children", label="Markdown Output") # Build mock function fn = mock_fn_with_return("Hello, world") fn_wrapper = app.callback( output=output, inputs=inputs, state=state, template=test_template )(fn) # call flat version (like dash would) assert fn_wrapper._flat_fn(1, "Option", "Some Text") == ["Hello, world"] # Check how mock function was called args, kwargs = fn.call_args assert args == (1, "Option", "Some Text") assert not kwargs # Check order of dependencies assert_deps_eq(fn_wrapper._flat_input_deps, [a.dependencies() for a in inputs]) assert_deps_eq(fn_wrapper._flat_state_deps, [state.dependencies()]) assert_deps_eq(fn_wrapper._flat_output_deps, [output.dependencies()])
def test_state_kwarg_only(app, test_template): state = { "test_input": dl.State(dcc.Input()), "test_slider": dl.Input(dcc.Slider()), } output = {"test_output_markdown": dl.Output(dcc.Markdown(), "children")} # Build mock function fn = mock_fn_with_return({"test_output_markdown": "Hello, world"}) fn_wrapper = app.callback(output=output, state=state, template=test_template)(fn) # call flat version (like dash would) assert fn_wrapper._flat_fn(1, "input string") == ["Hello, world"] # Check how mock function was called args, kwargs = fn.call_args assert kwargs == { "test_slider": 1, "test_input": "input string", } assert not args # Check dependencies # Input input_param_components = test_template.roles["input"] arg_component = input_param_components["test_input"].arg_component arg_props = input_param_components["test_input"].arg_property expected_deps = flat_deps(arg_component, arg_props, "state") assert isinstance(arg_component, dcc.Input) assert arg_props == "value" assert fn_wrapper._flat_state_deps[0] == expected_deps[0] # Slider input_param_components = test_template.roles["input"] arg_component = input_param_components["test_slider"].arg_component arg_props = input_param_components["test_slider"].arg_property expected_deps = flat_deps(arg_component, arg_props, "input") assert isinstance(arg_component, dcc.Slider) assert arg_props == "value" assert fn_wrapper._flat_input_deps[0] == expected_deps[0] # Markdown Output output_param_components = test_template.roles["output"] arg_component = output_param_components["test_output_markdown"].arg_component arg_props = output_param_components["test_output_markdown"].arg_property expected_deps = flat_deps(arg_component, arg_props, "output") assert isinstance(arg_component, dcc.Markdown) assert arg_props == "children" assert fn_wrapper._flat_output_deps[0] == expected_deps[0]
def wrapper(fn): def callback(__n_intervals__, *args, **kwargs): result_key = json.dumps({"args": list(args), "kwargs": kwargs}) progress_key = result_key + "-progress" result = cache.get(result_key) progress = cache.get(progress_key) if result is not None: return dict(result=result, interval_disabled=True) elif progress is not None: return dict( result=html.Progress( value=str(progress[0]), max=str(progress[1]), id=progress_id, style=progress_style, ), interval_disabled=False, ) else: target = make_update_cache(fn, cache, result_key, progress_key) p = Process(target=target, args=args, kwargs=kwargs) p.start() return dict( result=html.Progress(id=progress_id, style=progress_style), interval_disabled=False, ) interval_component = dl.Input( dcc.Interval(interval=interval, id=dl.build_id("interval")), "n_intervals", label=None, ) # Add interval component to inputs all_args = args if isinstance(all_args, dict): all_args = dict(all_args, __n_intervals__=interval_component) else: if not isinstance(all_args, (list, tuple)): all_args = [all_args] all_args = [interval_component] + all_args all_output = dict( result=dl.Output(html.Div(), "children"), interval_disabled=Output(interval_component.id, "disabled"), ) return app.callback(args=all_args, output=all_output, template=template)(callback)
def test_template_layout_generation(app, test_template): inputs = {"test_slider": dx.Input(dcc.Slider(min=0, max=10))} state = {"test_input": dx.State(dcc.Input(value="Initial input"))} output = {"test_output_markdown": dx.Output(dcc.Markdown(), "children")} # Build mock function fn = mock_fn_with_return({"test_output_markdown": "Hello, world"}) fn_wrapper = dx.callback(app, output=output, inputs=inputs, state=state, template=test_template)(fn) # Check dependencies # Slider input_param_components = test_template.roles["input"] arg_component = input_param_components["test_slider"].arg_component arg_props = input_param_components["test_slider"].arg_property assert isinstance(arg_component, dcc.Slider) assert arg_props == "value" expect_input_deps = Input(arg_component.id, "value") assert fn_wrapper._flat_input_deps[0] == expect_input_deps # Input Component as State input_param_components = test_template.roles["input"] arg_component = input_param_components["test_input"].arg_component arg_props = input_param_components["test_input"].arg_property assert isinstance(arg_component, dcc.Input) assert arg_props == "value" expect_input_deps = Input(arg_component.id, "value") assert fn_wrapper._flat_state_deps[0] == expect_input_deps # Markdown Output output_param_components = test_template.roles["output"] arg_component = output_param_components[ "test_output_markdown"].arg_component arg_props = output_param_components["test_output_markdown"].arg_property assert isinstance(arg_component, dcc.Markdown) assert arg_props == "children" expect_output_deps = Input(arg_component.id, "children") assert fn_wrapper._flat_output_deps[0] == expect_output_deps # Check generated layout layout = test_template.layout(app, full=False) check_layout_body(layout, test_template)
year_args=year_label_plugin.args, logs=tpl.checklist_input(["log(x)"], value="log(x)", label="Axis Scale", role="scatter"), table_inputs=table_plugin.args, tab=tpl.tab_input(), ), output=[ tpl.graph_output(role="scatter"), tpl.graph_output(role="hist"), table_plugin.output, year_label_plugin.output, dl.Output( dbc.Label(children="Current Tab: ", className="h5"), "children", role="input", ), ], template=tpl, ) def callback(year_args, continent, logs, table_inputs, tab): # Get year value from plugin year = year_label_plugin.get_value(year_args) logs = logs or [] # Let parameterize infer output component year_df = df[df.year == year] if continent: year_df = year_df[year_df.continent.isin(continent)]
import dash_labs as dl import dash_html_components as html import dash app = dash.Dash(__name__, plugins=[dl.plugins.FlexibleCallbacks()]) tpl = dl.templates.DbcCard(title="Simple App", columns=4) div = html.Div() button = html.Button(children="Click Me") @app.callback(dl.Output(div, "children"), dl.Input(button, "n_clicks")) def callback(n_clicks): return "Clicked {} times".format(n_clicks) tpl.add_component(button, label="Button to click", role="input") tpl.add_component(div, role="output") app.layout = tpl.layout(app) if __name__ == "__main__": app.run_server(debug=True)
def check_component_props_as_groupings( app, input_grouping, state_grouping, output_grouping, template, input_form="list", output_form="list", ): # Compute grouping sizes input_size = grouping_len(input_grouping) state_size = grouping_len(state_grouping) output_size = grouping_len(output_grouping) # Make buttons input_button, input_prop = button_component_prop_for_grouping( input_grouping) state_button, state_prop = button_component_prop_for_grouping( state_grouping) output_button, output_prop = button_component_prop_for_grouping( output_grouping) # Make flat dependencies flat_input_deps = flat_deps(input_button, input_prop, "input") + make_deps( Input, 1) flat_state_deps = flat_deps(state_button, state_prop, "state") flat_output_deps = make_deps(Output, 1) + flat_deps( output_button, output_prop, "output") # Build grouped dependency lists grouped_input_deps = [ dl.Input(input_button, input_prop), flat_input_deps[-1] ] grouped_state_deps = [dl.State(state_button, state_prop)] grouped_output_deps = [ flat_output_deps[0], dl.Output(output_button, output_prop) ] # Build flat input/output values (state is part of input now) flat_input_values = (make_letters(input_size) + ["-"] + make_letters(state_size, upper=True)) flat_output_values = [-1] + list(range(5, output_size + 5)) # Build grouped input/output values (state is part of input) grouped_input_values = [ make_letters_grouping(input_grouping), "-", make_letters_grouping(state_grouping, upper=True), ] grouped_output_values = [ -1, make_numbers_grouping(output_grouping, offset=5) ] # Handle input data forms if input_form == "dict": only_input_keys = make_letters(len(grouped_input_deps), upper=True) grouped_input_deps = { k: v for k, v in zip(only_input_keys, grouped_input_deps) } state_keys = make_letters(len(grouped_state_deps), upper=False) grouped_state_deps = { k: v for k, v in zip(state_keys, grouped_state_deps) } input_value_keys = only_input_keys + state_keys grouped_input_values = { k: v for k, v in zip(input_value_keys, grouped_input_values) } if output_form == "scalar": # Remove first extra scalar value, leave only grouped value as scalar grouped_output_deps = grouped_output_deps[1] grouped_output_values = grouped_output_values[1] flat_output_values = flat_output_values[1:] flat_output_deps = flat_output_deps[1:] elif output_form == "dict": grouped_output_deps = { k: v for k, v in zip(make_letters(len(grouped_output_deps), upper=True), grouped_output_deps) } grouped_output_values = { k: v for k, v in zip( make_letters(len(grouped_output_deps), upper=True), grouped_output_values, ) } # Build mock function with grouped output as return values fn = mock_fn_with_return(grouped_output_values) # Wrap callback with grouped dependency specifications fn_wrapper = dl.callback( app, output=grouped_output_deps, inputs=grouped_input_deps, state=grouped_state_deps, template=template, )(fn) # call flat version (like dash.Dash.callback would) assert fn_wrapper._flat_fn(*flat_input_values) == flat_output_values # Check that mock function was called with expected grouped values args, kwargs = fn.call_args if input_form == "list": assert args == tuple(grouped_input_values) assert not kwargs elif input_form == "dict": assert kwargs == grouped_input_values assert not args # Check order of dependencies assert_deps_eq(fn_wrapper._flat_input_deps, flat_input_deps) assert_deps_eq(fn_wrapper._flat_state_deps, flat_state_deps) assert_deps_eq(fn_wrapper._flat_output_deps, flat_output_deps)
) years = df.year.unique() range_slider = dcc.RangeSlider( min=years[0], max=years[-1], step=5, marks={int(i): str(i) for i in [1952, 2007]}, tooltip={"placement": "bottom"}, value=[1982, years[-1]], ) @app.callback( dl.Output(html.Div(), "children"), dl.Input(dropdown, label="Select indicator (y-axis)"), dl.Input(checklist, label="Select continents"), dl.Input(range_slider, label="Select time period"), Input("themes", "value"), Input("graph_template", "value"), Input("discrete_selected", "children"), Input("continuous_selected", "children"), Input("checkbox", "value"), template=tpl, ) def update_charts( indicator, continents, yrs, theme,
debounce=True, value=0, min=0, step=1000) geolocation = dmc.Geolocation(id="geolocation") interval = dcc.Interval(id="interval", disabled=True) """ =============================================================================== Callbacks """ @app.callback( dl.Output( geolocation, ("high_accuracy", "maximum_age", "timeout", "show_alert"), ), Input("options_checklist", "value"), Input("max_age", "value"), Input("timeout_input", "value"), ) def update_options(checked, maxage, timeout): if checked: high_accuracy = True if "high_accuracy" in checked else False alert = True if "alert" in checked else False else: watch, high_accuracy, alert = False, False, False return high_accuracy, maxage, timeout, alert @app.callback(