Integrate multiple Dash apps into Flask

Viewed 1410

I`m trying to integrate multiple Dash apps into a Flask application, but not able to do so.

I was able to integrate one Dash app into Flask, using the following structure:

dashboard1.py

def create_dashboard(server):
    dash_app = dash.Dash(server=server,
                         routes_pathname_prefix='/dash1/',
                         external_stylesheets=[dbc.themes.BOOTSTRAP], 
                
                         )

     ....
     return dash_app.server

init.py

from flask import Flask
from flask_assets import Environment


def create_app():
    """Construct core Flask application with embedded Dash app."""
    f_app = Flask(__name__, instance_relative_config=False)
    f_app.config.from_object('config.Config')
    assets = Environment()
    assets.init_app(f_app)

    with f_app.app_context():
        # Import parts of our core Flask app
        from . import routes
        from .assets import compile_static_assets

        # Import Dash application
        from .plotlydash.dashboard import create_dashboard
        app = create_dashboard(f_app)        
    
        # Compile static assets
        compile_static_assets(assets)

        return app

routes.py

from flask import render_template, redirect
from flask import current_app as app
 @app.route('/dash1')
 def dash1(): 
    return render_template('dash1.html', app_data=app_data)

app.py

from application import create_app
app= create_app()        
if __name__ == "__main__":
    app.run(host='0.0.0.0', debug=True)

Everything is working fine with the first Dash app. I want to create another menu/tab in the application and integrate a second dash app. How could I do this? I have tried the following but it has not resulted successful. Only the link of the first app works.

dashboard2.py

def create_dashboard2(server):
    dash_app = dash.Dash(server=server,
                         routes_pathname_prefix='/dash2/',
                         external_stylesheets=[dbc.themes.BOOTSTRAP], 
                
                         )

     ....
     return dash_app.server

init.py

from flask import Flask
from flask_assets import Environment


def create_app():
    """Construct core Flask application with embedded Dash app."""
    f_app = Flask(__name__, instance_relative_config=False)
    f_app.config.from_object('config.Config')
    assets = Environment()
    assets.init_app(f_app)

    with f_app.app_context():
        # Import parts of our core Flask app
        from . import routes
        from .assets import compile_static_assets

        # Import Dash application
        from .plotlydash.dashboard1 import create_dashboard
        from .plotlydash.dashboard2 import create_dashboard2
        app = create_dashboard(f_app)     
        app2 = create_dashboard2(f_app)      
    
        # Compile static assets
        compile_static_assets(assets)

        return app, app2

routes.py

from flask import render_template, redirect
from flask import current_app as app
@app.route('/dash1')
def dash1(): 
    return render_template('dash1.html', app_data=app_data)
@app.route('/dash2')
def dash2(): 
    return render_template('dash2.html', app_data=app_data)

app.py

from application import create_app
app, app2= create_app()        
if __name__ == "__main__":
    app.run(host='0.0.0.0', debug=True)
    app2.run(host='0.0.0.0', debug=True)

Could you please help me with some pointer/indications of what I might be doing wrong?

1 Answers

To answer @mLstudent33's question about callbacks initialization in the comments - there is a good blog post about it - https://hackersandslackers.com/plotly-dash-with-flask.

I followed their instructions and this worked for me:

For example, dashboard1.py:

def create_dashboard(server):
    dash_app = dash.Dash(
        server=server,
        routes_pathname_prefix='/dash1/',
        external_stylesheets=[dbc.themes.BOOTSTRAP], 
    )

    dash_app.layout = html.Div([
        # ... Layout stuff
    ])

    # Initialize callbacks after our app is loaded
    # Pass dash_app as a parameter
    init_callbacks(dash_app)

    return dash_app.server


def init_callbacks(dash_app):
    @dash_app.callback(
    # Callback input/output
    ....
    )
    def update_graph(rows):
        # Callback logic
        # ...
Related