Example #1
0
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()))
Example #2
0
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()])
Example #3
0
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]
Example #4
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)
Example #6
0
        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)]
Example #7
0
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)
Example #8
0
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)
Example #9
0
)

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,
Example #10
0
                               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(