Flask's DispatcherMiddleware not playing nice with Plotly's Dash

3.8k views Asked by At

I have an existing Flask web app, and I want to incorporate an existing Dash app (a Plotly Flask app) into it. As Flask's documentation recommends, I am using DispatcherMiddleware thusly to make this happen:

flask_app = Flask(__name__) # App with both apps attached to it 
app = Flask(__name__) # Existing Flask App 
dash_app = Dash(__name__) # Dash app 

dash_app.config.supress_callback_exceptions = True

# Use DispatcherMiddleware to route separate apps into one
flask_app.wsgi_app = DispatcherMiddleware(app, {'/dash': dash_app.server})

We end up running flask_app:

if __name__ == "__main__":
    flask_app.run(debug=True)

However, when I head to 127.0.0.1:<port>/dash/, I get the following error to appear on the webpage:

enter image description here

I see the following in the console log:

127.0.0.1 - - [30/Aug/2017 11:11:02] "GET /dash HTTP/1.1" 301 -
127.0.0.1 - - [30/Aug/2017 11:11:02] "GET /dash/ HTTP/1.1" 200 -
127.0.0.1 - - [30/Aug/2017 11:11:03] "GET /_dash-layout HTTP/1.1" 404 -
127.0.0.1 - - [30/Aug/2017 11:11:03] "GET /_dash-dependencies HTTP/1.1" 404 

How can I get the layouts to load properly for my Dash app?

1

There are 1 answers

2
PeaceLeka On

This is how I overcame this problem. Not pretty but effective.

You need run.py:

from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.serving import run_simple
from server import server
from dash_app  import app as app1
from flask_app import app as app2

app = DispatcherMiddleware(server, 
                           {'/myflaskapp': app2})
if __name__ == '__main__':
    run_simple('localhost', 5000, app, use_reloader=True)

Your server.py will look like this:

from flask import Flask, render_template

server = Flask(__name__)

@server.route('/')
def server_root():
    return render_template('index.html')

Your dash_app.py:

import dash
from server import server
app = dash.Dash(name='mydash', sharing=True, server=server, url_base_pathname='/mydash')

And finally your flask_app.py:

from flask import Flask
app = Flask(__name__)
@app.route("/news")
def news():
    return render_template('news.html')

Your flask_app is at /myflaskapp/news

Your dash_app is at /mydash