72

I have an existing Flask app, and I want to have a route to another app. More concretely, the second app is a Plotly Dash app. How can I run my Dash app within my existing Flask app?

@app.route('/plotly_dashboard') 
def render_dashboard():
    # go to dash app

I also tried adding a route to the Dash instance, since it's a Flask app, but I get the error:

AttributeError: 'Dash' object has no attribute 'route'
davidism
  • 121,510
  • 29
  • 395
  • 339
zthomas.nc
  • 3,689
  • 8
  • 35
  • 49

5 Answers5

77

From the docs:

The underlying Flask app is available at app.server.

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

You can also pass your own Flask app instance into Dash:

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

Now that you have the Flask instance, you can add whatever routes and other functionality you need.

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

To the more general question "how can I serve two Flask instances next to each other", assuming you don't end up using one instance as in the above Dash answer, you would use DispatcherMiddleware to mount both applications.

dash_app = Dash(__name__)
flask_app = Flask(__name__)

application = DispatcherMiddleware(flask_app, {'/dash': dash_app.server})
EricLavault
  • 12,130
  • 3
  • 23
  • 45
davidism
  • 121,510
  • 29
  • 395
  • 339
39

Set url_base_pathname in your Dash instance.

app_flask = flask.Flask(__name__)

app_dash = dash.Dash(__name__, server=app_flask, url_base_pathname='/pathname')

Now you can redirect to your Plotly Dashboard app under any Flask routes you want.

@app_flask.route('/plotly_dashboard') 
def render_dashboard():
    return flask.redirect('/pathname')
davidism
  • 121,510
  • 29
  • 395
  • 339
chanioxaris
  • 946
  • 10
  • 9
  • 7
    Let me point out just one thing that I stumbled upon: in your main you should then run the app_flask. I know it may be obvious, but it may save some minutes to beginners like me – Tommaso Guerrini May 10 '20 at 08:26
20

Ok for those who are lazy enough like me, here is the code

from dash import Dash
from werkzeug.wsgi import DispatcherMiddleware
import flask
from werkzeug.serving import run_simple
import dash_html_components as html

server = flask.Flask(__name__)
dash_app1 = Dash(__name__, server = server, url_base_pathname='/dashboard' )
dash_app2 = Dash(__name__, server = server, url_base_pathname='/reports')
dash_app1.layout = html.Div([html.H1('Hi there, I am app1 for dashboards')])
dash_app2.layout = html.Div([html.H1('Hi there, I am app2 for reports')])
@server.route('/')
@server.route('/hello')
def hello():
    return 'hello world!'

@server.route('/dashboard')
def render_dashboard():
    return flask.redirect('/dash1')


@server.route('/reports')
def render_reports():
    return flask.redirect('/dash2')

app = DispatcherMiddleware(server, {
    '/dash1': dash_app1.server,
    '/dash2': dash_app2.server
})

run_simple('0.0.0.0', 8080, app, use_reloader=True, use_debugger=True)
JustInTime
  • 2,716
  • 5
  • 22
  • 25
  • 4
    I tried your code . it looked like what I was looking for as a test case. I get the following: /usr/local/lib/python3.7/site-packages/flask/app.py", line 1107, in register_blueprint blueprint, self.blueprints[blueprint.name], blueprint.name AssertionError: A name collision occurred between blueprints and . Both share the same name "assets". Blueprints that are created on the fly need unique names. – user2945234 Aug 21 '18 at 18:05
  • Ran into the same problem. I notice that the method worked for one redirection, but not for two redirections to dask apps. I have no clue how the change the assets name. – Kehlin Swain Sep 25 '18 at 01:22
  • It seem that you have to take care of the flask version you use, I had two different experiences when using flask 1.0 and flask 0.12. – JustInTime Sep 28 '18 at 07:40
  • I used dispatch middleware from `werkzeug.middleware.dispatcher` because `werkzeug.wsgi` threw an error. Here is the [documentation link](https://flask.palletsprojects.com/en/1.1.x/patterns/appdispatch/) and code: `from werkzeug.middleware.dispatcher import DispatcherMiddleware` – william_drew_67 Feb 23 '21 at 21:58
  • Is it possible to pass data posted in a flask route to a dash callback triggering an update in a component (for example a plot)? If you'd like to suggest me to start a new question I already did but it was marked as duplicate.... https://stackoverflow.com/questions/69134233/how-to-share-data-from-a-flask-route-to-a-dash-callback – user11696358 Sep 13 '21 at 10:29
  • Since Dash 2.0 this pattern is not longer supported. Each Dash instance now sets up global state in the dash module, so only one Dash instance should be run in a process at time, otherwise you'll find things breaking in weird and surprising ways – nedned Jan 26 '23 at 12:25
0
#here are full codee
from dash import Dash
import flask
from dash import html

server = flask.Flask(__name__)
app = Dash(__name__, server=server, url_base_pathname='/ATM_Data_Anlaysis/')
app.layout = html.Div([html.H1('This Is head',style={'textAlign':'center'})])

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

if __name__ == '__main__':
    app.run_server(debug=True)
  • 2
    Welcome to Stack Overflow! While this code snippet may be the solution, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-‌​code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – holydragon Dec 23 '21 at 06:51
-4

To solve this issue, here is what I did and was successful. This should be documented in official DASH documentation

####################################
import dash_core_components as dcc
import dash_html_components as html
from dash import Dash
from dash.dependencies import Input, State, Output

from flask          import Flask, flash, redirect, render_template,    request, session, abort, url_for, json, make_response

url_router=''

@application.route("/view_tables", methods=['GET','POST'])
def view_tabales:
  # Logic for displaying dashboard using Dash
  server.layout = html.Div(
                    children=[
                    #division for graph 1
                    html.Div([html.H1(children='Capital Charge'),],className='text-center'),

                    html.Div([html.Div([html.H3(children='''Correlation for assets'''),],className='text-primary'),
                                # define the graph
                                dcc.Graph(
                                    id='Delta-graph',
                                    figure={
                                        'data': [
                                            {'x': df_delta['Correlation_Level'], 
                                             'y': df_delta['Capital_Charge'], 
                                             'type': 'bar', 
                                             'name': 'Delta',
                                             #'domain': {'x': [0, .48],'y': [0, .49]},
                                             }
                                        ],
                                        # sizes the graph
                                        'layout': {
                                            'title': 'Delta','margin': {'l': 10, 'r': 0, 't': 30, 'b': 10},
                                            "height":300,
                                        }
                                    }
                                )],className='col-md-4'),
  url_router = 'Dash(__name__,server=application, url_base_pathname="/dash")'

Then you can control which dashboard it is headed from inside flask

if url_router !='':
      server = url_router

server.layout = html.Div(children = [html.H1(children = ' MEP dashboard - error 404')])


# run the app.
if __name__ == "__main__":
   # Setting debug to True enables debug output. This line should be
   # removed before deploying a production app.
   server.secret_key = os.urandom(12)
   server.run_server(debug=True,port=5000)

you can create different functions with different graphs between the Flask code and keep calling the code in dash

Mandeep Singh
  • 174
  • 1
  • 8