Library to simplify building Plotly Dash applications
Project description
Simple Dash
Simple Dash is a library that simplifies building applications with Plotly Dash by allowing you to attach data directly to the layout and creating all the necessary callback functions under the hood.
Installation
pip install simpledash
Tutorial
Simplest example - using Input object in the layout
Let's create an app with single Input
component, that renders back whatever the user has typed in.
from simpledash.callbacks import setup_callbacks
app.layout = html.Div([
dash_core_components.Input(id='data-input', className='row'),
# with Simple Dash you can use a dash dependency object directly in the layout
# it will be replaced by actual `data-input.value` and updated every time it changes
html.Div(dash.dependencies.Input('data-input', 'value'), className='row', id='output-div')
])
setup_callbacks(app) # this will scan the layout and create all necessary callback functions
As you can see, no callbacks were explicitly defined and the code is clean and simple.
What happened? The setup_callbacks
method has scanned the app's layout, found all occurrences of dash.dependencies.Input
and created a callback functions for them.
More complex example - data functions with data_provider
decorator
We would like to have two Inputs (named A and B) and let user decide which one is going to be used for rendering the output value. This choice will be done via dropdown.
import dash_core_components as dcc
from dash.dependencies import Input
from simpledash.data.data_providers import data_provider
input_a = dcc.Input(id='data-input-a', value="")
input_b = dcc.Input(id='data-input-b', value="")
input_chooser = dcc.Dropdown(id='input-chooser', options=options_from(['A', 'B']))
# use a `data_provider` annotation to indicate, that the method provides data based on inputs
# inputs used by function are declared as arguments to the decorator
# and are later on passed to the function as arguments
@data_provider(Input('data-input-a', 'value'), Input('data-input-b', 'value'), Input('input-chooser', 'value'))
def output_value(input_a_value, input_b_value, input_chooser_value):
if input_chooser_value == "A":
return input_a_value
if input_chooser_value == "B":
return input_b_value
return ""
app.layout = html.Div([
html.Div(["A: ", input_a], className='row'),
html.Div(["B: ", input_b], className='row'),
html.Div(["Which one to show? ", input_chooser], className='row'),
html.Br(),
# you simply use `data_provider` instance in the layout (as in previous example)
html.Div(["Here's the output: ", output_value], className='row', id='output'),
# but you can also run some simple operations on `data_provider`, like `upper()`
html.Div(["Also in uppercase!: ", output_value.upper()], className='row', id='output-upper')
])
setup_callbacks(app)
This time we have used data_provider
decorator to declare the function that is able to provide data based on inputs. Note, that this is a plain python function, so you should be able to do any operation on inputs, regardless of the complexity.
Interesting thing we see in the example is output_value.upper()
. This is just a syntax sugar
that Simple Dash gives you - instead of writing another data_provider
to do the uppercasing,
we can call the method directly on output_value
(and this will create new data_provider
under the hood for you).
Please note that the set of operations you are able to do on data_provider
instance are limited to:
- accessing the property (
output_value.xyz
) - accessing the item by index (
output_value['xyz']
) - calling the method (
output_value.xyz("param")
)
Nesting data_provider
s
Let's say you'd like to replicate the output_value.upper()
behavior from previous example, but without syntax sugar, i.e. by defining new data_provider
directly.
The first option is to create a data_provider
that takes the same inputs as output_value
and passes values of those inputs to output_value
. Here's how it looks like:
@data_provider(Input('data-input-a', 'value'), Input('data-input-b', 'value'), Input('input-chooser', 'value'))
def uppercase_output_value_1(input_a_value, input_b_value, input_chooser_value):
v = output_value(input_a_value, input_b_value, input_chooser_value)
return v.upper()
The second option has much less boilerplate, because the whole data_provider
is specified as an input:
@data_provider(output_value)
def uppercase_output_value_2(v):
return v.upper()
What's next?
To see more advanced examples go to examples section of the repo.
FAQ
Is there a usage for data_provider
with no inputs?
Use data_provider
with no inputs when you've got a static, but time-consuming-to-calculate data. data_provider
will ensure laziness - i.e. that the function is called only if the component using it is being displayed to the user.
What is the performance of Simple Dash vs plain dash?
Performance hasn't been priority so far, so it's reasonable to expect Simple Dash to be slower. That being said - there's a room for improvement (for example - caching data_provider
's output) and we expect to tackle this issue in later releases.
What are the limitations when compared to plain dash?
Validators like to fail on data_provider
s, so in many cases you need to just stop using them.
To give you an example - this will not work:
dcc.Graph(figure={'data': [
graph_objects.Scattermapbox(lat=some_data_provider, ...)
]})
but this will:
dcc.Graph(figure={'data': [
dict(lat=some_data_provider, ...)
]})
Can I test it?
Absolutely. Any testing methods that worked for plain dash apps will work with this approach too.
Testing data providers is also pretty easy - they behave just like a methods, so you can call them in your test code.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file simpledash-0.2.2.tar.gz
.
File metadata
- Download URL: simpledash-0.2.2.tar.gz
- Upload date:
- Size: 8.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.15.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/45.3.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.5.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c4dc7fceb4e89f5e92d2b8fdf1f230122534f33276424b8bf995010524c39ca6 |
|
MD5 | 44d0d220bf52a3f7aff9bdc2b32530e1 |
|
BLAKE2b-256 | 8d2e1e2c1111d075b6e7d00728c8257c312d1e72d9227c96e32096d381804cae |