10 min read Author: klaas

Dash on Wheels

Update August 2021

PythonOnWheels 0.925.51 now supports Dash current. No specific version is required anymore.

So installing the requirements of a PythonOnWheels App will reIf you encounter any issues with the current DASH kibs at that time.  If you encounter any issues with a specific Dash lib version  please open an issue on github. It will help a lot.


Update November 2019

PythonOnWheels 0.916 now supports Dash 1.6.0

    dash==1.6.0 
dash-core-components==1.5.0
dash-daq==0.2.1
dash-html-components==1.0.1
dash-renderer==1.2.0
dash-table==4.5.0

Update July 2019

PythonOnWheels 0.912 now supports Dash 1.0.2

Thanks to Philip who pushed this in the dash community forum.

A Short Hands on Tutorial

By integrating Dash in PythonOnWheels you get the additional benefit to easily use the features of the framework, like:

PythonOnWheels idea is to take all the boilerplate from you and lets you really focus on your app and idea. So it's really quick to get from zero to a working app. In this hands-on tutorial we will create a short Dash application so you get a feeling how it works. 

Let's start to create our PoW Dash application

Installation:

Make sure that you install the current version of PythonOnWheels or update your Installation to the newest version. The Dash integration is supported from version 0.895b1. 

pip install -U pythononwheels

After installing you should have the generate_app script available.This installs the PythonOnWheels Application with the given name (-n) in the given path (-p). For this Dash test we will name our app dashtest. Choose any path you prefer.

generate_app -n dashtest -p <path>

Great. We now have a a PythonOnWheels application, named dashtest in the given <path>.

Create a virtualenv 

Switch to a directory before our app dir and create a virtualenv:

virtualenv dashtest

Then cd into the dashtest directory, activate the virtualenv

  • On Windows Scripts\activate 
  • And on Linux/OSX  source bin/activate

And install the PythonOnWheels requirements with

pip install -r requirements.txt

If you encounter problems to install numpy or pandas on windows I recommend using the Anaconda Python distro.

Now we can run the server to see the "hello PythonOnWheel's world" site:

python server.py

Point your browser to:

http://localhost:8080

That's it. You generated your first PyhtonOnWheels application that already calls a handler with the route / and returns the  bootstrap4 default welcome view. But we want to embedd Dash into our app. So let's do that. 

Let's embedd Dash into our application

Switch to the command line and end your server process. 

Then generate the dash integration

python generate_dash.py

The output shows you that PythonOnWheels generated the right handler, a bootstrap4 based view and the dash layout file as well as some helpers for us:

---------------------------------------- 
generating dash environment:
----------------------------------------
Copied : the view: dash_index.tmpl
rendered : handler/dash.py
rendered : pow_dash.py [This is the actual Dash layout and Dash app file]
Copied : the components file: dash_components.py
Requirements : dash_requirements.txt
----------------------------------------
Next Steps:
----------------------------------------
commandline : pip install -r dash_requirements.txt
commandline : python server.py
go to : http://localhost:8080/dash

The next steps section show us what to do. We need to install some additional python requirements for dash. Let's do that.

Install additional Dash requirements

pip install -r dash_requirements.txt

This can take something like 2 or 3 minutes since this installs numpy, pandas, dash and some dash utils. So meanwhile just read on and have and

Let's have a little deeper look into what was generated for us.

  • the handler that reacts on the URL localhost:8080/dash.
    • You can find that handler in handlers/dash_handler.py. It creates a route and action for the dash internal AJAX calls and one for the user (API) calls. In the end it renders the dash_index.tmpl view.
  • the bootrstrap view that embedds the Dash application
    • You can find that view (which is rendered by the handler above) in views/dash_index.tmpl
  • the Dash App.layout, which contains the actual dash layout and callbacks.
    • You can find it in the file pow_dash.py
  • I also integrated the helper components for column and row management from here in the dash community forum which easy your layout management when working with bootstrap.You can add other components as well, if you need them.
    • You can find them in the file: dash_components.py

And finally and most important the Dash App layout.

You can find it in the file: pow_dash.py. The _create_app() method is the place where your App layout goes. As you can see below it's a plain Dash layout file, nothing more, nothing less. In this case it's copy & pasted from the Dash User guide. Change and adapt to your needs. This would also be the place to use models to get DB Data instead of reading a csv for example. 

def _create_app_layout(*args, **kwargs):   
'''
Creates the actual dash application and layout
Just put any Dash layout in here.
Documentation and examples: https://dash.plot.ly/
The default route is: /dash which calls the handler/dash.py which creates the app
and renders the pow_dash template.
'''

df = pd.read_csv(
'https://raw.githubusercontent.com/plotly/'
'datasets/master/gapminderDataFiveYear.csv')
app.layout = html.Div([
dcc.Graph(id='graph-with-slider'),
dcc.Slider(
id='year-slider',
min=df['year'].min(),
max=df['year'].max(),
value=df['year'].min(),
marks={str(year): str(year) for year in df['year'].unique()},
step=None
)
])
@app.callback(
Output('graph-with-slider', 'figure'),
[Input('year-slider', 'value')])
def update_figure(selected_year):
filtered_df = df[df.year == selected_year]
traces = []
for i in filtered_df.continent.unique():
df_by_continent = filtered_df[filtered_df['continent'] == i]
traces.append(go.Scatter(
x=df_by_continent['gdpPercap'],
y=df_by_continent['lifeExp'],
text=df_by_continent['country'],
mode='markers',
opacity=0.7,
marker={
'size': 15,
'line': {'width': 0.5, 'color': 'white'}
},
name=i
))
return {
'data': traces,
'layout': go.Layout(
xaxis={'type': 'log', 'title': 'GDP Per Capita'},
yaxis={'title': 'Life Expectancy', 'range': [20, 90]},
margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
legend={'x': 0, 'y': 1},
hovermode='closest'
)
}
return app.layout

Now we are actually already done and can start the server again.

python server.py

Let's check the result 

Go to:

localhost:8080/dash

in your browser again and you should see the live view shown at the top of this article. 

Which is the second callback example taken from the dash userguide. While loading for the first time it'll fetch the csv data from github, so this also may take a few seconds. The csv fetching is already done by pandas using:

pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')

So this is basically it.

If you want to play around with the embedded Dash layout

  • just edit the dashtest/pow_dash.py file.

If you want to change the surrounding bootstrap view 

  • change the views/dash_index.tmpl or create a new one and change the render() directive in the handlers/dash_handler.py

Hope you see that it's pretty simple to get from zero to a nicely embedded Dash app in some minutes. Now take it to the next level and add Database support. It's pretty easy as well. Just read the Getting started  with NoSQL Models.  Or go to the documentation. 

Hope you enjoy PythonOnWheels. If you have any questions or remarks or errors you can open an issue on github or tweet to @pythononwheels. If you like PythonOnWheels give it a star on GitHub 

Credits

Go to: