.. _plotly-dash-service-reference: 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 in MVI. 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 on MVI. Plotly Dash application as a standalone service ----------------------------------------------- Let's get som fresh boiler-plate directories/files using the functionality provided by the MVI CLI: >>> mvi init # doctest: +SKIP Active host: http://your-host project_name [my_project]: plotly_dashboard The first thing we have to do is to add ``va-mvi`` to the `requirements.txt` file so that it looks like this:: va-mvi dash The next step is to take our application source code and put it into `service.py`. We also make a few minor tweaks to the application code according to below. Lets add an import of mvi at the top:: import mvi When creating the `app`-object we also need to tell Dash that it will be running under some custom `root_path` (aka `base_path`) like so:: app = dash.Dash( __name__, requests_pathname_prefix=mvi.utilities.get_service_root_path(), ) And finally, 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 mvi import dash import dash_html_components as html app = dash.Dash( __name__, requests_pathname_prefix=mvi.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: >>> mvi deploy plotly_dashboard 1.0.0 ./plotly_dashboard --port 8050 # doctest: +SKIP 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:: MVI services created using the SDK use port 8000, which is the default port for ``mvi 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 MVI SDK service ``app``:: import mvi 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=mvi.utilities.get_service_root_path() + "dashboard/", ) app.layout = html.Div(children=[ html.H1(children='Hello World'), ]) # We mount the Dash app server under the mvi.service.app on the subpath `/dashboard` mvi.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__': mvi.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): >>> mvi deploy plotly_dashboard 1.0.0 ./plotly_dashboard # doctest: +SKIP 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/