Ejemplo n.º 1
0
def test_inin_024_port_env_success(dash_duo):
    app = Dash(__name__)
    app.layout = html.Div("hi", "out")
    dash_duo.start_server(app, port="12345")
    assert dash_duo.server_url == "http://localhost:12345"
    dash_duo.wait_for_text_to_equal("#out", "hi")
Ejemplo n.º 2
0
# This Code was written by Ann Marie - a Plotly Forum Moderator
from dash import Dash, dcc, html, Input, Output, dash_table, no_update  # Dash version >= 2.0.0
import plotly.express as px

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = Dash(__name__, external_stylesheets=external_stylesheets)

df = px.data.gapminder()
df["id"] = df.index
# print(df.head(15))
dff = df[df.year == 2007]
columns = ["country", "continent", "lifeExp", "pop", "gdpPercap"]
color = {"lifeExp": "#636EFA", "pop": "#EF553B", "gdpPercap": "#00CC96"}
initial_active_cell = {
    "row": 0,
    "column": 0,
    "column_id": "country",
    "row_id": 0
}

app.layout = html.Div([
    html.Div([
        html.H3("2007 Gap Minder", style={"textAlign": "center"}),
        dash_table.DataTable(
            id="table",
            columns=[{
                "name": c,
                "id": c
            } for c in columns],
            data=dff.to_dict("records"),
Ejemplo n.º 3
0
def test_clsd011_clientside_callback_context_inputs_list(dash_duo):
    app = Dash(__name__, assets_folder="clientside_assets")

    app.layout = html.Div([
        html.Button("btn0", id="btn0"),
        html.Button("btn1:0", id={"btn1": 0}),
        html.Button("btn1:1", id={"btn1": 1}),
        html.Button("btn1:2", id={"btn1": 2}),
        html.Div(id="output-clientside", style={"font-family": "monospace"}),
    ])

    app.clientside_callback(
        ClientsideFunction(namespace="clientside",
                           function_name="inputs_list_to_str"),
        Output("output-clientside", "children"),
        [Input("btn0", "n_clicks"),
         Input({"btn1": ALL}, "n_clicks")],
    )

    class DashView(BaseDashView):
        dash = app

    dash_duo.start_server(DashView)

    dash_duo.wait_for_text_to_equal(
        "#output-clientside",
        ('[{"id":"btn0","property":"n_clicks"},'
         '[{"id":{"btn1":0},"property":"n_clicks"},'
         '{"id":{"btn1":1},"property":"n_clicks"},'
         '{"id":{"btn1":2},"property":"n_clicks"}]]'),
    )

    dash_duo.find_element("#btn0").click()

    dash_duo.wait_for_text_to_equal(
        "#output-clientside",
        ('[{"id":"btn0","property":"n_clicks","value":1},'
         '[{"id":{"btn1":0},"property":"n_clicks"},'
         '{"id":{"btn1":1},"property":"n_clicks"},'
         '{"id":{"btn1":2},"property":"n_clicks"}]]'),
    )

    dash_duo.find_element("button[id*='btn1\":0']").click()
    dash_duo.find_element("button[id*='btn1\":0']").click()

    dash_duo.wait_for_text_to_equal(
        "#output-clientside",
        ('[{"id":"btn0","property":"n_clicks","value":1},'
         '[{"id":{"btn1":0},"property":"n_clicks","value":2},'
         '{"id":{"btn1":1},"property":"n_clicks"},'
         '{"id":{"btn1":2},"property":"n_clicks"}]]'),
    )

    dash_duo.find_element("button[id*='btn1\":2']").click()

    dash_duo.wait_for_text_to_equal(
        "#output-clientside",
        ('[{"id":"btn0","property":"n_clicks","value":1},'
         '[{"id":{"btn1":0},"property":"n_clicks","value":2},'
         '{"id":{"btn1":1},"property":"n_clicks"},'
         '{"id":{"btn1":2},"property":"n_clicks","value":1}]]'),
    )
# flask run

import inspect, os
#os.environ["FLASK_APP"] = inspect.getfile(inspect.currentframe())
os.environ[
    "OCTAVE_EXECUTABLE"] = "C:\\Octave\\Octave-4.2.2\\bin\\octave-cli.exe"

from oct2py import octave
from flask import Flask
from dash import Dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_core_components as dcc

flask_app = Flask(__name__)
dash_app = Dash(__name__, server=flask_app)

filepath = 'C:\\Users\\SEC\\Documents\\Alperia\\HydroptModel\\vsm.mod'
octave.eval("load('" + filepath + "', '-mat')")
globalData = octave.pull('Data')

dash_app.layout = html.Div(id='page-content',
                           children=[dcc.Location(id='url', refresh=False)])


@dash_app.callback(Output('page-content', 'children'),
                   [Input('url', 'pathname')])
def display_page(pathname):
    return dash_router(pathname)

Ejemplo n.º 5
0
import os
import pandas as pd
from flask import Flask
from dash import Dash, dcc
from flask_sqlalchemy import SQLAlchemy
import plotly.graph_objects as go
from utils import stancecolormap, stancemap

app = Flask(__name__)
dashapp = Dash(__name__, server=app, url_base_pathname='/plots/')
app.config.from_object(os.environ['APP_SETTINGS'])
db = SQLAlchemy(app)

custom_font = dict(family="Courier New, monospace", size=14, color="#000000")

df = pd.read_pickle('preds.pkl')[:10000]
fig = go.Figure(
    data=[
        go.Scatter(x=df['h_pos'][df['actual'] == stance],
                   y=df['v_pos'][df['actual'] == stance],
                   mode='markers',
                   marker_color=stancecolormap.get(stance),
                   opacity=0.6,
                   name=stance)
        for stance in sorted(stancemap.keys(), reverse=True)
    ],
    layout=go.Layout(
        # title='Stances',
        margin=go.layout.Margin(l=0, r=0, b=8, t=8),
        autosize=True,
        plot_bgcolor="rgba(0, 10, 25, 0.3)",
Ejemplo n.º 6
0
def Add_Dash(server):
    """Create a Dash app."""
    external_stylesheets = [
        '/static/dist/css/styles.css',
        'https://fonts.googleapis.com/css?family=Lato',
        'https://use.fontawesome.com/releases/v5.8.1/css/all.css'
    ]
    external_scripts = [
        '/static/dist/js/includes/jquery.min.js', '/static/dist/js/main.js'
    ]
    dash_app = Dash(server=server,
                    external_stylesheets=external_stylesheets,
                    external_scripts=external_scripts,
                    routes_pathname_prefix='/followers/')

    # Override the underlying HTML template
    dash_app.index_string = html_layout

    # Add Cassandra Queries and Parameters
    # Pass this as a dictionary of parameters, hidden in a function

    x_name = 'timestamp'
    y_name = 'follower_count'

    cluster = Cluster(['10.0.0.5', '10.0.0.7', '10.0.0.12', '10.0.0.19'])
    session = cluster.connect()
    session.set_keyspace('insight')
    session.row_factory = lambda x, y: pd.DataFrame(y, columns=x)
    session.default_fetch_size = 100000

    prepared_query_youtube_live = session.prepare(
        "select timestamp, follower_count from youtube_live "
        "where streamer=?")
    prepared_query_twitter_live = session.prepare(
        "select timestamp, follower_count from twitter_live "
        "where streamer=?")
    prepared_query_twitch_live = session.prepare(
        "select timestamp, follower_count from twitch_live "
        "where streamer=?")

    prepared_query_day = session.prepare(
        "select timestamp, twitch_count, twitter_count, youtube_count, total_count "
        "from unified_day where streamer=?")
    prepared_query_hour = session.prepare(
        "select timestamp, twitch_count, twitter_count, youtube_count, total_count "
        "from unified_hour where streamer=?")
    prepared_query_minute = session.prepare(
        "select timestamp, twitch_count, twitter_count, youtube_count, total_count "
        "from unified_minute where streamer=?")

    prepared_query_accounts = session.prepare(
        "select streamer from insight.accounts;")

    # Get streamers names, and prepare the dropdown options

    streamers = session.execute(prepared_query_accounts)._current_rows

    dropdown_options = [{
        'label': streamer,
        'value': streamer
    } for streamer in streamers.streamer]

    # Create Dash Layout comprised of Graphs
    dash_app.layout = html.Div(children=get_followers(dropdown_options),
                               id='dash-container')

    # Initialize callbacks after our app is loaded
    # Pass dash_app as a parameter

    init_callbacks(dash_app, session, x_name, y_name, prepared_query_day,
                   prepared_query_hour, prepared_query_minute,
                   prepared_query_youtube_live, prepared_query_twitter_live,
                   prepared_query_twitch_live)

    return dash_app.server
Ejemplo n.º 7
0
def test_rdrh001_request_hooks(dash_duo):
    app = Dash(__name__)

    app.index_string = """<!DOCTYPE html>
    <html>
        <head>
            {%metas%}
            <title>{%title%}</title>
            {%favicon%}
            {%css%}
        </head>
        <body>
            <div id="top">Testing custom DashRenderer</div>
            {%app_entry%}
            <footer>
                {%config%}
                {%scripts%}
                <script id="_dash-renderer" type"application/json">
                    const renderer = new DashRenderer({
                        request_pre: (payload) => {
                            var output = document.getElementById('output-pre')
                            var outputPayload = document.getElementById('output-pre-payload')
                            if(output) {
                                output.innerHTML = 'request_pre changed this text!';
                            }
                            if(outputPayload) {
                                outputPayload.innerHTML = JSON.stringify(payload);
                            }
                        },
                        request_post: (payload, response) => {
                            var output = document.getElementById('output-post')
                            var outputPayload = document.getElementById('output-post-payload')
                            var outputResponse = document.getElementById('output-post-response')
                            if(output) {
                                output.innerHTML = 'request_post changed this text!';
                            }
                            if(outputPayload) {
                                outputPayload.innerHTML = JSON.stringify(payload);
                            }
                            if(outputResponse) {
                                outputResponse.innerHTML = JSON.stringify(response);
                            }
                        }
                    })
                </script>
            </footer>
            <div id="bottom">With request hooks</div>
        </body>
    </html>"""

    app.layout = html.Div([
        dcc.Input(id="input", value="initial value"),
        html.Div(
            html.Div([
                html.Div(id="output-1"),
                html.Div(id="output-pre"),
                html.Div(id="output-pre-payload"),
                html.Div(id="output-post"),
                html.Div(id="output-post-payload"),
                html.Div(id="output-post-response"),
            ])),
    ])

    @app.callback(Output("output-1", "children"), [Input("input", "value")])
    def update_output(value):
        return value

    dash_duo.start_server(app)

    _in = dash_duo.find_element("#input")
    dash_duo.clear_input(_in)

    _in.send_keys("fire request hooks")

    dash_duo.wait_for_text_to_equal("#output-1", "fire request hooks")
    dash_duo.wait_for_text_to_equal("#output-pre",
                                    "request_pre changed this text!")
    dash_duo.wait_for_text_to_equal("#output-post",
                                    "request_post changed this text!")

    assert json.loads(dash_duo.find_element("#output-pre-payload").text) == {
        "output":
        "output-1.children",
        "outputs": {
            "id": "output-1",
            "property": "children"
        },
        "changedPropIds": ["input.value"],
        "inputs": [{
            "id": "input",
            "property": "value",
            "value": "fire request hooks"
        }],
    }

    assert json.loads(dash_duo.find_element("#output-post-payload").text) == {
        "output":
        "output-1.children",
        "outputs": {
            "id": "output-1",
            "property": "children"
        },
        "changedPropIds": ["input.value"],
        "inputs": [{
            "id": "input",
            "property": "value",
            "value": "fire request hooks"
        }],
    }

    assert json.loads(dash_duo.find_element("#output-post-response").text) == {
        "output-1": {
            "children": "fire request hooks"
        }
    }

    assert dash_duo.find_element("#top").text == "Testing custom DashRenderer"
    assert dash_duo.find_element("#bottom").text == "With request hooks"

    assert dash_duo.get_logs() == []
Ejemplo n.º 8
0
import dash_html_components as html
import dash_core_components as dcc

from flask import Flask
from dash import Dash
from flask_sqlalchemy import SQLAlchemy

# initialize flask app
APP = Flask(__name__)
APP.config["SQLALCHEMY_DATABASE_URI"] = config("DATABASE_URL")

# initialize dash, for visualizations
DASH = Dash(
    __name__,
    server=APP,
    external_stylesheets=[
        "/css/style.css",
    ],
    url_base_pathname="/plot/",
)
DASH.layout = html.Div(
    [
        dcc.Location(id="url", refresh=False),
        dcc.Graph(id="main-graph", style={
            "height": "100%",
            "width": "100%"
        }),
    ],
    id="page-content",
    style={
        "height": "100%",
        "width": "100%"
Ejemplo n.º 9
0
from dash import Dash
from dash.components import *

from userguide import app, const

dash = Dash(server=app, url_namespace='/{}'.format(const['text-input']))

dash.layout = div(
    [div(id="app"),
     hr(), Highlight(id="code", className="python")],
    className="container")

app_template = '''from dash import Dash
from dash.components import *
{}

dash = Dash(__name__)
dash.layout = {}

{}

if __name__ == "__main__":
    dash.server.run(debug=True)
'''

preamble = '''import pandas as pd
import pandas_datareader.data as web
import datetime as dt
import traceback

# list of tickers
Ejemplo n.º 10
0
def test_dada002_external_files_init(dash_duo):
    js_files = [
        "https://www.google-analytics.com/analytics.js",
        {"src": "https://cdn.polyfill.io/v2/polyfill.min.js"},
        {
            "src": "https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js",
            "integrity": "sha256-43x9r7YRdZpZqTjDT5E0Vfrxn1ajIZLyYWtfAXsargA=",
            "crossorigin": "anonymous",
        },
        {
            "src": "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js",
            "integrity": "sha256-7/yoZS3548fXSRXqc/xYzjsmuW3sFKzuvOCHd06Pmps=",
            "crossorigin": "anonymous",
        },
    ]

    css_files = [
        "https://codepen.io/chriddyp/pen/bWLwgP.css",
        {
            "href": "https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css",
            "rel": "stylesheet",
            "integrity": "sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO",
            "crossorigin": "anonymous",
        },
    ]

    app = Dash(__name__, external_scripts=js_files, external_stylesheets=css_files)

    app.index_string = """<!DOCTYPE html>
    <html>
        <head>
            {%metas%}
            <title>{%title%}</title>
            {%css%}
        </head>
        <body>
            <div id="tested"></div>
            <div id="ramda-test"></div>
            <button type="button" id="btn">Btn</button>
            {%app_entry%}
            <footer>
                {%config%}
                {%scripts%}
                {%renderer%}
            </footer>
        </body>
    </html>"""

    app.layout = html.Div()

    dash_duo.start_server(app)

    js_urls = [x["src"] if isinstance(x, dict) else x for x in js_files]
    css_urls = [x["href"] if isinstance(x, dict) else x for x in css_files]

    for fmt, url in itertools.chain(
        (("//script[@src='{}']", x) for x in js_urls),
        (("//link[@href='{}']", x) for x in css_urls),
    ):
        dash_duo.driver.find_element_by_xpath(fmt.format(url))

    assert (
        dash_duo.find_element("#btn").value_of_css_property("height") == "18px"
    ), "Ensure the button style was overloaded by reset (set to 38px in codepen)"

    # ensure ramda was loaded before the assets so they can use it.
    assert dash_duo.find_element("#ramda-test").text == "Hello World"
Ejemplo n.º 11
0
from dash import Dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd

df = px.data.iris()
fig = px.scatter(df,
                 x="sepal_width",
                 y="sepal_length",
                 color="species",
                 size='petal_length',
                 hover_data=['petal_width'])
#simulates two different dash apps
#requests pathname prefix tells the dash renderer where to look and request data

#dummy app 1
app1 = Dash(__name__, requests_pathname_prefix='/app1/')

app1.layout = html.Div([html.H1('App 1'), dcc.Graph(id='id', figure=fig)])

if __name__ == '__main__':
    app1.run_server(debug=True)
Ejemplo n.º 12
0
    return content

regions = {
    'world': {'lat': 0, 'lon': 0, 'zoom': 1},
    'europe': {'lat': 50, 'lon': 0, 'zoom': 3},
    'north_america': {'lat': 40, 'lon': -100, 'zoom': 2},
    'south_america': {'lat': -15, 'lon': -60, 'zoom': 2},
    'africa': {'lat': 0, 'lon': 20, 'zoom': 2},
    'asia': {'lat': 30, 'lon': 100, 'zoom': 2},
    'oceania': {'lat': -10, 'lon': 130, 'zoom': 2},
}

app_name = 'Real-time Global Earthquake Data Map'
server = Flask(app_name)
server.secret_key = os.environ.get('SECRET_KEY', 'default-secret-key')
app = Dash(name=app_name, server=server)

app.index_string = '''
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        {%metas%}
        <title>HalcyonAgri Digitization Dashboard | Real-time Global Earthquake Data Map</title>
        {%favicon%}
        {%css%}
    </head>
    <body>
        <nav class="navbar navbar-inverse">
        <div class="container-fluid">
          <div class="navbar-header">
Ejemplo n.º 13
0
# -*- coding: utf-8 -*-
from dash import Dash
from flask import Flask, send_from_directory

server = Flask(__package__)

# load default settings
server.config.from_object(f'{__package__}.settings')

# load additional settings that will override the defaults in settings.py. eg
# $ export SLAPDASH_SETTINGS=/some/path/prod_settings.py
server.config.from_envvar('HVODASH_SETTINGS', silent=True)

app = Dash(
    __package__,
    server=server,
    # url_base_pathname=server.config['URL_BASE_PATHNAME']
)

# We need to suppress validations as we will be initialising callbacks
# that target element IDs that won't yet occur in the layout.
app.config.supress_callback_exceptions = True
app.config.update({
    'routes_pathname_prefix': '/',
    'requests_pathname_prefix': '/dash/'
})


@server.route('/favicon.ico')
def favicon():
    """Serve the favicon"""
Ejemplo n.º 14
0
def test_inin026_graphs_in_tabs_do_not_share_state(dash_duo):
    app = Dash(__name__, suppress_callback_exceptions=True)

    app.layout = html.Div([
        dcc.Tabs(
            id="tabs",
            children=[
                dcc.Tab(label="Tab 1", value="tab1", id="tab1"),
                dcc.Tab(label="Tab 2", value="tab2", id="tab2"),
            ],
            value="tab1",
        ),
        # Tab content
        html.Div(id="tab_content"),
    ])
    tab1_layout = [
        html.Div([
            dcc.Graph(
                id="graph1",
                figure={
                    "data": [{
                        "x": [1, 2, 3],
                        "y": [5, 10, 6],
                        "type": "bar"
                    }]
                },
            )
        ]),
        html.Pre(id="graph1_info"),
    ]

    tab2_layout = [
        html.Div([
            dcc.Graph(
                id="graph2",
                figure={
                    "data": [{
                        "x": [4, 3, 2],
                        "y": [5, 10, 6],
                        "type": "bar"
                    }]
                },
            )
        ]),
        html.Pre(id="graph2_info"),
    ]

    @app.callback(Output("graph1_info", "children"),
                  Input("graph1", "clickData"))
    def display_hover_data(hover_data):
        return json.dumps(hover_data)

    @app.callback(Output("graph2_info", "children"),
                  Input("graph2", "clickData"))
    def display_hover_data_2(hover_data):
        return json.dumps(hover_data)

    @app.callback(Output("tab_content", "children"), Input("tabs", "value"))
    def render_content(tab):
        return tab2_layout if tab == "tab2" else tab1_layout

    dash_duo.start_server(app)

    dash_duo.find_element("#graph1:not(.dash-graph--pending)").click()

    until(lambda: '"label": 2' in dash_duo.find_element("#graph1_info").text,
          timeout=3)

    dash_duo.find_element("#tab2").click()

    dash_duo.find_element("#graph2:not(.dash-graph--pending)").click()

    until(lambda: '"label": 3' in dash_duo.find_element("#graph2_info").text,
          timeout=3)
Ejemplo n.º 15
0
# Prepare static data to load into application
# Realtime data please refer to https://dash.plot.ly/live-updates
# Iframe https://community.plot.ly/t/embedding-dash-into-webpage/10645/3

# cavity,clashdiff,hbond,localclash,sbond,sbridge,Mean,SD

# CSS
external_stylesheets = [
    'https://codepen.io/chriddyp/pen/bWLwgP.css', '/static/main.css'
]

# Setting up flask server and dash applications
server = flask.Flask(__name__)
dash_app1 = Dash(__name__,
                 server=server,
                 url_base_pathname='/leaderboard',
                 external_stylesheets=external_stylesheets)
dash_app2 = Dash(__name__,
                 server=server,
                 url_base_pathname='/orderbook',
                 external_stylesheets=external_stylesheets)

dash_app1.layout = html.Div(children=[
    html.H1(children='Hello Dash'),
    html.Div(children='''
        Dash: A web application framework for Python.
    '''),
    dcc.Graph(id='example-graph',
              figure={
                  'data': [
                      {
Ejemplo n.º 16
0
url_base_pathname = '/publisher-dash'

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

# dash-leaflet uses it
external_scripts = ['https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.1.0/chroma.min.js']

server = Flask(__name__)


@server.route('/')
def index():
    # redirect from `/` to `url_base_pathname`
    return redirect(f'{url_base_pathname}')


@server.route('/<bad_link>')
def redirect_to_index(bad_link):
    # if the user types an invalid link, then it redirects him to `url_base_pathname`
    return redirect(f'{url_base_pathname}')


app = Dash(
    __name__,
    server=server,
    external_stylesheets=external_stylesheets,
    external_scripts=external_scripts,
    suppress_callback_exceptions=True,
    url_base_pathname='{}/'.format(url_base_pathname)
)
Ejemplo n.º 17
0
def test_cbmt011_callbacks_triggered_on_generated_output(dash_duo):
    app = Dash(__name__, suppress_callback_exceptions=True)

    call_counts = {"tab1": Value("i", 0), "tab2": Value("i", 0)}

    app.layout = html.Div([
        dcc.Dropdown(
            id="outer-controls",
            options=[{
                "label": i,
                "value": i
            } for i in ["a", "b"]],
            value="a",
        ),
        dcc.RadioItems(
            options=[
                {
                    "label": "Tab 1",
                    "value": 1
                },
                {
                    "label": "Tab 2",
                    "value": 2
                },
            ],
            value=1,
            id="tabs",
        ),
        html.Div(id="tab-output"),
    ])

    @app.callback(Output("tab-output", "children"), Input("tabs", "value"))
    def display_content(value):
        return html.Div([html.Div(id="tab-{}-output".format(value))])

    @app.callback(Output("tab-1-output", "children"),
                  Input("outer-controls", "value"))
    def display_tab1_output(value):
        call_counts["tab1"].value += 1
        return 'Selected "{}" in tab 1'.format(value)

    @app.callback(Output("tab-2-output", "children"),
                  Input("outer-controls", "value"))
    def display_tab2_output(value):
        call_counts["tab2"].value += 1
        return 'Selected "{}" in tab 2'.format(value)

    dash_duo.start_server(app)

    dash_duo.wait_for_text_to_equal("#tab-output", 'Selected "a" in tab 1')
    dash_duo.wait_for_text_to_equal("#tab-1-output", 'Selected "a" in tab 1')
    assert call_counts["tab1"].value == 1
    assert call_counts["tab2"].value == 0

    dash_duo.find_elements('input[type="radio"]')[1].click()

    dash_duo.wait_for_text_to_equal("#tab-output", 'Selected "a" in tab 2')
    dash_duo.wait_for_text_to_equal("#tab-2-output", 'Selected "a" in tab 2')
    assert call_counts["tab1"].value == 1
    assert call_counts["tab2"].value == 1

    assert not dash_duo.get_logs()
Ejemplo n.º 18
0
def Add_Dash(server):
    app = Dash(server=server, url_base_pathname=_URL_BASE)
    pgdb = create_engine(get_postgres_sqlalchemy_uri())
    apply_layout_with_auth(app, layout)

    @app.callback([
        Output('sensitivities-date-dropdown', 'options'),
        Output('sensitivities-date-dropdown', 'value')
    ], [Input('account-dropdown', 'value')])
    def update_date_dropdowns(account_value):
        statement = text("""
        select distinct model_date from {}.ltv_model_sensitivities order by model_date;
        """.format(account_value))
        with pgdb.connect() as con:
            rs = con.execute(statement)
            data = rs.fetchall()
            data = [{
                'label': datetime.strftime(d[0], "%Y-%m-%d"),
                'value': datetime.strftime(d[0], "%Y-%m-%d")
            } for d in data]
            default = data[0]['value']
        return [data, default]

    @app.callback([
        Output('ltv-metrics-model-type-dropdown', 'options'),
        Output('ltv-metrics-model-type-dropdown', 'value')
    ], [Input('account-dropdown', 'value')])
    def update_ltv_metrics_model_type_dropdown(account_value):
        statement = text("""
        select distinct model_type from {}.ltv_model_metrics;
        """.format(account_value))
        with pgdb.connect() as con:
            rs = con.execute(statement)
            data = rs.fetchall()
            data = [{'label': d[0], 'value': d[0]} for d in data]
            print(data)
            default = data[0]['value']
        return [data, default]

    @app.callback(Output('ltv-metrics-graph', 'figure'), [
        Input('account-dropdown', 'value'),
        Input('ltv-metrics-model-type-dropdown', 'value')
    ])
    def get_ltv_metrics_graph(account_value, model_type):
        statement = text("""
        select * from {}.ltv_model_metrics where model_type='{}' order by model_type, model_date
        """.format(account_value, model_type))
        with pgdb.connect() as con:
            rs = con.execute(statement)
            data = rs.fetchall()
            keys = rs.keys()
            df = pd.DataFrame(data, columns=keys)

        df = pd.melt(df,
                     id_vars=['model_date', 'model_type'],
                     value_vars=['precision', 'recall', 'accuracy', 'auc'])
        df = df.rename(columns={'variable': 'metric'})
        fig = px.scatter(
            df,
            x='model_date',
            y='value',
            color='metric',
        )
        for d in fig.data:
            d.update(mode='markers+lines')
        return fig

    @app.callback(Output('ltv-sensitivities-table', 'data'), [
        Input('account-dropdown', 'value'),
        Input('sensitivities-date-dropdown', 'value')
    ])
    def get_ltv_sensitivities_table(account_value, sensitivity_date):
        statement = text("""
        select
             category,
             category_value,
             category_count,
             ROUND(sensitivity::numeric, 3) sensitivity,
             model_type,
             model_date
        from {}.ltv_model_sensitivities where model_date = '{}'
        """.format(
            account_value,
            sensitivity_date))  # assume already ordered by batch process
        with pgdb.connect() as con:
            rs = con.execute(statement)
        data = rs.fetchall()
        keys = rs.keys()
        df = pd.DataFrame(data, columns=keys)
        print(df)
        return df.to_dict(orient='records')

    return app.server
Ejemplo n.º 19
0
def test_rdrh003_refresh_jwt(dash_duo):

    app = Dash(__name__)

    app.index_string = """<!DOCTYPE html>
    <html>
        <head>
            {%metas%}
            <title>{%title%}</title>
            {%favicon%}
            {%css%}
        </head>
        <body>
            <div>Testing custom DashRenderer</div>
            {%app_entry%}
            <footer>
                {%config%}
                {%scripts%}
                <script id="_dash-renderer" type"application/json">
                    const renderer = new DashRenderer({
                        request_refresh_jwt: (old_token) => {
                            console.log("refreshing token", old_token);
                            var new_token = "." + (old_token || "");
                            var output = document.getElementById('output-token')
                            if(output) {
                                output.innerHTML = new_token;
                            }
                            return new_token;
                        }
                    })
                </script>
            </footer>
            <div>With request hooks</div>
        </body>
    </html>"""

    app.layout = html.Div([
        dcc.Input(id="input", value="initial value"),
        html.Div(
            html.Div([html.Div(id="output-1"),
                      html.Div(id="output-token")])),
    ])

    @app.callback(Output("output-1", "children"), [Input("input", "value")])
    def update_output(value):
        return value

    required_jwt_len = 0

    # test with an auth layer that requires a JWT with a certain length
    def protect_route(func):
        @functools.wraps(func)
        def wrap(*args, **kwargs):
            try:
                if flask.request.method == "OPTIONS":
                    return func(*args, **kwargs)
                token = (
                    flask.request.authorization
                    or flask.request.headers.environ.get("HTTP_AUTHORIZATION"))
                if required_jwt_len and (not token or len(token) !=
                                         required_jwt_len + len("Bearer ")):
                    # Read the data to prevent bug with base http server.
                    flask.request.get_json(silent=True)
                    flask.abort(401, description="JWT Expired " + str(token))
            except HTTPException as e:
                return e
            return func(*args, **kwargs)

        return wrap

    # wrap all API calls with auth.
    for name, method in ((x, app.server.view_functions[x]) for x in app.routes
                         if x in app.server.view_functions):
        app.server.view_functions[name] = protect_route(method)

    dash_duo.start_server(app)

    _in = dash_duo.find_element("#input")
    dash_duo.clear_input(_in)

    required_jwt_len = 1

    _in.send_keys("fired request")

    dash_duo.wait_for_text_to_equal("#output-1", "fired request")
    dash_duo.wait_for_text_to_equal("#output-token", ".")

    required_jwt_len = 2

    dash_duo.clear_input(_in)
    _in.send_keys("fired request again")

    dash_duo.wait_for_text_to_equal("#output-1", "fired request again")
    dash_duo.wait_for_text_to_equal("#output-token", "..")

    assert len(dash_duo.get_logs()) == 2
Ejemplo n.º 20
0
# Run this app with `python app.py` and
# visit http://127.0.0.1:8050/ in your web browser.
from dash import Dash, html, dcc
import plotly.express as px
import pandas as pd
import math
from dash.dependencies import Input, Output, State

app = Dash(__name__)

colors = {
    'background': '#111111',
    'text': '#FFFFFF'
}

# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
o1 = 0.1
o2 = 0.15
k1 = 0.05
k2 = 0.056


df = pd.DataFrame({
    "t": [],
    "x": [],
    "y": [],
    "wav": []
})

Ejemplo n.º 21
0
import requests

from dash import Dash
from dash.components import *

from userguide import app, const

dash = Dash(server=app, url_namespace='')

dash.layout = div([
    h1('dash'),

    blockquote('''
        dash is a framework for creating interactive web-applications
        in pure python.'''),

    h3('quickstart'),

    Highlight('\n'.join([
        '$ pip install dash.ly --upgrade',
        '$ git clone -b skeleton https://github.com/chriddyp/messin.git',
        '$ cd messin',
        '$ pip install -r requirements.txt',
        '$ cd helloworld',
        '$ python helloworld.py',
        ' * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)']),
        className="bash"),

    hr(),

    div(className="row", content=[
Ejemplo n.º 22
0
def test_cbsc004_callback_using_unloaded_async_component(dash_duo):
    app = Dash()
    app.layout = html.Div(
        [
            dcc.Tabs(
                [
                    dcc.Tab("boo!"),
                    dcc.Tab(
                        dash_table.DataTable(
                            id="table",
                            columns=[{"id": "a", "name": "A"}],
                            data=[{"a": "b"}],
                        )
                    ),
                ]
            ),
            html.Button("Update Input", id="btn"),
            html.Div("Hello", id="output"),
            html.Div(id="output2"),
        ]
    )

    @app.callback(
        Output("output", "children"),
        [Input("btn", "n_clicks")],
        [State("table", "data")],
    )
    def update_out(n_clicks, data):
        return json.dumps(data) + " - " + str(n_clicks)

    @app.callback(
        Output("output2", "children"),
        [Input("btn", "n_clicks")],
        [State("table", "derived_viewport_data")],
    )
    def update_out2(n_clicks, data):
        return json.dumps(data) + " - " + str(n_clicks)

    dash_duo.start_server(app)

    dash_duo.wait_for_text_to_equal("#output", '[{"a": "b"}] - None')
    dash_duo.wait_for_text_to_equal("#output2", "null - None")

    dash_duo.find_element("#btn").click()
    dash_duo.wait_for_text_to_equal("#output", '[{"a": "b"}] - 1')
    dash_duo.wait_for_text_to_equal("#output2", "null - 1")

    dash_duo.find_element(".tab:not(.tab--selected)").click()
    dash_duo.wait_for_text_to_equal("#table th", "A")
    # table props are in state so no change yet
    dash_duo.wait_for_text_to_equal("#output2", "null - 1")

    # repeat a few times, since one of the failure modes I saw during dev was
    # intermittent - but predictably so?
    for i in range(2, 10):
        expected = '[{"a": "b"}] - ' + str(i)
        dash_duo.find_element("#btn").click()
        dash_duo.wait_for_text_to_equal("#output", expected)
        # now derived props are available
        dash_duo.wait_for_text_to_equal("#output2", expected)

    assert dash_duo.get_logs() == []
Ejemplo n.º 23
0
def test_cbmt004_chain_with_sliders(MULTI, dash_duo):
    app = Dash(__name__)
    app.layout = html.Div(
        [
            html.Button("Button", id="button"),
            html.Div(
                [
                    html.Label(id="label1"),
                    dcc.Slider(id="slider1", min=0, max=10, value=0),
                ]
            ),
            html.Div(
                [
                    html.Label(id="label2"),
                    dcc.Slider(id="slider2", min=0, max=10, value=0),
                ]
            ),
        ]
    )

    if MULTI:

        @app.callback(
            [Output("slider1", "value"), Output("slider2", "value")],
            [Input("button", "n_clicks")],
        )
        def update_slider_vals(n):
            if not n:
                raise PreventUpdate
            return n, n

    else:

        @app.callback(Output("slider1", "value"), [Input("button", "n_clicks")])
        def update_slider1_val(n):
            if not n:
                raise PreventUpdate
            return n

        @app.callback(Output("slider2", "value"), [Input("button", "n_clicks")])
        def update_slider2_val(n):
            if not n:
                raise PreventUpdate
            return n

    @app.callback(Output("label1", "children"), [Input("slider1", "value")])
    def update_slider1_label(val):
        return "Slider1 value {}".format(val)

    @app.callback(Output("label2", "children"), [Input("slider2", "value")])
    def update_slider2_label(val):
        return "Slider2 value {}".format(val)

    dash_duo.start_server(app)

    dash_duo.wait_for_text_to_equal("#label1", "")
    dash_duo.wait_for_text_to_equal("#label2", "")

    dash_duo.find_element("#button").click()
    dash_duo.wait_for_text_to_equal("#label1", "Slider1 value 1")
    dash_duo.wait_for_text_to_equal("#label2", "Slider2 value 1")

    dash_duo.find_element("#button").click()
    dash_duo.wait_for_text_to_equal("#label1", "Slider1 value 2")
    dash_duo.wait_for_text_to_equal("#label2", "Slider2 value 2")
Ejemplo n.º 24
0
def test_cbsc008_wildcard_prop_callbacks(dash_duo):
    lock = Lock()

    app = Dash(__name__)
    app.layout = html.Div(
        [
            dcc.Input(id="input", value="initial value"),
            html.Div(
                html.Div(
                    [
                        1.5,
                        None,
                        "string",
                        html.Div(
                            id="output-1",
                            **{"data-cb": "initial value", "aria-cb": "initial value"},
                        ),
                    ]
                )
            ),
        ]
    )

    input_call_count = Value("i", 0)
    percy_enabled = Value("b", False)

    def snapshot(name):
        percy_enabled.value = os.getenv("PERCY_ENABLE", "") != ""
        dash_duo.percy_snapshot(name=name)
        percy_enabled.value = False

    @app.callback(Output("output-1", "data-cb"), [Input("input", "value")])
    def update_data(value):
        with lock:
            if not percy_enabled.value:
                input_call_count.value += 1
            return value

    @app.callback(Output("output-1", "children"), [Input("output-1", "data-cb")])
    def update_text(data):
        return data

    dash_duo.start_server(app)
    dash_duo.wait_for_text_to_equal("#output-1", "initial value")
    snapshot("wildcard-callback-1")

    input1 = dash_duo.find_element("#input")
    dash_duo.clear_input(input1)

    for key in "hello world":
        with lock:
            input1.send_keys(key)

    dash_duo.wait_for_text_to_equal("#output-1", "hello world")
    snapshot("wildcard-callback-2")

    # an initial call, one for clearing the input
    # and one for each hello world character
    assert input_call_count.value == 2 + len("hello world")

    assert not dash_duo.get_logs()
Ejemplo n.º 25
0
def test_rddd001_initial_state(dash_duo):
    app = Dash(__name__)
    my_class_attrs = {
        "id": "p.c.4",
        "className": "my-class",
        "title": "tooltip",
        "style": {"color": "red", "fontSize": 30},
    }
    # fmt:off
    app.layout = html.Div([
        'Basic string',
        3.14,
        True,
        None,
        html.Div('Child div with basic string', **my_class_attrs),
        html.Div(id='p.c.5'),
        html.Div([
            html.Div('Grandchild div', id='p.c.6.p.c.0'),
            html.Div([
                html.Div('Great grandchild', id='p.c.6.p.c.1.p.c.0'),
                3.14159,
                'another basic string'
            ], id='p.c.6.p.c.1'),
            html.Div([
                html.Div(
                    html.Div([
                        html.Div([
                            html.Div(
                                id='p.c.6.p.c.2.p.c.0.p.c.p.c.0.p.c.0'
                            ),
                            '',
                            html.Div(
                                id='p.c.6.p.c.2.p.c.0.p.c.p.c.0.p.c.2'
                            )
                        ], id='p.c.6.p.c.2.p.c.0.p.c.p.c.0')
                    ], id='p.c.6.p.c.2.p.c.0.p.c'),
                    id='p.c.6.p.c.2.p.c.0'
                )
            ], id='p.c.6.p.c.2')
        ], id='p.c.6')
    ])
    # fmt:on

    dash_duo.start_server(app)
    dash_duo.wait_for_text_to_equal(r"#p\.c\.5", "")

    # Note: this .html file shows there's no undo/redo button by default
    with open(
        os.path.join(os.path.dirname(__file__), "initial_state_dash_app_content.html")
    ) as fp:
        expected_dom = BeautifulSoup(fp.read().strip(), "lxml")

    fetched_dom = dash_duo.dash_outerhtml_dom

    assert (
        fetched_dom.decode() == expected_dom.decode()
    ), "the fetching rendered dom is expected"

    assert dash_duo.get_logs() == [], "Check that no errors or warnings were displayed"

    assert dash_duo.driver.execute_script(
        "return JSON.parse(JSON.stringify(window.store.getState().layout))"
    ) == json.loads(
        json.dumps(app.layout, cls=plotly.utils.PlotlyJSONEncoder)
    ), "the state layout is identical to app.layout"

    r = requests.get("{}/_dash-dependencies".format(dash_duo.server_url))
    assert r.status_code == 200
    assert r.json() == [], "no dependencies present in app as no callbacks are defined"

    paths = dash_duo.redux_state_paths
    assert paths["objs"] == {}
    assert paths["strs"] == {
        abbr: [
            int(token)
            if token in string.digits
            else token.replace("p", "props").replace("c", "children")
            for token in abbr.split(".")
        ]
        for abbr in (
            child.get("id")
            for child in fetched_dom.find(id="react-entry-point").findChildren(id=True)
        )
    }, "paths should reflect to the component hierarchy"

    assert not dash_duo.redux_state_is_loading, "no callback => no pendingCallbacks"

    assert dash_duo.get_logs() == [], "console has no errors"
Ejemplo n.º 26
0
def test_cbsc014_multiple_properties_update_at_same_time_on_same_component(dash_duo):
    call_count = Value("i", 0)
    timestamp_1 = Value("d", -5)
    timestamp_2 = Value("d", -5)

    percy_enabled = Value("b")

    def snapshot(name):
        percy_enabled.value = os.getenv("PERCY_ENABLE", "") != ""
        dash_duo.percy_snapshot(name=name)
        percy_enabled.value = False

    app = Dash(__name__)
    app.layout = html.Div(
        [
            html.Div(id="container"),
            html.Button("Click", id="button-1", n_clicks=0, n_clicks_timestamp=-1),
            html.Button("Click", id="button-2", n_clicks=0, n_clicks_timestamp=-1),
        ]
    )

    @app.callback(
        Output("container", "children"),
        Input("button-1", "n_clicks"),
        Input("button-1", "n_clicks_timestamp"),
        Input("button-2", "n_clicks"),
        Input("button-2", "n_clicks_timestamp"),
    )
    def update_output(n1, t1, n2, t2):
        if not percy_enabled.value:
            call_count.value += 1
            timestamp_1.value = t1
            timestamp_2.value = t2
        return "{}, {}".format(n1, n2)

    dash_duo.start_server(app)

    dash_duo.wait_for_text_to_equal("#container", "0, 0")
    assert timestamp_1.value == -1
    assert timestamp_2.value == -1
    assert call_count.value == 1
    snapshot("Dash button-1 initialization 1")

    dash_duo.find_element("#button-1").click()
    dash_duo.wait_for_text_to_equal("#container", "1, 0")
    assert timestamp_1.value > ((time.time() - (24 * 60 * 60)) * 1000)
    assert timestamp_2.value == -1
    assert call_count.value == 2
    snapshot("Dash button-1 click")
    prev_timestamp_1 = timestamp_1.value

    dash_duo.find_element("#button-2").click()
    dash_duo.wait_for_text_to_equal("#container", "1, 1")
    assert timestamp_1.value == prev_timestamp_1
    assert timestamp_2.value > ((time.time() - 24 * 60 * 60) * 1000)
    assert call_count.value == 3
    snapshot("Dash button-2 click")
    prev_timestamp_2 = timestamp_2.value

    dash_duo.find_element("#button-2").click()
    dash_duo.wait_for_text_to_equal("#container", "1, 2")
    assert timestamp_1.value == prev_timestamp_1
    assert timestamp_2.value > prev_timestamp_2
    assert timestamp_2.value > timestamp_1.value
    assert call_count.value == 4
    snapshot("Dash button-2 click again")
Ejemplo n.º 27
0
from flask import Flask
from dash import Dash
import dash_bootstrap_components as dbc
from dashapp.util.show_docs import docs
from dashapp.api.yahoo.routes import yahoo
from dashapp.api.sel.banks.util.get_env import get_env
server = Flask(__name__,template_folder='./templates')

# Hide Selenium API for heroku
if get_env() not in ["production"]:
    from dashapp.api.sel.chrome_headless import sel
    server.register_blueprint(sel)

server.register_blueprint(docs)
server.register_blueprint(yahoo)

# Add auth eventually https://dash.plot.ly/authentication
from os import environ
# Only used for CI
if environ.get('DASH_SUPPRESS') is not None:
    app = Dash(server=server, suppress_callback_exceptions=True, external_stylesheets=[dbc.themes.BOOTSTRAP])
else:
    app = Dash(server=server,  external_stylesheets=[dbc.themes.BOOTSTRAP])
Ejemplo n.º 28
0
def test_cbsc002_callbacks_generating_children(dash_duo):
    """Modify the DOM tree by adding new components in the callbacks."""

    # some components don't exist in the initial render
    app = Dash(__name__, suppress_callback_exceptions=True)
    app.layout = html.Div(
        [dcc.Input(id="input", value="initial value"), html.Div(id="output")]
    )

    @app.callback(Output("output", "children"), [Input("input", "value")])
    def pad_output(input):
        return html.Div(
            [
                dcc.Input(id="sub-input-1", value="sub input initial value"),
                html.Div(id="sub-output-1"),
            ]
        )

    call_count = Value("i", 0)

    @app.callback(Output("sub-output-1", "children"), [Input("sub-input-1", "value")])
    def update_input(value):
        call_count.value = call_count.value + 1
        return value

    dash_duo.start_server(app)

    dash_duo.wait_for_text_to_equal("#sub-output-1", "sub input initial value")

    assert call_count.value == 1, "called once at initial stage"

    pad_input, pad_div = dash_duo.dash_innerhtml_dom.select_one(
        "#output > div"
    ).contents

    assert (
        pad_input.attrs["value"] == "sub input initial value"
        and pad_input.attrs["id"] == "sub-input-1"
    )
    assert pad_input.name == "input"

    assert (
        pad_div.text == pad_input.attrs["value"] and pad_div.get("id") == "sub-output-1"
    ), "the sub-output-1 content reflects to sub-input-1 value"

    dash_duo.percy_snapshot(name="callback-generating-function-1")

    paths = dash_duo.redux_state_paths
    assert paths["objs"] == {}
    assert paths["strs"] == {
        "input": ["props", "children", 0],
        "output": ["props", "children", 1],
        "sub-input-1": [
            "props",
            "children",
            1,
            "props",
            "children",
            "props",
            "children",
            0,
        ],
        "sub-output-1": [
            "props",
            "children",
            1,
            "props",
            "children",
            "props",
            "children",
            1,
        ],
    }, "the paths should include these new output IDs"

    # editing the input should modify the sub output
    dash_duo.find_element("#sub-input-1").send_keys("deadbeef")

    # the total updates is initial one + the text input changes
    dash_duo.wait_for_text_to_equal(
        "#sub-output-1", pad_input.attrs["value"] + "deadbeef"
    )

    assert not dash_duo.redux_state_is_loading, "loadingMap is empty"

    dash_duo.percy_snapshot(name="callback-generating-function-2")
    assert dash_duo.get_logs() == [], "console is clean"
Ejemplo n.º 29
0
def test_clsd002_chained_serverside_clientside_callbacks(dash_duo):
    app = Dash(__name__, assets_folder="clientside_assets")

    app.layout = html.Div([
        html.Label("x"),
        dcc.Input(id="x", value=3),
        html.Label("y"),
        dcc.Input(id="y", value=6),
        # clientside
        html.Label("x + y (clientside)"),
        dcc.Input(id="x-plus-y"),
        # server-side
        html.Label("x+y / 2 (serverside)"),
        dcc.Input(id="x-plus-y-div-2"),
        # server-side
        html.Div([
            html.Label("Display x, y, x+y/2 (serverside)"),
            dcc.Textarea(id="display-all-of-the-values"),
        ]),
        # clientside
        html.Label("Mean(x, y, x+y, x+y/2) (clientside)"),
        dcc.Input(id="mean-of-all-values"),
    ])

    app.clientside_callback(
        ClientsideFunction("clientside", "add"),
        Output("x-plus-y", "value"),
        [Input("x", "value"), Input("y", "value")],
    )

    call_counts = {"divide": Value("i", 0), "display": Value("i", 0)}

    @app.callback(Output("x-plus-y-div-2", "value"),
                  [Input("x-plus-y", "value")])
    def divide_by_two(value):
        call_counts["divide"].value += 1
        return float(value) / 2.0

    @app.callback(
        Output("display-all-of-the-values", "value"),
        [
            Input("x", "value"),
            Input("y", "value"),
            Input("x-plus-y", "value"),
            Input("x-plus-y-div-2", "value"),
        ],
    )
    def display_all(*args):
        call_counts["display"].value += 1
        return "\n".join([str(a) for a in args])

    app.clientside_callback(
        ClientsideFunction("clientside", "mean"),
        Output("mean-of-all-values", "value"),
        [
            Input("x", "value"),
            Input("y", "value"),
            Input("x-plus-y", "value"),
            Input("x-plus-y-div-2", "value"),
        ],
    )

    class DashView(BaseDashView):
        dash = app

    dash_duo.start_server(DashView)

    test_cases = [
        ["#x", "3"],
        ["#y", "6"],
        ["#x-plus-y", "9"],
        ["#x-plus-y-div-2", "4.5"],
        ["#display-all-of-the-values", "3\n6\n9\n4.5"],
        ["#mean-of-all-values",
         str((3 + 6 + 9 + 4.5) / 4.0)],
    ]
    for selector, expected in test_cases:
        dash_duo.wait_for_text_to_equal(selector, expected)

    assert call_counts["display"].value == 1
    assert call_counts["divide"].value == 1

    x_input = dash_duo.wait_for_element_by_css_selector("#x")
    x_input.send_keys("1")

    test_cases = [
        ["#x", "31"],
        ["#y", "6"],
        ["#x-plus-y", "37"],
        ["#x-plus-y-div-2", "18.5"],
        ["#display-all-of-the-values", "31\n6\n37\n18.5"],
        ["#mean-of-all-values",
         str((31 + 6 + 37 + 18.5) / 4.0)],
    ]
    for selector, expected in test_cases:
        dash_duo.wait_for_text_to_equal(selector, expected)

    assert call_counts["display"].value == 2
    assert call_counts["divide"].value == 2
Ejemplo n.º 30
0
            dbc.Col([
                html.H2("Graph"),
                dcc.Graph(figure={"data": [{
                    "x": [1, 2, 3],
                    "y": [1, 4, 9]
                }]}),
            ]),
        ])
    ],
    className="mt-4",
)

_layout = html.Div([_navbar, _body])


class DemoLayoutPage:
    def for_path(self, component):
        return _layout


if __name__ == "__main__":
    app = Dash(
        __name__,
        external_stylesheets=[
            "https://stackpath.bootstrapcdn.com/bootstrap/"
            "4.1.3/css/bootstrap.min.css"
        ],
    )
    app.layout = _layout
    app.run_server(port=8888, debug=True)