예제 #1
0
def test_gene002_arbitrary_resources(dash_duo):
    app = Dash(__name__)

    app.layout = Div([Button(id="btn"), Div(id="container")])

    @app.callback(Output("container", "children"), [Input("btn", "n_clicks")])
    def update_container(n_clicks):
        if n_clicks is None:
            raise PreventUpdate

        return StyledComponent(id="styled",
                               value="Styled",
                               style={"font-family": "godfather"})

    dash_duo.start_server(app)

    assert (dash_duo.driver.execute_script(
        "return document.fonts.check('1em godfather')") is False)

    dash_duo.wait_for_element("#btn").click()
    assert dash_duo.wait_for_element("#styled").text == "Styled"

    WebDriverWait(dash_duo.driver, 10).until(
        lambda _: dash_duo.driver.execute_script(
            "return document.fonts.check('1em godfather')") is True, )

    dash_duo.percy_snapshot(name="gene002-arbitrary-resource")
예제 #2
0
def test_szng004_on_focus(test, props, data_fn):
    app = dash.Dash(__name__)

    baseProps1 = get_props(data_fn=data_fn)
    baseProps2 = get_props(data_fn=data_fn)

    baseProps1.update(dict(**props, id="table1"))
    baseProps2.update(dict(**props, id="table2"))

    app.layout = Div(
        [
            DataTable(**baseProps1),
            DataTable(**baseProps2),
        ]
    )

    test.start_server(app)

    table2 = test.table("table2")

    for i in range(len(baseProps1.get("columns"))):
        table2.cell(0, i).click()

        t1 = test.driver.find_element_by_css_selector("#table1")
        t2 = test.driver.find_element_by_css_selector("#table2")

        cells_are_same_width(t1, t1)
        cells_are_same_width(t1, t2)

    assert test.get_log_errors() == []
예제 #3
0
파일: test_empty.py 프로젝트: plotly/dash
def get_app():
    app = dash.Dash(__name__)

    columns = [{"name": i, "id": i} for i in ["a", "b"]]
    data = [dict(a=1, b=2), dict(a=11, b=22)]

    app.layout = Div(
        [
            Button(id="clear-table", children=["Clear table"]),
            DataTable(id="table", columns=columns, data=data),
        ]
    )

    @app.callback(
        [Output("table", "data"), Output("table", "columns")],
        [Input("clear-table", "n_clicks")],
    )
    def clear_table(n_clicks):
        if n_clicks is None:
            raise PreventUpdate

        nonlocal columns, data

        return (data, columns) if n_clicks % 2 == 0 else (None, None)

    return app
예제 #4
0
def szng003_on_prop_change_impl(
    test, fixed_columns, fixed_rows, merge_duplicate_headers, callback_props
):
    props = {**base_props, **fixed_columns, **fixed_rows, **merge_duplicate_headers}

    table = DataTable(**props, id="table")

    app = dash.Dash(__name__)
    app.layout = Div([Button(id="btn", children=["Update"]), table])

    @app.callback(
        [Output("table", key) for key in callback_props.keys()],
        [Input("btn", "n_clicks")],
        prevent_initial_call=True,
    )
    def callback(n_clicks):
        return [callback_props.get(key) for key in callback_props.keys()]

    test.start_server(app)

    target = test.driver.find_element_by_css_selector("#table")
    cells_are_same_width(target, target)

    test.driver.find_element_by_css_selector("#btn").click()
    cells_are_same_width(target, target)

    assert test.get_log_errors() == []
예제 #5
0
def test_gene001_simple_callback(dash_duo):
    app = Dash(__name__)

    app.layout = Div(
        [
            # Note: `value` is not part of the explicit function signature
            # for MyStandardComponent, due to --max-props 2 in its build command
            # but this verifies that it still works.
            MyStandardComponent(id="standard", value="Standard"),
            MyNestedComponent(id="nested", value="Nested"),
            TypeScriptComponent(id="typescript", required_string="TypeScript"),
            TypeScriptClassComponent(id="typescript-class",
                                     required_string="TypeScriptClass"),
            StandardComponent(id="ts-standard", children="jsx"),
        ],
        id="outer",
    )

    dash_duo.start_server(app)

    assert dash_duo.wait_for_element("#standard").text == "Standard"
    assert dash_duo.wait_for_element("#nested").text == "Nested"
    assert dash_duo.wait_for_element("#typescript").text == "TypeScript"
    assert dash_duo.wait_for_element(
        "#typescript-class").text == "TypeScriptClass"
    assert dash_duo.wait_for_element("#ts-standard").text == "jsx"
    expected_html = (
        '<div id="standard">Standard</div>'
        '<div id="nested">Nested</div>'
        '<div id="typescript">TypeScript</div>'
        '<div class="typescript-class-component" id="typescript-class">TypeScriptClass</div>'
        '<div id="ts-standard">jsx</div>')
    assert dash_duo.find_element("#outer").get_property(
        "innerHTML") == expected_html
