dash
Application BoilerplateSince I first started using dash
in production environments, I have developed a recipe that allows for faster deployment that also scales well for different business needs. Let’s start by looking at the folder structure that I use:
repository-name/
.gitignore
LICENSE.txt
assets/
styles.css
favicon.ico
app.py
gunicorn.conf.py
Procfile
requirements.txt
Let’s break down the contents of each file…
.gitignore
The stuff we don’t want in our repository. Instead of using Github’s boilerplate, I tend to keep the content very minimal.
venv
*.pyc
.DS_Store
.env
.cache/
__pycache__/
cache-directory/
requirements.txt
Contains the required dependencies and version criteria. Typically, this is generated from pip -m freeze > requirements.txt
app.py
This is your main Dash application. I tend to keep all dashboard elements in one file instead of having multiple imports.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from dash import html
from dash import dcc
from dash import Dash
from dash import Input
from dash import Output
from dash import State
app = Dash(__name__)
server = app.server
app.layout = html.Div(
# layout elements go here
)
# application callbacks
if __name__ == ‘__main__’:
app.run_server(debug=False)
Procfile
Contains a list of process types for an app. This is required for deployment platforms, such as Heroku. For my purposes, I typically specify Gunicorn, which is a WSGI HTTP server.
web: gunicorn -c gunicorn.conf.py app:server
gunicorn.conf.py
This is where I handle my server instantiation and configuration using Gunicorn.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import multiprocessing
chdir = ‘/root’
bind = ‘:80’
workers = multiprocessing.cpu_count() * 2 + 1
threads = multiprocessing.cpu_count() * 2 + 1
worker_connections = 1000 * workers
errorlog = ‘/tmp/gunicorn.log’
loglevel = ‘warning’
And that’s it! I hope someone just getting started with Dash applications found this helpful. If you have any feedback or suggestions on how I could improve this boilerplate further, feel free to email me!