[Dash + Flask] How to Deploy a Python Dash App on Pythonanywhere.com

Here’s the step-by-step approach of how to deploy your Dash app on Pythonanywhere.com using Flask and pip:

  • Create an account on Pythonanywhere.com.
  • Create a Flask application.
  • Create a Dash application.
  • Copy the Dash app into the Flask app.
  • Connect the Flask server with the Dash app.
  • Modify the WSGI configuration file.
  • Install Dash with pip in your bash shell (e.g., pip3.7 install dash --user)
  • Refresh your Flask server.

How to Integrate Dash with Your Existing App

Do you have an existing non-dash app and you want to integrate a dashboard within it?

Disclaimer: If you ask me, this isn’t the best idea. Can’t you keep your website clean and simple? One page for one intent. Do you really have to integrate a full-fledged Dash application within this particular web app? Before you answer: yes!, please consider the following: you can always embed interactive graphs with JavaScript.

For instance, a great alternative would be CanvaJS. I’m not affiliated with those guys but they created a great framework that can be used on any website. Heck, you could even use Plotly graphs on your website to visualize data. (These are the creators of Dash.)

The reason why I don’t advocate to use dash in your existing (HTML/CSS/JS) application is that it’s tedious, error prone, and it slows down your website.

I’ll give you three ways—ordered by difficulty:

1 – Place Links Intelligently

Believe it or not, I came up with this genius strategy all by myself. Instead of integrating your app with Dash, you just link to your separate (independent) Dash app so that it appears like the two websites (your original and the Dash app) are working together and are tightly integrated. However, they’re running independently and you can avoid all the struggles and keep living the simple life.

2 – Use iFrames

On the official Dash site to this issue, they recommend to use an <iframe>. An iFrame is an HTML element that allows you to embed any website Y on website X. It’s like a window into the other website. On page X, you can define the size of the window and the environment around the window. But you can control little more.

While this may work theoretically, it often slows down websites and causes security issues. Some web browsers block the use of iFrames altogether. So, it may happen that users don’t even see your great Dash application!

Do you still want to try it with iFrames? Okay, so go for it:

  • Include an <iframe> element in your HTML site.
  • Point the src attribute towards the address of your Dash app.
  • Place your Dash app iFrame within your website defining your desired dimensions:
<iframe src="http://localhost:8050" width=1200 height=800></iframe>

Here’s how such an embedded iFrame Dash app looks on the Finxter website:

It doesn’t look pretty, does it?

Using an Existing Flask App

Yes, all the programmers out there are salivating. It’s just beautiful to natively integrate two apps, isn’t it? Well, if you think so. I think, it’s a big mess and you’ll curse yourself for doing it. However, if you must do it, here’s how you can do it (based on this resource and the docs):

Access the Flask app via app.server and assign it to a variable (e.g., server).

import dash
app = dash.Dash(__name__)
server = app.server

As an alternative, pass your Flask app instance into Dash when instantiating the app in the dash.Dash(...) initialization routine.

import flask
server = flask.Flask(__name__)
app = dash.Dash(__name__, server=server)

What did you accomplish? The server variable now holds the Flask instance. This allows you to add any route and custom functionality like this:

@server.route('/hello')
def hello():
    return 'Hello, World!'

You can see such an example in the code given here:

from flask import Flask
from dash import Dash
import dash_core_components as dcc
import dash_html_components as html


server = Flask(__name__)
app = dash.Dash(
    __name__,
    server=server,
    url_base_pathname='/dash'
)

app.layout = html.Div(id='dash-container')

@server.route("/dash")
def my_dash_app():
    return app.index()

But the authors of the code share the same disclaimer: it sucks! You lose a lot of integrated Flask functionality when working from inside Dash like this.

Maybe go back to method 1? A better way is to use Dash from inside Flask—instead of using Flask from inside Dash. You can see how this works here (scroll down to the heading “Combining One or More Dash Apps with Existing WSGI Apps”).