예제 #6
0
def update_table(n) -> Div:
    """ """
    MQTT_CLIENT.loop()

    compute_machines = []

    if GPU_STATS:
        df = to_overall_gpu_process_df(copy.deepcopy(GPU_STATS))
    else:
        df = DataFrame(["No data"], columns=("data", ))

    compute_machines.append(
        DataTable(
            id="gpu-table-0",
            columns=[{
                "name": i,
                "id": i
            } for i in df.columns],
            data=df.to_dict("records"),
            page_size=ALL_CONSTANTS.TABLE_PAGE_SIZE,
            # style_as_list_view=True,
            style_data_conditional=[{
                "if": {
                    "row_index": "odd"
                },
                "backgroundColor": "rgb(248, 248, 248)"
            }],
            style_header={
                "backgroundColor": "rgb(230, 230, 230)",
                "fontWeight": "bold",
            },
        ))

    return Div(compute_machines)
예제 #7
0
def test_gene001_simple_callback(dash_duo):
    app = Dash(__name__)

    app.layout = Div([
        # Note: `value` is not part of the explicit function signature
        # for MyStandardComponent, due to --max-props 2 in its build command
        # but this verifies that it still works.
        MyStandardComponent(id="standard", value="Standard"),
        MyNestedComponent(id="nested", value="Nested"),
        TypeScriptComponent(id="typescript", required_string="TypeScript"),
        TypeScriptClassComponent(id="typescript-class",
                                 required_string="TypeScriptClass"),
        StandardComponent(id="ts-standard", children="jsx"),
    ])

    dash_duo.start_server(app)

    assert dash_duo.wait_for_element("#standard").text == "Standard"
    assert dash_duo.wait_for_element("#nested").text == "Nested"
    assert dash_duo.wait_for_element("#typescript").text == "TypeScript"
    assert dash_duo.wait_for_element(
        "#typescript-class").text == "TypeScriptClass"
    assert dash_duo.wait_for_element("#ts-standard").text == "jsx"

    dash_duo.percy_snapshot(name="gene001-simple-callback")
예제 #8
0
파일: test_sizing.py 프로젝트: plotly/dash
def test_szng002_percentages_result_in_same_widths(test):
    _fixed_columns = [dict(headers=True, data=1), dict(headers=True)]
    _fixed_rows = [dict(headers=True, data=1), dict(headers=True)]
    _merge_duplicate_headers = [True, False]

    variations = []
    i = 0
    for fixed_columns in _fixed_columns:
        for fixed_rows in _fixed_rows:
            for merge_duplicate_headers in _merge_duplicate_headers:
                variations.append({
                    **base_props,
                    "fixed_columns": fixed_columns,
                    "fixed_rows": fixed_rows,
                    "merge_duplicate_headers": merge_duplicate_headers,
                    "id": "table{}".format(i),
                })
                i = i + 1

    tables = [DataTable(**variation) for variation in variations]

    app = dash.Dash(__name__)
    app.layout = Div(tables)

    test.start_server(app)

    cells_are_same_width(test, "#table0", "#table0")

    for i in range(1, len(variations)):
        cells_are_same_width(test, "#table0", "#table{}".format(i))

    assert test.get_log_errors() == []
예제 #9
0
def update_graph(n) -> Div:
    """ """
    global GPU_STATS
    global KEEP_ALIVE
    compute_machines = []
    if GPU_STATS:
        compute_machines.extend(
            per_machine_per_device_pie_charts(copy.deepcopy(GPU_STATS),
                                              KEEP_ALIVE))
    return Div(compute_machines)
예제 #10
0
def test_gene001_simple_callback(dash_duo):
    app = Dash(__name__)

    app.layout = Div([
        MyStandardComponent(id="standard", value="Standard"),
        MyNestedComponent(id="nested", value="Nested"),
    ])

    dash_duo.start_server(app)

    assert dash_duo.wait_for_element("#standard").text == "Standard"
    assert dash_duo.wait_for_element("#nested").text == "Nested"

    dash_duo.percy_snapshot(name="gene001-simple-callback")
