📣 Dash 1.3.0 released

Update: version 1.16 has been released since this was posted.

Changelog

Or check out the release for all relevant entries under one roof.

Highlights

  • Persistence
  • Table loading state
  • Simplified cell styling for text ellipsis and wrapping. docs

Previous Releases

Code Examples

Persistence
Run this app, modify the input’s value, the table’s filter / sort order / header name and reload the page, your changes will be re-applied to the new session.

To use, simply add persisted=True to the components that support the new prop: Checklist, DatePickerRange, DatePickerSingle, Dropdown, Input, RadioItems, RangeSlider, Slider, Tabs, Textarea and the DataTable.

import dash

from dash_html_components import Div
from dash_core_components import Input
from dash_table import DataTable

app = dash.Dash(__name__)

app.layout = Div([
    Input(
        id='input',
        value='Default value',
        persistence=True
    ),
    DataTable(
        id='table',
        columns=[{
            'name': x,
            'id': x,
            'selectable': True
        } for x in ['a', 'b', 'c']],
        data=[{
            'a': str(x),
            'b': x,
            'c': str(x*x)
        } for x in range(0,20)],
        editable=True,
        filter_action='native',
        persistence=True,
        sort_action='native',
        row_selectable='multi',
        row_deletable=True
    )
])

if __name__ == '__main__':
    app.run_server(debug=True)

Table loading state
Run this app and press the freeze button. The callback is artificially lengthen to take 5 seconds to return. Since it’s returning the data prop, it will prevent further modifications to the table while it’s not completed. This prevents having multiple callbacks modifying the data and causing unpredictable behavior.

If there’s no callback on data, the table does not freeze itself.

import json
import time

import pandas as pd

import dash
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate

from dash_table import DataTable, FormatTemplate
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([
    html.Button(
        id='btn',
        children='Freeze table'
    ),
    DataTable(
        id='table',
        columns=[{
            'name': x,
            'id': x,
            'selectable': True
        } for x in ['a', 'b', 'c']],
        editable=True,
        data=[{
            'a': 'a' + str(x),
            'b': 'b' + str(x),
            'c': 'c' + str(x)
        } for x in range(0,20)]
    )
])

@app.callback(
    [Output('table', 'data')],
    [Input('btn', 'n_clicks')],
    [State('table', 'data')]
)
def update_styles(n_clicks, data):
    if n_clicks is None:
        raise PreventUpdate

    time.sleep(5)
    return data,

if __name__ == '__main__':
    app.run_server(debug=True)
4 Likes

Thanks again for the hardwork!

There’s a few apps I can go through now and clear out a manual version of the persistence feature where I was using a callback and the store, this should mean less code, higher performance, less bugs :slight_smile:

2 Likes

For Dash App developers

One bonus feature we got from reducing the dash-renderer pypi size PR is that you can now play with the official React profiler extensions (debug=True) to understand better where is your performance bottleneck.

4 Likes