Analytical Web Apps for Python, R, Julia, and Jupyter. No JavaScript Required.

Dash

CircleCI GitHub PyPI PyPI - Python Version GitHub commit activity LGTM Alerts LGTM Grade

Dash is the most downloaded, trusted Python framework for building ML & data science web apps.

Built on top of Plotly.js, React and Flask, Dash ties modern UI elements like dropdowns, sliders, and graphs directly to your analytical Python code. Read our tutorial proudly crafted ❤️ by Dash itself.

App Samples

App Description
Sample Dash App Here’s a simple example of a Dash App that ties a Dropdown to a D3.js Plotly Graph. As the user selects a value in the Dropdown, the application code dynamically exports data from Google Finance into a Pandas DataFrame. This app was written in just 43 lines of code (view the source).
Crossfiltering Dash App Dash app code is declarative and reactive, which makes it easy to build complex apps that contain many interactive elements. Here’s an example with 5 inputs, 3 outputs, and cross filtering. This app was composed in just 160 lines of code, all of which were Python.
Dash App with Mapbox map showing walmart store openings Dash uses Plotly.js for charting. Over 35 chart types are supported, including maps.
Financial report Dash isn't just for dashboards. You have full control over the look and feel of your applications. Here's a Dash App that's styled to look like a PDF report.

To learn more about Dash, read the extensive announcement letter or jump in with the user guide.

Dash OSS & Dash Enterprise

With Dash Open Source, Dash apps run on your local laptop or workstation, but cannot be easily accessed by others in your organization.

Scale up with Dash Enterprise when your Dash app is ready for department or company-wide consumption. Or, launch your initiative with Dash Enterprise from the start to unlock developer productivity gains and hands-on acceleration from Plotly's team.

ML Ops Features: A one-stop shop for ML Ops: Horizontally scalable hosting, deployment, and authentication for your Dash apps. No IT or DevOps required.

  • App manager Deploy & manage Dash apps without needing IT or a DevOps team. App Manager gives you point & click control over all aspects of your Dash deployments.
  • Kubernetes scaling Ensure high availability of Dash apps and scale horizontally with Dash Enterprise’s Kubernetes architecture. No IT or Helm required.
  • No code auth Control Dash app access in a few clicks. Dash Enterprise supports LDAP, AD, PKI, Okta, SAML, OpenID Connect, OAuth, SSO, and simple email authentication.
  • Job Queue The Job Queue is the key to building scalable Dash apps. Move heavy computation from synchronous Dash callbacks to the Job Queue for asynchronous background processing.

Low-Code Features: Low-code Dash app capabilities that supercharge developer productivity.

  • Design Kit Design like a pro without writing a line of CSS. Easily arrange, style, brand, and customize your Dash apps.
  • Snapshot Engine Save & share Dash app views as links or PDFs. Or, run a Python job through Dash and have Snapshot Engine email a report when the job is done.
  • Dashboard Toolkit Drag & drop layouts, chart editing, and crossfilter for your Dash apps.
  • Embedding Natively embed Dash apps in an existing web application or website without the use of IFrames.

Enterprise AI Features: Everything that your data science team needs to rapidly deliver AI/ML research and business initiatives.

  • AI App Marketplace Dash Enterprise ships with dozens of Dash app templates for business problems where AI/ML is having the greatest impact.
  • Big Data for Pything Connect to Python's most popular big data back ends: Dask, Databricks, NVIDIA RAPIDS, Snowflake, Postgres, Vaex, and more.
  • GPU & Dask Acceleration Dash Enterprise puts Python’s most popular HPC stack for GPU and parallel CPU computing in the hands of business users.
  • Data Science Workspaces Be productive from Day 1. Write and execute Python, R, & Julia code from Dash Enterprise's onboard code editor.

See https://plotly.com/contact-us/ to get in touch.

image