예제 #11
0
def test_ddvi001_fixed_table(dash_duo):
    app = Dash(__name__)
    app.layout = Div([
        Dropdown(
            id="dropdown",
            options=[
                {
                    "label": "New York City",
                    "value": "NYC"
                },
                {
                    "label": "Montreal",
                    "value": "MTL"
                },
                {
                    "label": "San Francisco",
                    "value": "SF"
                },
            ],
            value="NYC",
        ),
        DataTable(
            id="table",
            columns=[{
                "name": x,
                "id": x,
                "selectable": True
            } for x in ["a", "b", "c"]],
            editable=True,
            row_deletable=True,
            fixed_rows=dict(headers=True),
            fixed_columns=dict(headers=True),
            data=[{
                "a": "a" + str(x),
                "b": "b" + str(x),
                "c": "c" + str(x)
            } for x in range(0, 20)],
        ),
    ])

    dash_duo.start_server(app)

    dash_duo.find_element("#dropdown").click()
    dash_duo.wait_for_element("#dropdown .Select-menu-outer")

    dash_duo.percy_snapshot(
        "dcc.Dropdown dropdown overlaps table fixed rows/columns")

    assert dash_duo.get_logs() == []
예제 #12
0
def get_app(props=dict(), special=False, clear=False):
    app = dash.Dash(__name__)

    baseProps = get_props(rows=200)

    if special:
        for c in baseProps.get("columns"):
            if c["id"] == "bbb":
                c["id"] = "b+bb"
            elif c["id"] == "ccc":
                c["id"] = "c cc"
            elif c["id"] == "ddd":
                c["id"] = "d:dd"
            elif c["id"] == "eee":
                c["id"] = "e-ee"
            elif c["id"] == "fff":
                c["id"] = "f_ff"
            elif c["id"] == "ggg":
                c["id"] = "g.gg"

        for i in range(len(baseProps["data"])):
            d = baseProps["data"][i]
            d["b+bb"] = d["bbb"]
            d["c cc"] = d["ccc"]
            d["d:dd"] = d["ddd"]
            d["e-ee"] = d["eee"]
            d["f_ff"] = d["fff"]
            d["g.gg"] = d["ggg"]

    baseProps.update(dict(filter_action="native"))
    baseProps.update(props)

    if clear:
        app.layout = Div([
            DataTable(**baseProps),
            Button(id="btn", children=["Clear filters"])
        ])

        @app.callback(Output("table", "filter_query"),
                      Input("btn", "n_clicks"))
        def get_filter(n_clicks):
            return ""

    else:
        app.layout = DataTable(**baseProps)

    return app
예제 #13
0
def get_app(props=dict()):
    app = dash.Dash(__name__)

    baseProps = dict(
        columns=[dict(name=i, id=i, selectable=True) for i in rawDf.columns],
        data=df,
        editable=True,
        filter_action="native",
        fixed_columns={"headers": True},
        fixed_rows={"headers": True},
        page_action="native",
        row_deletable=True,
        row_selectable=True,
        sort_action="native",
    )

    baseProps.update(props)

    app.layout = Div([DataTable(**baseProps), DataTable(**baseProps)])

    return app
예제 #14
0
def per_machine_per_device_pie_charts(gpu_stats: Mapping,
                                      keep_alive: Sequence[Number]):
    """ """
    compute_machines = []
    for machine_name, machine in gpu_stats.items():
        machine_devices = []
        devices = machine["devices"]

        for i, d in enumerate(devices):

            used = d["used"] // MB_DIVISOR
            total = d["total"] // MB_DIVISOR

            used_ratio = used / total
            used_ratio = [used_ratio] + [1.0 - used_ratio]

            hover_text = [f"used:{used:.0f}mb", f"free:{total - used:.0f}mb"]

            machine_devices.append(
                Div(
                    [
                        Graph(
                            id=f"gpu_stats_{machine_name}{i}",
                            figure={
                                "data": [
                                    graph_objs.Pie(
                                        values=used_ratio,
                                        text=hover_text,
                                        name="used ratio",
                                        hole=0.4,
                                    )
                                ],
                                "layout":
                                graph_objs.Layout(
                                    title=f"{d['name']} cuda_idx:{d['id']}",
                                    showlegend=False,
                                    hovermode="closest",
                                ),
                            },
                            style={
                                "width": "100%",
                            },
                        )
                    ],
                    className="col",
                ))
        compute_machines.append(
            Div(
                [
                    H3(
                        f"{machine_name}: {keep_alive[machine_name]} sec ago",
                        className="text-monospace",
                        style={"text-decoration": "underline"},
                    ),
                    Div([*machine_devices], className="row"),
                ],
                style={
                    "text-align": "center",
                    "width": "100%",
                },
            ))
    return compute_machines
