Using Plotly Dash to build a dashboard
In this tutorial we will see how to create a service that serves a dashboard using Plotly Dash.We will not go into detail into how to use Plotly Dash itself, but rather how to deploy a Plotly Dash application with Daeploy.
Example Plotly Dash application
We will use a hello-world Plotly Dash application in this tutorial that simply prints Hello World. The code for this application looks like this:
import dash
import dash_html_components as html
app = dash.Dash(__name__)
app.layout = html.Div(
children=[
html.H1(children="Hello World"),
]
)
if __name__ == "__main__":
app.run_server(debug=True)
In order to run this application, our requirements.txt will look like:
dash
That is all you need to run this Plotly Dash application locally. Lets now have a look at making this example deployable and runnable with Daeploy.
Plotly Dash application as a standalone service
Let’s get som fresh boiler-plate directories/files using the functionality provided by the Daeploy CLI:
>>> daeploy init
project_name [my_project]: plotly_dashboard
To run the same dashboard on Daeploy only a few changes have to be made. First, when creating the app-object we must tell Dash that it will be running under some custom root_path (aka base_path):
import daeploy
app = dash.Dash(
__name__,
requests_pathname_prefix=daeploy.utilities.get_service_root_path(),
)
And when starting the server, we need to make sure that the Plotly Dash application accepts connections from others than localhost:
if __name__ == "__main__":
app.run_server("0.0.0.0")
The final application code should now look like this:
import dash
import dash_html_components as html
import daeploy
app = dash.Dash(
__name__,
requests_pathname_prefix=daeploy.utilities.get_service_root_path(),
)
app.layout = html.Div(
children=[
html.H1(children="Hello World"),
]
)
if __name__ == "__main__":
app.run_server("0.0.0.0")
We can now deploy the Plotly Dash app, like we would any other service, with one important difference. Plotly Dash, by default, use port 8050 to communicate so we have to explicitly set the port when deploying:
>>> daeploy deploy plotly_dashboard 1.0.0 ./plotly_dashboard --port 8050
Active host: http://your-host
Deploying service...
Service deployed successfully
MAIN NAME VERSION STATUS RUNNING
------ ---------------- --------- -------- -----------------------------------
* plotly_dashboard 1.0.0 running Running (since 2021-01-13 07:14:55)
Note
Daeploy services created using the SDK use port 8000, which is the default
port for daeploy deploy
. But when deploying other apps it might be necessary
to change it to not get a Bad Gateway.
Open http://your-host/services/plotly_dashboard/ and you should see your app there
Plotly Dash application as part of a SDK-based application
It is also possible to add a Plotly Dash application as a (sub-)part of an SDK-based
service. This is done by mounting the Plotly Dash server
on the SDK app
. In the
example below, we mount the Plotly Dash app
at the subpath /dashboard/
under the
Daeploy SDK service app
:
import daeploy
import dash
import dash_html_components as html
# We need a WSGIMiddleware to be the middleman between the asynchronous SDK app
# (based on FastAPI) and the synchronous Dash app (based on Flask). `starlette`
# is a dependency of FastAPI so it doesnt need to be added to the
# `requirements.txt`
from starlette.middleware.wsgi import WSGIMiddleware
# Creating Dash app object that can be used as usual to build you Dash application.
# We make sure to give it the correct path where it will be mounted
app = dash.Dash(
__name__,
requests_pathname_prefix=daeploy.utilities.get_service_root_path() + "dashboard/",
)
app.layout = html.Div(
children=[
html.H1(children="Hello World"),
]
)
# We mount the Dash app server under daeploy.service.app on the subpath `/dashboard`
daeploy.service.app.mount("/dashboard", WSGIMiddleware(app.server))
# And finally we start the service as we would with any other SDK-based service.
if __name__ == "__main__":
daeploy.service.run()
Assuming we deploy our service as such (note that we no longer need to specify a custom port number since we are using the SDK to actually run the application):
>>> daeploy deploy plotly_dashboard 1.0.0 ./plotly_dashboard
Active host: http://your-host
Deploying service...
Service deployed successfully
MAIN NAME VERSION STATUS RUNNING
------ ---------------- --------- -------- -----------------------------------
* plotly_dashboard 1.0.0 running Running (since 2021-01-13 07:14:55)
Your dashboard would then be available at http://your-host/services/plotly_dashboard/dashboard/