Comments
  • A simple working example for embedding dash in flask under a path

    A simple working example for embedding dash in flask under a path

    Dash documentation lacks a simple but full working example of how to embed dash layout as a path in a flask app, so that the dash layout becomes a div in the flask and follows the base template. For example path '/plot&type=plot1' return dash layout for plot type 1. I know that one can get the underlying flask app in dash, but how to get rendered dash layout in flask is not well documented.

  • 475 Pattern Matching Callbacks (codenamed wildcards)

    475 Pattern Matching Callbacks (codenamed wildcards)

    Pattern Matching Callbacks! (Codenamed, Wildcards!)

    ➡️ See official documentation here: https://dash.plotly.com/pattern-matching-callbacks

    Closes #475 - using the API discussed there (I'll post some examples soon, but for now here's the description):

    • String IDs still work the same way in both layout and callbacks
    • Now you can also make dict IDs. Keys should be strings, values can be strings, numbers, booleans, like:
      • id={"type": "cat", "age": 4, "purrs": True}
      • IDs must still be unique
    • Callbacks can use dict IDs with wildcard values for any of the keys. The supported wildcards are MATCH, ALL, and ALLSMALLER - and can be imported from dash.dependencies. There are various rules about how these can combine, driven by the need to resolve these to a unique callback invocation for each set of outputs and identify uniquely the inputs required for this invocation...

    To do before this is ready:

    • [x] Move most callback validation logic to the front end (so it doesn't need to be replicated in R)
    • [x] Do something with the callback graph when there are wildcards
    • [x] Test that this PR closes callback failure bugs: #1053, #1071, #1084, #1105
    • [x] See if it also closes redundant callback bugs #635, #832

    Contributor Checklist

    • [x] I have run the tests locally and they passed. (refer to testing section in contributing)
    • [x] I have added tests, or extended existing tests, to cover any new features or bugs fixed in this PR
    • [x] I have added entry in the CHANGELOG.md
    • [ ] If this PR needs a follow-up in dash docs, community thread, I have mentioned the relevant URLS as follow
      • [ ] this github #PR number updates the dash docs
      • [ ] here is the show and tell thread in plotly dash community

    Closes #832 (among other callback bugs - the others all have commits that close them with matching tests, but #832 is a bit heavy for a test of its own) Closes #1146

  • Validate component properties #264

    Validate component properties #264

    PR for #264

    Current Prerelease

    pip install dash==0.29.0rc8
    pip install dash-renderer==0.15.0rc1
    pip install dash-core-components==0.31.0rc2
    pip install dash-html-components==0.14.0rc3
    

    Validation is on by default. To turn it off, you can set app.config.disable_component_validation = True

    Test Cases to run for demo

    import dash
    import dash_html_components as html
    import dash_core_components as dcc
    import plotly.graph_objs as go
    from dash.dependencies import Input, Output
    
    app = dash.Dash()
    app.scripts.config.serve_locally=True
    
    app.layout = html.Div([
        html.Button(id='click1', children='click to return bad Div children'),
        html.Div(id='output1', **{'data-cb': 'foo'}),
        html.Button(id='click2', children='click to return a bad figure'),
        dcc.Graph(id='output2', figure={'data': [], 'layout': {}}),
        html.Button(id='click3', children='click to return a bad radio'),
        dcc.RadioItems(id='output3', options=[{'value': 'okay', 'label': 'okay'}]),
        html.Button(id='click4', children='click to make a figure with no id'),
        html.Div(id='output4'),
    ])
    
    
    
    @app.callback(Output('output1', 'children'),
                  [Input('click1', 'n_clicks')])
    def crash_it1(clicks):
        if clicks:
            return [[]]
        return clicks
    
    @app.callback(Output('output2', 'figure'),
                  [Input('click2', 'n_clicks')])
    def crash_it2(clicks):
        if clicks:
            return {'data': {'x': [1, 2, 3], 'y': [1, 2, 3], 'type': 'scatter'}, 'layout': {}}
        return go.Figure(data=[go.Scatter(x=[1,2,3], y=[1,2,3])], layout=go.Layout()) 
    
    @app.callback(Output('output3', 'options'),
                  [Input('click3', 'n_clicks')])
    def crash_it3(clicks):
        if clicks:
            return [{'value': {'not okay': True}, 'labl': 'not okay'}]
        return [{'value': 'okay', 'label': 'okay'}]
    
    @app.callback(Output('output4', 'children'),
                  [Input('click4', 'n_clicks')])
    def crash_it4(clicks):
        if clicks:
            return dcc.Graph()
        return dcc.Graph(id='hi')
    
    app.run_server(debug=True, port=8050)
    

    Example Error Messages

    CallbackOutputValidationError: 
    
    
    A Dash Callback produced an invalid value!
    
    Dash tried to update the `figure` prop of the
    `Graph` with id `output2` by calling the
    `crash_it2` function with `(1)` as arguments.
    
    This function call returned `{'layout': {}, 'data': {'y': [1, 2, 3], 'x': [1, 2, 3], 'type': 'scatter'}}`, which did not pass
    validation tests for the `Graph` component.
    
    The expected schema for the `figure` prop of the
    `Graph` component is:
    
    ***************************************************************
    {'validator': 'plotly_figure'}
    ***************************************************************
    
    The errors in validation are as follows:
    
    * figure	<- Invalid Plotly Figure:
    
    
        Invalid value of type '__builtin__.dict' received for the 'data' property of 
            Received value: {'y': [1, 2, 3], 'x': [1, 2, 3], 'type': 'scatter'}
    
        The 'data' property is a tuple of trace instances
        that may be specified as:
          - A list or tuple of trace instances
            (e.g. [Scatter(...), Bar(...)])
          - A list or tuple of dicts of string/value properties where:
            - The 'type' property specifies the trace type
                One of: ['mesh3d', 'splom', 'scattercarpet',
                         'scattergl', 'scatterternary', 'pie',
                         'surface', 'histogram', 'ohlc', 'heatmapgl',
                         'cone', 'scatterpolar', 'table',
                         'scatterpolargl', 'histogram2d', 'contour',
                         'carpet', 'box', 'violin', 'bar',
                         'contourcarpet', 'area', 'choropleth',
                         'candlestick', 'streamtube', 'parcoords',
                         'heatmap', 'barpolar', 'scattermapbox',
                         'scatter3d', 'pointcloud',
                         'histogram2dcontour', 'scatter', 'scattergeo',
                         'sankey']
    
            - All remaining properties are passed to the constructor of
              the specified trace type
    
            (e.g. [{'type': 'scatter', ...}, {'type': 'bar, ...}])
    
    
    CallbackOutputValidationError: 
    
    
    A Dash Callback produced an invalid value!
    
    Dash tried to update the `options` prop of the
    `RadioItems` with id `output3` by calling the
    `crash_it3` function with `(1)` as arguments.
    
    This function call returned `[{'value': {'not okay': True}, 'labl': 'not okay'}]`, which did not pass
    validation tests for the `RadioItems` component.
    
    The expected schema for the `options` prop of the
    `RadioItems` component is:
    
    ***************************************************************
    {'schema': {'allow_unknown': False,
                'nullable': False,
                'schema': {'disabled': {'type': 'boolean'},
                           'label': {'type': 'string'},
                           'value': {'type': 'string'}},
                'type': 'dict'},
     'type': 'list'}
    ***************************************************************
    
    The errors in validation are as follows:
    
    * options
     * 0
      * value	<- must be of string type
      * labl	<- unknown field
    
    
    ComponentInitializationValidationError: 
    
    
    A Dash Component was initialized with invalid properties!
    
    Dash tried to create a `RadioItems` component with the
    following arguments, which caused a validation failure:
    
    ***************************************************************
    {'id': 'output3', 'options': [{'label': 'okay', 'value': {}}]}
    ***************************************************************
    
    The expected schema for the `RadioItems` component is:
    
    ***************************************************************
    {'className': {'type': 'string'},
     'dashEvents': {'allowed': ['change'], 'type': ('string', 'number')},
     'fireEvent': {},
     'id': {'type': 'string'},
     'inputClassName': {'type': 'string'},
     'inputStyle': {'type': 'dict'},
     'labelClassName': {'type': 'string'},
     'labelStyle': {'type': 'dict'},
     'options': {'schema': {'allow_unknown': False,
                            'nullable': False,
                            'schema': {'disabled': {'type': 'boolean'},
                                       'label': {'type': 'string'},
                                       'value': {'type': 'string'}},
                            'type': 'dict'},
                 'type': 'list'},
     'setProps': {},
     'style': {'type': 'dict'},
     'value': {'type': 'string'}}
    ***************************************************************
    
    The errors in validation are as follows:
    
    
    * options
     * 0
      * value	<- must be of string type
    
    

    PropTypes to Cerberus reference

    | PropType | Cerberus Schema Validated Against | Known Current Limitations | | ---------- | ------------------------------------ | -------------------------- | | array | {'type': 'list'} | | | bool | {'type': 'boolean'} | | | func | {} | No validation occurs. | | object | {'type': 'dict'} | Validates that input is explicitly a dict object. We cannot be more general (e.g. collections.abc.Mapping) since the core Component is an instance of that.| | string | {'type': 'string'} | | | symbol | {} | No validation occurs | | node | {'anyof': [{'type': 'component'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'string'}, {'type': 'list', 'schema': {'anyof': [{'type': 'component'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'string'}]}}]} | | | instanceOf(Object) | {} | No validation occurs | | oneOf(['val1', 2]) | {'allowed': [None, 'val1', 2]} | Strings will have ' characters stripped off each end. This is because metadata.json generation serializes the literal values as json, so for example PropTypes.oneOf(['News', 'Photos']) serializes to ["'News'", "'Photos'"]. https://github.com/reactjs/react-docgen/issues/57 | | oneOfType( [ PropTypes.string, PropTypes.bool ] ) | {'anyof': [{'type': 'string', 'type': 'boolean'}]} | If one of the types is a PropType that cannot be validated individually (e.g. PropType.func), no validation will occur and the schema will effectively be {} | | arrayOf( PropTypes.number ) | {'type': 'list', 'schema': {'type': 'number'}} | | | objectOf( PropTypes.number ) | {'type': 'dict', 'valueschema': {'type': 'number'}} | | | shape( { k1: PropTypes.string, k2: PropTypes.number } ) | {'type': 'dict', 'allow_unknown': False, 'schema': {'k1': {'type': 'string}, 'k2': {'type': 'number'}}} | | | any | {'type': ('boolean', 'number', 'string', 'dict', 'list')} | |

  • Clientside Callbacks

    Clientside Callbacks

    In Dash, changes to component properties in the front-end trigger user-supplied Python functions (@app.callback). This framework is very flexible: users have full control over the Python code that they write in their app.callback functions.

    However, app.callback functions are simple. They filter some data or change the color of the chart or display some text. These data transformations, although simple, currently need to be processed entirely over the network in the Python backend. This makes the apps slower than they could be (because of the network delay) and less portable than they could be (because they require a running Python server).

    Clientside Callbacks will introduce an interface for describing data transformation relationships between components in JavaScript. These data transformations will happen entirely in the client-side without passing data over the network. The Clientside callbacks Dash framework will enable developers to swap out their python-driven @app.callback functions with javascript-executed data transformations, enabling more performant apps.


    As a quick background, here is what Dash Apps currently look like in Python:

    The first part describes what the app looks like. These classes just declaratively describe the names and the props of the React components that they generate. These objects get serialized as JSON.

    image

    app.layout = html.Div([
    
        html.H1('Example'),
    
        comonents.TextInput(
            id='my-text-input',
            value='Initial value'
        ),
        components.Dropdown(
            id='my-dropdown',
            options=[
                'Option A', 'Option B', 'Option C'
            ]
            value='Option A'
        ),
    
        components.Graph(
            id='my-graph'
            figure={             # Just a plotly figure
                'data': [...],
                'layout': {...}
            }
        )
    ])
    

    The second part of dash apps describe the relationship between graphs. This sets up "sources" ("inputs") and "sinks" ("outputs") in the Dash front-end. Whenever any of the Input properties change, the AJAX call gets made.

    It's Reactive like a spreadsheet: as inputs change, the new values propagate down the dependency graph, updating components in the correct order:

    1_basic_reactive

    @callback(
        Input(
            id='my-dropdown',
            property='value'
        ),
        Input(
            id='my-text-input',
            property='value'
        ),
        Output(
            id='my-graph',
            property='figure'
        )
    )
    def update_graph(new_dropdown_value, new_text_input_value):
        # compute a new figure based off of the new values of the dropdown
        # or text input
        return {
            'data': [{
                'x': [1, 2, 3],
                'y': ({
                    'Option A': [3, 1, 2],
                    'Option B': [4, 3, 5],
                    'Option C': [1, 2, 4]
                })[dropdown]
            }],
            'layout': {'title': text}
        }
    

    These reactive updates happen entirely server-side through HTTP requests. (This allows dash developers to do complicated updates or analytics through their python context).

    I think that we could extend this framework to work client-side as well. Instead of a custom function defining how Inputs ("sources") update Outputs ("sinks"), we could define a library of transformations components and a syntax for relating input properties to output properties. These transformations could be just be functional React components.

    Here are some conceptual examples: 2_input_updates_text

    from dash.serverless import Selector as S
    
    layout = Div([
        Input(id='my-input', value='initial-value'),
        H3(children=S('my-input', 'value'))
    ])
    

    In this example, we're setting the "children" property of the HTML H3 element to just be the "value" of the "my-input" component. When "value" changes, the content of the H3 element updates to match the new value.

    I'm wrapping the ID and property with S to denote that the string represents a "reactive" property corresponding to the component with the specified ID and that component's property. (The actual API might be different, just using s for conceptual purposes.)

    Now, consider a "Dataset" component and a "Graph":

    3_dataset_graph

    layout = Div([
        Dataset(
            id='my-dataset'
            columns={
                'column-1': [1, 2, 3],
                'column-2': [3, 1, 4]
            },
            column_names={
                'column-1': 'My first column',
                'column-2': 'My second column'
            }
        ),
    
        Graph(
            figure={
                'data': [{
                    'x': S('my-dataset', 'column-1'),
                    'y': S('my-dataset', 'column-2')
                }]
            }
        )
    ])
    

    Note that not all components actually get rendered in the DOM. In this case, the Dataset component isn't actually visible. It's just included as state. If you wanted to view it as a table, it would look like:

    image

    layout = Div([
        Dataset(
            id='my-dataset'
            columns={
                'column-1': [1, 2, 3],
                'column-2': [3, 1, 4]
            },
            column_names={
                'column-1': 'My first column',
                'column-2': 'My second column'
            }
        ),
    
        Table(data='::my-dataset.columns'),
    
        Graph(
            figure={
                'data': [{
                    'x': S('my-dataset', 'columns', 'column-1'),
                    'y': S('my-dataset', 'columns', 'column-2')
                }]
            }
        )
    ])
    

    You can imagine how there might be several datasets and several graphs in one (like a dashboard or a report).

    layout = Div([
        Dataset(id='dataset-1', columns={...}),
        Dataset(id='dataset-2', columns={...}),
        Dataset(id='dataset-3', columns={...}),
        Graph(id='graph-1',
              data=[{'x': S('dataset-1', 'columns', 'column-1'), ...}]
        ),
        Graph(id='graph-2',
              data=[{'x': S('dataset-2', 'columns', 'column-1'), ...}]
        ),
        Graph(id='graph-3',
              data=[{'x': S('dataset-3, 'columns', 'column-1'), ...}]
        )
    ])
    

    Now, we would also need a library for lightweight data transformations. I'm thinking something like Ramda.

    import dash.clientside.transformations as T
    import dash.clientside.selector as S
    
    df = pd.DataFrame([
        {'col-1': 1, 'col-2': 5, 'col-3': 10},
        {'col-1': 2, 'col-2': 6, 'col-3': 11},
        {'col-1': 3, 'col-2': 7, 'col-3': 12},
        # ...
    ])
    
    app.layout = html.Div([
    
        # "Virtual" component that doesn't render anything
        # to the screen, it just contains the data for other
        # components to reference
        dcc.Dataset(
            id='my-dataset',
            columns=df.columns,
            rows=df.to_dict(),
        ),
    
        # `Table` renders an actual table to the screen
        dcc.Table(
            rows=S('my-dataset', 'rows'),
            columns=S('my-dataset', 'rows')
        ),
    
        dcc.Graph(
            figure={
    
                # T.pluck('col-1', [{'col-1': 1}, {'col-1': 2}]) -> [1, 2]
    
                'x': T.pluck(
                    'col-1',
                    S('my-dataset', 'rows')
                ),
                'y': T.pluck(
                    'col-2',
                    S('my-dataset', 'rows')
                )
            }
        )
    ])
    

    Or, extending this with dynamic components:

    app.layout = html.Div([
        dcc.Dataset(
            id='my-dataset',
            columns=df.columns,
            rows=df.to_dict(),
        ),
    
        dcc.Dropdown(
            id='my-dropdown',
            options=[
                {'option': i, 'label': i}
                for i in df.columns
            ],
            value=df.columns[0]
        ),
    
        dcc.Graph(
            figure={
                'x': T.pluck(
                    'col-1',
                    S('my-dataset', 'rows')
                ),
                'y': T.pluck(
                    S('my-dropdown', 'value'),
                    S('my-dataset', 'rows')
                )
            }
        )
    ])
    

    5_simple_declarative_dropdown


    Here are some high-level architectural requirements and goals for this work item:

    • The Dash Apps will still be created with Python
    • The clientside callbacks will be executed in JavaScript
    • The existing set of Dash components will be available (with the exception of network-connected components like the mapbox charts)
    • We will introduce a new syntax or language ("data transformation language") for declaratively describing the relationships and simple operations between component properties. This language will have a Python interface, will be serialized as JSON, and executed in JavaScript.
    • This client-side data transformation will be available in server-connected Dash apps as well, enabling certain simple updates to happen quickly
    • The app will not run arbitrary JavaScript, it will be designed in a way to be safe from XSS injections
    • The "data transformation language" will operations like filtering, plucking values from nested objects, sorting, and arithmetic. It will draw inspiration from functional programming libraries and languages that enable concise, chainable, and immutable data transformations. See Ramda (http://ramdajs.com/) for an example.
  • Dash Dev Tools

    Dash Dev Tools

    In https://github.com/orgs/plotly/projects/3, many of our issues involve Dash's front-end: Front-end error handling, front-end live-DAG, front-end hot-reload.

    I'd like to open this issue to discuss an architecture for handling these requirements.

    Some framing:

    JavaScript Error Handling

    • We should expose Dash's front-end errors to the users. Currently, they are only available in the browser's dev tools, which is too hidden for our community.

    For example, consider Atom's plugins: image

    Python Error Handling Could we use the same architecture that we use for JavaScript errors to display python errors? That way, the user never needs to look at the terminal for errors, they only need to focus on their app.

    For example, consider create-react-app: image

    or werkzeug: image

    Hot Reloading If we had hot-reloading, could we build a nice little "control bar" that users could use to configure hot reloading? For example, it could:

    • Tell the user if hot-reloading is on or off
    • Users could turn hot-reloading on and off
    • It could provide build times or "last updated" times

    Displaying the DAG If we wanted to display the DAG to the user, could we place this in the Dash Dev Tools container as well? image


    cc @plotly/dash

  • error UnsupportedOperation: not writable

    error UnsupportedOperation: not writable

    I had dash running on my pc before without problems. I had to reinstall and now I can't get it to work. Even when I use the most basic code I get the same error. Here I used the very first code example of the tutorial with montreal and sf https://dash.plot.ly/getting-started#installation

    I still always get this error:


    File "", line 25, in app.run_server(debug=True)

    File "/Users/Wheez/anaconda3/envs/py36/lib/python3.6/site-packages/dash/dash.py", line 568, in run_server self.server.run(port=port, debug=debug, **flask_run_options)

    File "/Users/Wheez/anaconda3/envs/py36/lib/python3.6/site-packages/flask/app.py", line 938, in run cli.show_server_banner(self.env, self.debug, self.name, False)

    File "/Users/Wheez/anaconda3/envs/py36/lib/python3.6/site-packages/flask/cli.py", line 629, in show_server_banner click.echo(message)

    File "/Users/Wheez/anaconda3/envs/py36/lib/python3.6/site-packages/click/utils.py", line 259, in echo file.write(message)

    UnsupportedOperation: not writable


    I run it on python 3.6 with anaconda and spyder and followed the installation tutorial. I have no idea what to do. Thanks for any help.

  • Embedding or displaying local images

    Embedding or displaying local images

    I can't find a way to embed or display local images, either through html or in a plotly graph. This seems to be a limitation with the server can do (in the former case) or a lack of support (in the later case).

    My intended use case is have a user point to a directory of images. I want to display the image that the user selects. The image is then classified using a model built in Keras.

    Is there any way to display an image locally?

  • Proposal for Offline CSS and JS and Customizable `index.html`

    Proposal for Offline CSS and JS and Customizable `index.html`

    Opening this issue to propose the officially endorsed and documented method for embedding custom, local CSS and JavaScript in Dash apps.

    This development for this issue has been sponsored by an organization. Many thanks! If your company or organization would like to sponsor development, please reach out.

    Background: In Dash, HTML tags and higher-level components are embedded in the App by assigning the app.layout property to a nested hierarchy of Dash components (e.g. the components in the dash-core-components or the dash-html-components library). These components are serialized as JSON and then rendered client-side with React.js. On page load, Dash serves a very minimal HTML string which includes the blank container for rendering the app within, the component library's JavaScript and CSS, and a few meta HTML tags like the page title and the encoding (see https://github.com/plotly/dash/blob/6a1809fc619671f8bf7e1294d12ef1180e90df6b/dash/dash.py#L293-L318).

    This architecture doesn't work well for embedding custom JavaScript scripts and CSS Stylesheets because these scripts and stylesheets usually need to be included in the HTML that is served on page load.

    We will support user-supplied JavaScript and CSS through two enhancements:

    Enhancement 1 - Automatic

    • This "automatic" method will template in all stylesheets (CSS) and scripts (JavaScript) that are included in a static folder
    • These links will be included in alphabetical order
    • These links will be included after the component library's stylesheets and scripts
    • The server route (/static/<path:string>) for serving these files will be configured automatically by Dash

    This method will be what most Dash users will use. It's very easy to use and easy to document ("To include custom CSS, just place your CSS files in static folder. Dash will take care of the rest"). Since the files will be templated alphabetically, the user can control the order (if necessary) by prefixing ordered numbers to the files (e.g. 1-loading.css, 2-app.css).

    With this method, we'll be able to add custom CSS processing middleware like minifying CSS or creating cache-busting URLs completely automatically.

    If the user needs more control over the placement of these files, they can use the method in "Enhancement 2 - Manual Override".

    Enhancement 2 - Manual Override

    Currently on page load, Dash serves this HTML string: https://github.com/plotly/dash/blob/6a1809fc619671f8bf7e1294d12ef1180e90df6b/dash/dash.py#L293-L318.

    This enhancement will make this overridable:

    • The user will assign a HTML string or a function that returns an HTML string to a property on the app object (e.g. app.index).
    • This HTML string will include several predefined template variable names that will correspond to the stylesheets and scripts that Dash needs to include to render the component libraries.
    • The user can include extra meta tags in their template or even include other HTML around their Dash app container.

    Here is an example:

    def custom_index():
        return '''
        <!DOCTYPE html>
        <html>
    
            <head>
                <meta charset="UTF-8">
                <meta description="This is my dash app">
    
                <title>My Custom Dash App</title>
                <link ref="stylesheet" href="/static/my-custom-css-normalize.css">
                {dash_renderer_css_bundle}
                {dash_component_css_bundles}
                <link ref="stylesheet" href="/static/my-component-css-override.css">
    
            </head>
    
            <body>
                <div>
                    My Custom Header
                </div>
                <div id="react-entry-point">
                    <div class="_dash-loading">
                        Loading...
                    </div>
                </div>
            </body>
    
            <footer>
                <script type="javascript" src="/static/my-custom-javascript-bundle.js">
                {dash_renderer_javascript_bundle}
                {dash_component_javascript_bundles}
                <script type="javascript" src="/static/my-custom-javascript-override.js">
            </footer>
    
        </html>
        '''
    
    app.index = custom_index
    

    The following items will be required in creating an index string:

    • The dash_component_css_bundles, dash_component_javascript_bundles, dash_renderer_css_bundle, dash_renderer_javascript_bundle template names. Dash will look for these names and fill them in with the appropriate component CSS and JavaScript on page load.
    • A <div/> with an id react-entry-point. Dash's front-end will render the app within this div once the JavaScript has been evaluated.

    Note the level of customizability in this solution:

    • The user has full control over the location of the custom JS and CSS files with respect to the auto-templated CSS and JavaScript files
    • The user can include custom meta tags in the <head/>. In the example, see the custom <title/> and custom <meta/> description.
    • The user can include custom HTML around their Dash app container (see the <div/> with My Custom Header)
    • The user can omit the templated tags if they want to supply their own front-end JavaScript bundles. This ties in nicely with the "Custom JavaScript Hooks" requirement: if the user adds their own hooks to a custom dash-renderer build, they could remove the default dash_renderer template variable and include their own version.
    • If the tags depend on the URL of the page, they could program in different values that depend on the flask.request.url variable.
  • allow optional header and footer

    allow optional header and footer

    This PR depends on html components having a HTML serializer, see https://github.com/plotly/dash-html-components/pull/29

    This PR simplifies adding custom JavaScript and CSS to Dash apps - a more flexible and declarative alternative to app.css.append_css and app.scripts.append_script

    Example usage:

    app.head = [
        html.Link(
            href='https://codepen.io/chriddyp/pen/bWLwgP.css',
            rel='stylesheet'
        ),
        ('''
        <style type="text/css">
        html {
            font-size: 50px;
        }
        </style>
        '''),
        html.Title(path)
    ]
    
    app.footer = [
        html.Script(type='text/javascript', children='alert("hello world")')
    ]
    

    app.head and app.footer can also be functions, which enables setting variables dynamically based off of the URL (i.e. unique page titles)

    def head():
        path = request.path
        return html.Title(path)
    
    app.head = head
    

    Unlike app.layout, app.head and app.footer are templated directly into the HTML (as HTML!) rather than generated in Dash’s front-end. This allows the components to be rendered immediately on page load rather than after page load (required for things like page title and meta descriptions and for preventing a “Flash of Unstyled Content” https://en.wikipedia.org/wiki/Flash_of_unstyled_content).

    This makes the components in app.head and app.footer different than the components in app.layout. In particular:

    • Callbacks can’t be applied to components rendered in app.head or app.footer
    • Only dash_html_components can be applied to the app.head and app.footer as these are the only valid HTML tags (a `dash_core_components.Graph is not a valid HTML tag, it’s a rich component generated by React.js with dynamic javascript and CSS)

    Fixes #https://github.com/plotly/dash/issues/170 and several issues brought up in the dash community forum (https://community.plot.ly/c/dash)

  • Improve Callback Graph

    Improve Callback Graph

    Attempt to improve and significantly expand the features available in the callback graph to improve its usefulness in debugging and testing. Will try to cover the ideas given in https://github.com/plotly/dash/issues/1176. Comments/suggestions would be welcome, especially for styling.

    Current Status

    captured (1)

    captured (2)

    Changes

    • Replaced viz.js with cytoscape.js via react-cytoscape. This results in some minor visual and layout changes.
    • CallbackGraphContainer now subscribes to layout and paths so it can introspect the current state.
    • Added new reducers to compute profiling information and report all changed props (not just those that are inputs).

    Issues

    • State layout is finicky. dagre was giving horrible results even when cycles were pruned away. Using breadthfirst for now, but layout properties may need to be tailored to viewport size instead of being fixed.
    • Outputs that return no_update are still being flashed during execution highlighting. No way to detect them right now.

    Contributor Checklist

    • [ ] I have broken down my PR scope into the following TODO tasks
      • [X] Zoom in/out functionality for large/complex callback chains
      • [ ] Callback graph accessible from a dedicated url.
      • [X] Distinguish between clientside and serverside callbacks using different node colors.
      • [x] Add state information to the callback graph
      • [x] Report profiling information
        • [x] Number of times a callback was invoked per node
        • [x] Time spent (total or average) in the callback. Maybe link to the node color?
        • [ ] Label each edge with the number of times that input triggered a callback
      • [ ] Live introspection
        • [X] Components, properties, and callback inputs/outputs are inspect-able in real time.
        • [ ] Component properties are modifiable.
      • [ ] Live debugging
        • [x] Highlight currently executing callbacks and modified outputs
        • [ ] Probe the last input/output by hovering/focusing an edge
        • [ ] Manually emit a property changed event to trigger callback paths
    • [x] I have run the tests locally and they passed. (refer to testing section in contributing)
    • [x] I have added tests, or extended existing tests, to cover any new features or bugs fixed in this PR

    optionals

    • [x] I have added entry in the CHANGELOG.md
    • [ ] If this PR needs a follow-up in dash docs, community thread, I have mentioned the relevant URLS as follow
      • [ ] this github #PR number updates the dash docs
      • [ ] here is the show and tell thread in plotly dash community
  • Plotly express scatter_mapbox does not show map[BUG]

    Plotly express scatter_mapbox does not show map[BUG]

    I am trying to insert a scatter_mapbox map with openstreetmap layer following this example:

    https://plot.ly/python/mapbox-layers/#openstreetmap-tiles-no-token-needed

    But I only get a blank figure. scatter_geo works normally. The above example works in a Jupyter notebook but not in m dash app

    Is this a known bug?

  • Graph edit queue

    Graph edit queue

    Plotly.js rendering in dcc.Graph can be async - more so now that we support MathJax in Dash, though there were always some async things like loading geojson. Anyway this hasn't caused any problems in core dash that I'm aware of, but in dash-design-kit, which wraps dcc.Graph and passes some information back and forth for theming purposes, extendData and prependData could cause two render cycles to overlap and drop the new data. This ensures the plotly.js method calls are sequenced properly, even if they end up delayed relative to the React renders. In my testing the changes here fix DDK (separate PR coming there) and it may fix some as-yet-undiscovered bugs in core DCC.

    • [x] I have run the tests locally and they passed. (refer to testing section in contributing)
    • [x] I have added entry in the CHANGELOG.md
  • [BUG] Can't define components in submodules

    [BUG] Can't define components in submodules

    Describe your context

    dash==2.6.1
    dash-bootstrap-components==1.2.1
    dash-core-components==2.0.0
    dash-html-components==2.0.0
    dash-table==5.0.0
    

    Describe the bug

    I have an application that is deployed using a namespace package. It has multiple parts, and each of them is a different package, but all of them in the same namespace:

    my_namespace.scripts holds data retrieval scripts, while my_namespace.web holds the dash application to show the data. I also created a new package to hold the components, called my_namespace.components. This means that there's no __init__.py inside the my_namespace folder.

    I can import components like from my_namespace.components import MyComponent, but when I visit the webpage it raises an Error: <my components namespace name> was not found. This is because the script needed is not loaded. And the script is not loaded because the module my_namespace.components is not added to the registry (see line 38).

    https://github.com/plotly/dash/blob/0df861f212cbd4a55dcbf77f64c1a1bffedb0bc7/dash/development/base_component.py#L33-L50

    Expected behavior

    To be able to define my components in a namespace package, like dash does with dash.html and dash.dcc

  • [BUG] Flask contexts not available inside background callback

    [BUG] Flask contexts not available inside background callback

    Describe your context

    dash                              2.6.1
    dash-core-components              2.0.0
    dash-html-components              2.0.0
    dash-table                        5.0.0
    
    

    Describe the bug

    Background callbacks don't have flask's app and request contexts inside.

    Expected behavior

    Background callbacks have flask's app and request contexts inside.

    So, after creating callback function and before providing them to the Celery, we should provide flask contexts inside this function to imitate the default callback behaviour

    with flask_app.app_context():
        return (copy_current_request_context(job_fn) if has_request_context() else job_fn)(*args, **kwargs)
    

    Any recommendations for now?

  • [BUG] multi_page layout (use_pages=True) won't recognize the pages if they are compiled .pyc files.

    [BUG] multi_page layout (use_pages=True) won't recognize the pages if they are compiled .pyc files.

    As mention in the title, it looks like dash only bats an eye for .py files. Am i doing something wrong or are .pyc files just not supported "yet"?

  • [Feature Request] Include type hints in function parameters?

    [Feature Request] Include type hints in function parameters?

    Hi,

    Static type checkers (mypy, pyright/pylance) are becoming increasingly popular in the python world. For now they don't work with Dash as there are no type annotations included with the library.

    From what I understand, python code for dash components as well as their docstrings are somehow transpiled from javascript? If so, adding type hints should be relatively straightforward as it appears that the docstrings already contain very detailed typing information. This would significantly improve QOL for users using type checkers (which includes the majority of the vscode userbase since vscode uses pylance by default).

    For reference, plotly has also started adding typing information to their functions - see for instance https://github.com/plotly/plotly.py/pull/3425#issuecomment-1117210067 .

Analytical Web Apps for Python, R, Julia, and Jupyter. No JavaScript Required.
Analytical Web Apps for Python, R, Julia, and Jupyter. No JavaScript Required.

Dash Dash is the most downloaded, trusted Python framework for building ML & data science web apps. Built on top of Plotly.js, React and Flask, Dash t

Feb 18, 2021
Python & Julia port of codes in excellent R books

X4DS This repo is a collection of Python & Julia port of codes in the following excellent R books: An Introduction to Statistical Learning (ISLR) Stat

Jun 21, 2022
Visual Python is a GUI-based Python code generator, developed on the Jupyter Notebook environment as an extension.
Visual Python is a GUI-based Python code generator, developed on the Jupyter Notebook environment as an extension.

Visual Python is a GUI-based Python code generator, developed on the Jupyter Notebook environment as an extension.

Sep 21, 2022
IPython/Jupyter notebook module for Vega and Vega-Lite
IPython/Jupyter notebook module for Vega and Vega-Lite

IPython Vega IPython/Jupyter notebook module for Vega 5, and Vega-Lite 4. Notebooks with embedded visualizations can be viewed on GitHub and nbviewer.

Sep 11, 2022
Drag’n’drop Pivot Tables and Charts for Jupyter/IPython Notebook, care of PivotTable.js

pivottablejs: the Python module Drag’n’drop Pivot Tables and Charts for Jupyter/IPython Notebook, care of PivotTable.js Installation pip install pivot

Sep 3, 2022
IPython/Jupyter notebook module for Vega and Vega-Lite
IPython/Jupyter notebook module for Vega and Vega-Lite

IPython Vega IPython/Jupyter notebook module for Vega 5, and Vega-Lite 4. Notebooks with embedded visualizations can be viewed on GitHub and nbviewer.

Feb 12, 2021
Drag’n’drop Pivot Tables and Charts for Jupyter/IPython Notebook, care of PivotTable.js

pivottablejs: the Python module Drag’n’drop Pivot Tables and Charts for Jupyter/IPython Notebook, care of PivotTable.js Installation pip install pivot

Feb 11, 2021
High performance, editable, stylable datagrids in jupyter and jupyterlab
High performance, editable, stylable datagrids in jupyter and jupyterlab

An ipywidgets wrapper of regular-table for Jupyter. Examples Two Billion Rows Notebook Click Events Notebook Edit Events Notebook Styling Notebook Pan

Aug 31, 2022
Plotting library for IPython/Jupyter notebooks
Plotting library for IPython/Jupyter notebooks

bqplot 2-D plotting library for Project Jupyter Introduction bqplot is a 2-D visualization system for Jupyter, based on the constructs of the Grammar

Sep 23, 2022
An interactive GUI for WhiteboxTools in a Jupyter-based environment
An interactive GUI for WhiteboxTools in a Jupyter-based environment

whiteboxgui An interactive GUI for WhiteboxTools in a Jupyter-based environment GitHub repo: https://github.com/giswqs/whiteboxgui Documentation: http

Sep 25, 2022
Plotting library for IPython/Jupyter notebooks
Plotting library for IPython/Jupyter notebooks

bqplot 2-D plotting library for Project Jupyter Introduction bqplot is a 2-D visualization system for Jupyter, based on the constructs of the Grammar

Sep 22, 2022
A Jupyter - Three.js bridge
A Jupyter - Three.js bridge

pythreejs A Python / ThreeJS bridge utilizing the Jupyter widget infrastructure. Getting Started Installation Using pip: pip install pythreejs And the

Sep 23, 2022
Plotting library for IPython/Jupyter notebooks
Plotting library for IPython/Jupyter notebooks

bqplot 2-D plotting library for Project Jupyter Introduction bqplot is a 2-D visualization system for Jupyter, based on the constructs of the Grammar

Feb 18, 2021
A Jupyter - Three.js bridge
A Jupyter - Three.js bridge

pythreejs A Python / ThreeJS bridge utilizing the Jupyter widget infrastructure. Getting Started Installation Using pip: pip install pythreejs And the

Feb 17, 2021
Render Jupyter notebook in the terminal
Render Jupyter notebook in the terminal

jut - JUpyter notebook Terminal viewer. The command line tool view the IPython/Jupyter notebook in the terminal. Install pip install jut Usage $jut --

Aug 13, 2022
A Jupyter - Leaflet.js bridge
A Jupyter - Leaflet.js bridge

ipyleaflet A Jupyter / Leaflet bridge enabling interactive maps in the Jupyter notebook. Usage Selecting a basemap for a leaflet map: Loading a geojso

Sep 21, 2022
Draw datasets from within Jupyter.
Draw datasets from within Jupyter.

drawdata This small python app allows you to draw a dataset in a jupyter notebook. This should be very useful when teaching machine learning algorithm

Sep 7, 2022
ipyvizzu - Jupyter notebook integration of Vizzu
ipyvizzu - Jupyter notebook integration of Vizzu

ipyvizzu - Jupyter notebook integration of Vizzu. Tutorial · Examples · Repository About The Project ipyvizzu is the Jupyter Notebook integration of V

Sep 20, 2022
BrowZen correlates your emotional states with the web sites you visit to give you actionable insights about how you spend your time browsing the web.
BrowZen correlates your emotional states with the web sites you visit to give you actionable insights about how you spend your time browsing the web.

BrowZen BrowZen correlates your emotional states with the web sites you visit to give you actionable insights about how you spend your time browsing t

Aug 9, 2022