Search code examples
pythonhtmliframeplotly-dash

HTML iframe with dash output


I have 2 pretty simple dashboards and I would like to run this two dashboards with flask using main.py for routing.

app1.py

import dash
from dash import html, dcc

app = dash.Dash(__name__)

app.layout = html.Div(
    children=[
        html.H1('App 1'),
        dcc.Graph(
            id='graph1',
            figure={
                'data': [{'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'App 1'}],
                'layout': {
                    'title': 'App 1 Graph'
                }
            }
        )
    ]
)

and

app2.py

import dash
from dash import html, dcc

app = dash.Dash(__name__)

app.layout = html.Div(
    children=[
        html.H1('App 2'),
        dcc.Graph(
            id='graph2',
            figure={
                'data': [{'x': [1, 2, 3], 'y': [2, 4, 1], 'type': 'bar', 'name': 'App 2'}],
                'layout': {
                    'title': 'App 2 Graph'
                }
            }
        )
    ]
)

main.py

# main_app.py
from flask import Flask, render_template
import app1
import app2

app = Flask(__name__)

@app.route('/')
def index():
    return 'Main App'

@app.route('/app1')
def render_dashboard1():
    return render_template('dashboard1.html')

@app.route('/app2')
def render_dashboard2():
    return render_template('dashboard2.html')

if __name__ == '__main__':
    app.run(debug=True)

dashboard1.html

<!-- dashboard1.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Dashboard 1</title>
</head>
<body>
    <h1>Dashboard 1</h1>
    <iframe src="/app1" width="1000" height="800"></iframe>
</body>
</html>

dashboard2.html

<!-- dashboard2.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Dashboard 2</title>
</head>
<body>
    <h1>Dashboard 2</h1>
    <iframe src="/app2" width="1000" height="800"></iframe>
</body>
</html>

structure

/
app1.py
app2.py
main.py
/templates
dashboard1.html
dashboard2.html

but when I run my main.py and route for app1 I can see frame for the app1 but there is no graph. Could someone please explain how to use iframe to for me to be able to see output?


Solution

  • I can't access the templates with your code, I think dask uses flask so this may be causing problems. What I have done is calling two dash apps and one flask app; this for main.py:

    from flask import Flask, render_template
    from app1 import create_app as create_app1
    from app2 import create_app as create_app2
    
    server = Flask(__name__)
    app1 = create_app1(server)
    app2 = create_app2(server)
    
    
    @server.route('/')
    def index():
        return 'Main App'
    
    
    def render_dashboard1():
        return render_template('dashboard1.html')
    
    
    def render_dashboard2():
        return render_template('dashboard2.html')
    
    
    if __name__ == '__main__':
        server.run(debug=True)
    

    Use the method create_app for each app, app1.py:

    import dash
    from dash import html, dcc
    
    
    def create_app(server):
        app = dash.Dash(server=server, routes_pathname_prefix='/app1/')
    
        app.layout = html.Div(
            children=[
                html.H1('App 1'),
                dcc.Graph(
                    id='graph1',
                    figure={
                        'data': [{'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'App 1'}],
                        'layout': {
                            'title': 'App 1 Graph'
                        }
                    }
                )
            ]
        )
    
        return app
    

    and app2.py (I changed y values to be sure it is reading the app2 template):

    import dash
    from dash import html, dcc
    
    
    def create_app(server):
        app = dash.Dash(server=server, routes_pathname_prefix='/app2/')
    
        app.layout = html.Div(
            children=[
                html.H1('App 2'),
                dcc.Graph(
                    id='graph2',
                    figure={
                        'data': [{'x': [1, 2, 3], 'y': [10, 10, 10], 'type': 'bar', 'name': 'App 2'}],
                        'layout': {
                            'title': 'App 2 Graph'
                        }
                    }
                )
            ]
        )
    
        return app
    

    and I can see both graphs correctly.