예제 #15
0
def test_szng001_widths_on_style_change(test):
    base_props = dict(
        data=[
            {"a": 85, "b": 601, "c": 891},
            {"a": 967, "b": 189, "c": 514},
            {"a": 398, "b": 262, "c": 743},
            {"a": 89, "b": 560, "c": 582},
            {"a": 809, "b": 591, "c": 511},
        ],
        columns=[
            {"id": "a", "name": "A"},
            {"id": "b", "name": "B"},
            {"id": "c", "name": "C"},
        ],
        style_data={
            "width": 100,
            "minWidth": 100,
            "maxWidth": 100,
            "border": "1px solid blue",
        },
        row_selectable="single",
        row_deletable=True,
    )

    styles = [
        dict(
            style_table=dict(
                width=500, minWidth=500, maxWidth=500, paddingBottom=10, display="none"
            )
        ),
        dict(style_table=dict(width=500, minWidth=500, maxWidth=500, paddingBottom=10)),
        dict(style_table=dict(width=750, minWidth=750, maxWidth=750, paddingBottom=10)),
        dict(
            style_table=dict(
                width=750, minWidth=750, maxWidth=750, paddingBottom=10, display="none"
            )
        ),
        dict(style_table=dict(width=350, minWidth=350, maxWidth=350, paddingBottom=10)),
    ]

    fixes = [
        dict(),
        dict(fixed_columns=dict(headers=True)),
        dict(fixed_rows=dict(headers=True)),
        dict(fixed_columns=dict(headers=True), fixed_rows=dict(headers=True)),
        dict(fixed_columns=dict(headers=True, data=1)),
        dict(fixed_rows=dict(headers=True, data=1)),
        dict(
            fixed_columns=dict(headers=True, data=1),
            fixed_rows=dict(headers=True, data=1),
        ),
    ]

    variations = []
    style = styles[0]
    i = 0
    for fix in fixes:
        variations.append({**style, **fix, **base_props, "id": "table{}".format(i)})
        i = i + 1

    variations_range = range(0, len(variations))

    tables = [DataTable(**variation) for variation in variations]

    app = dash.Dash(__name__)
    app.layout = Div(
        children=[
            Button(id="btn", children="Click me"),
            Div(
                [
                    DataTable(
                        **base_props,
                        id="table{}".format(width),
                        style_table=dict(
                            width=width,
                            minWidth=width,
                            maxWidth=width,
                            paddingBottom=10,
                        )
                    )
                    for width in [350, 500, 750]
                ]
            ),
            Div(tables),
        ]
    )

    @app.callback(
        [Output("table{}".format(i), "style_table") for i in variations_range],
        [Input("btn", "n_clicks")],
        prevent_initial_call=True,
    )
    def update_styles(n_clicks):
        if n_clicks < len(styles):
            style_table = styles[n_clicks]["style_table"]
            return [style_table for i in variations_range]
        else:
            raise PreventUpdate

    test.start_server(app)

    for style in styles:
        display = style.get("style_table", dict()).get("display")
        width = style.get("style_table", dict()).get("width")
        target = (
            test.driver.find_element_by_css_selector("#table{}".format(width))
            if display != "none"
            else None
        )

        for variation in variations:
            table = test.driver.find_element_by_css_selector(
                "#{}".format(variation["id"])
            )
            if target is None:
                assert table is not None
                assert (
                    test.driver.execute_script(
                        "return getComputedStyle(document.querySelector('#{} .dash-spreadsheet-container')).display".format(
                            variation["id"]
                        )
                    )
                    == "none"
                )
            else:
                cells_are_same_width(target, table)

        test.driver.find_element_by_css_selector("#btn").click()

    assert test.get_log_errors() == []
예제 #16
0
import pytest

from dash import Output
from dash.html import Div
from dash.exceptions import InvalidCallbackReturnValue
from dash._validate import fail_callback_output


@pytest.mark.parametrize(
    "val",
    [
        {0},
        [{1}, 1],
        [1, {2}],
        Div({3}),
        Div([{4}]),
        Div(style={5}),
        Div([1, {6}]),
        Div([1, Div({7})]),
        [Div({8}), 1],
        [1, Div({9})],
        [Div(Div({10}))],
        [Div(Div({11})), 1],
        [1, Div(Div({12}))],
        {
            "a": {13}
        },
        Div(style={"a": {14}}),
        Div(style=[{15}]),
        [1, Div(style=[{16}])],
    ],