Multiple Dashboards?

@will - Does the approach outlined in https://plot.ly/dash/urls work for you? This is what I use on the Dash docs (https://plot.ly/dash, https://github.com/plotly/dash-docs).

In your case, this would look something like:

import dash
import dash_core_components as dcc
import dash_html_components as html

import app1
import app2
import app3
import app4

print(dcc.__version__) # 0.6.0 or above is required

app = dash.Dash()


app.layout = html.Div([
    # represents the URL bar, doesn't render anything
    dcc.Location(id='url', refresh=False),

    # content will be rendered in this element
    html.Div(id='page-content')
])


@app.callback(dash.dependencies.Output('page-content', 'children'),
              [dash.dependencies.Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/apps/app1':
         return html.Div('This is app 1')
    elif pathname == '/apps/app2':
         return html.Div('This is app 2')
    elif pathname == '/apps/category/app3':
         return html.Div('This is app 3')
    elif pathname == '/apps/category/app4':
         return html.Div('This is app 4')

Or, if you want to put these apps in separate files and import them, it would look something like:

- app.py
- index.py
- apps
   |-- __init__.py
   |-- app1.py
   |-- app2.py

app.py

import dash

app = dash.Dash()
server = app.server
app.config.supress_callback_exceptions = True

app.css.append_css({
    "external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})

index.py

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

from app import app
from apps import app1, app2


app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='page-content')
])


@app.callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/apps/app1':
         return app1.layout
    elif pathname == '/apps/app2':
         return app2.layout
    else:
        return '404'

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

__init__.py

# empty file

app1.py

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

from app import app

layout = html.Div([
    html.H3('App 1'),
    dcc.Dropdown(
        id='app-1-dropdown',
        options=[
            {'label': 'App 1 - {}'.format(i), 'value': i} for i in [
                'NYC', 'MTL', 'LA'
            ]
        ]
    ),
    html.Div(id='app-1-display-value'),
    dcc.Link('Go to App 2', href='/apps/app2')
])


@app.callback(
    Output('app-1-display-value', 'children'),
    [Input('app-1-dropdown', 'value')])
def display_value(value):
    return 'You have selected "{}"'.format(value)

app2.py

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

from app import app

layout = html.Div([
    html.H3('App 2'),
    dcc.Dropdown(
        id='app-2-dropdown',
        options=[
            {'label': 'App 2 - {}'.format(i), 'value': i} for i in [
                'NYC', 'MTL', 'LA'
            ]
        ]
    ),
    html.Div(id='app-2-display-value'),
    dcc.Link('Go to App 1', href='/apps/app1')
])


@app.callback(
    Output('app-2-display-value', 'children'),
    [Input('app-2-dropdown', 'value')])
def display_value(value):
    return 'You have selected "{}"'.format(value)

4 Likes

Awesome, @chriddyp. I’ve actually tried something similar yesterday but yours is neater - and works well for simple apps. But for one of my more complicated one (multiple figures, callbacks; about 20 radios/dropdowns) I get the same wsgi issue:

Error on request:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/werkzeug/serving.py", line 209, in run_wsgi
    execute(self.server.app)
  File "/usr/local/lib/python2.7/site-packages/werkzeug/serving.py", line 200, in execute
    write(data)
  File "/usr/local/lib/python2.7/site-packages/werkzeug/serving.py", line 168, in write
    self.send_header(key, value)
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py", line 412, in send_header
    self.wfile.write("%s: %s\r\n" % (keyword, value))
IOError: [Errno 32] Broken pipe
127.0.0.1 - - [21/Aug/2017 20:59:08] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:08] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:08] "GET /favicon.ico HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:08] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/Aug/2017 20:59:09] "POST /_dash-update-component HTTP/1.1" 200

The 200 response is repeated 6-10 times per second. I tried adding threaded=True to app.run_server() without luck; there must be something fundamentally wrong in my app. I’d share it here but it’s too sensitive unfortunately. I may pm you though, in case this is a common issue which may affect others (doubt it!)

Think your approach is on the right lines though. Will just have to start the app afresh

1 Like

For more complex, production-level apps, I recommend running the app behind gunicorn instead of the flask dev server. Like threading=True, this will run the app in a way that can process many requests in parallel. Unlike threading=True, it’s more robust and performant.

So:

$ gunicorn app:server

install gunicorn with pip install gunicorn. In this case, app refers to app.py and server refers to the variable server instead app.py. This is adapted from the instructions in deployment: Deploy Your Dash App | Dash for Python Documentation | Plotly

3 Likes

Thanks Chris. I did try with Gunicorn yesterday, but no joy. I’m going to forget about using this particular app inside a multi-page multi-URL app; it’s clearly too heavy / unwieldy / poorly written. Plan is to fire uwsgi once to handle the simpler apps, and again for this more complicated one.

Ideally, I believe we want to make it work with something like this:
http://uwsgi-docs.readthedocs.io/en/latest/Emperor.html

Combined with lazy start and timeout process termination - this seams to be a perfect setup, where each app is running in a separate python process, therefore avoiding potential memory issues, with one heavy app blocking everything else.
So far - I had only some luck with this setup (caused by some url path issues).

2 Likes

A post was split to a new topic: URLs with a url_base_pathname

Thanks Chris. Your post for setting up the multipage app using separate files was very useful to me. However, I am having problems getting dash_auth.BasicAuth working with this project structure. Using a similar project tree as you have listed above, I have the following:

app.py

import dash
import dash_auth

VALID_USERNAME_PASSWORD_PAIRS = [
    ['bob', 'loblaw']
]

app = dash.Dash('auth')
auth = dash_auth.BasicAuth(
    app,
    VALID_USERNAME_PASSWORD_PAIRS
]
server = app.server
app.config.suppress_callback_exceptions = True

Upon trying to run from index.py, I get the following error:

File ".../site-packages/dash_auth/auth.py", in line 16, in _overwrite_index
   original_index = self.app.server.view_functions['index']
KeyError: 'index'

which happens regardless of the order of the app.server and BasicAuth lines. Any thoughts?

A post was split to a new topic: Multiple Page App - Google App Engine

@chriddyp i was wondering if you or anyone else on this message board could assist me. I tried going the way of the tutorial you posted but to no avail {on how to create a multi-page Dash App} so I’m currently trying the other way {the method Vlad posted higher on this board}

My structure looks like this:

dash-project/
app1/
dash_1.py

app2/
dash_2.py

 ...

server.py
run.py

My run.py code is

from app import server as application
from app import app

import app_1.dash_1
import app_2.dash_2

My app.py code is:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap
from flask_mail import Mail
from flask_moment import Moment
from flask_login import LoginManager
from flask_pagedown import PageDown
from flask_migrate import Migrate, MigrateCommand
from flask_sslify import SSLify
from werkzeug.wsgi import DispatcherMiddleware
import os
import pandas as pd
import dash
import flask

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from analysis import *

server=flask.Flask(name)
app = dash.Dash(name)
app.config.suppress_callback_exceptions = True

app.css.append_css({
‘external_url’: ‘https://codepen.io/chriddyp/pen/bWLwgP.css
})

My dash_1.py code is

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import plotly.graph_objs as go
from analysis import *

from app import app, server

app = dash.Dash(name=‘dash_1’, sharing=True, url_base_pathname=’/dash_1’, csrf_protect=False)

app.config[‘suppress_callback_exceptions’]=True

df = pd.read_csv(’/Users/WilliamStevens/Documents/deplorable_snowflake/ds/app_1/main.csv’)

layout = html.Div([
dcc.Graph(
id='Senators ',
figure={
‘data’: [
go.Scatter(
x=df[df[‘candidate_name’] == i][‘contributor_individual’],
y=df[df[‘candidate_name’] == i][‘contributor_pac’],
#z=df[df[‘candidate_name’] == i][‘contributor_total’],
text=df[df[‘candidate_name’] == i][‘contributor_total’],
mode=‘markers’,
opacity=0.7,
marker={
‘size’: 15,
‘line’: {‘width’: 0.5, ‘color’: ‘white’}
},
name=i
) for i in df.candidate_name.unique()
],
‘layout’: go.Layout(
xaxis={‘title’: ‘Contributor’},
yaxis={‘title’: ‘Contributor’},
#margin={‘l’: 40, ‘b’: 40, ‘t’: 10, ‘r’: 10},
#legend={‘x’: 0, ‘y’: 1},
hovermode=‘closest’
)
}
)
])

layout = html.Div(children=[
html.H1(children='Senators '),

html.Div(children='''
    God Bless .
'''),

dcc.Graph(
    id='main.csv',
    figure={
        'data': [
        {'x':df['x'], 'y': df['sector'], 'type': 'bar'},
        {'x':df['y'], 'y': df['industr'], 'type': 'bar'},
        {'x':df['z'], 'y': df['contributor'], 'type': 'bar'},
        ],
        'layout': {
            'title': 'Let Them Eat Cake ...'
        }
    }
)

])

My dash_2.py code is

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd

from app import app, server

app = dash.Dash(name=‘dash_2’, sharing=True, url_base_pathname=’/dash_2’, csrf_protect=False)

app.config[‘suppress_callback_exceptions’]=True

df = pd.read_csv(’/Users/WilliamStevens/Documents/deplorable_snowflake/ds/app_2/slice.csv’)

layout = html.Div(children=[
html.H1(children=‘Barstool’),

html.Div(children='''
    One .
'''),

dcc.Graph(
    id='slice.csv',
    figure={
        'data': [
        {'x':df['Slice'], 'y': df['Score'], 'type': 'bar'},
        ],
        'layout': {
            'title': 'Bar'
        }
    }
)

])

When I run the app, all my other pages work except the /dash_1 & /dash_2 pages. Was wondering if you or anyone else could help out

Hi
I have the same problem i don’t know where i have to write this uwsgi --http 0.0.0.0:5000 --processes 4 --wsgi-file run.py

hi
where should i write this :uwsgi --http 0.0.0.0:5000 --processes 4 --wsgi-file run.py

@chriddyp, this is awesome. Thanks!
One question, how could I also render an html template if the pathname == ‘/about’

I’ve tried to add this to the index.py file:

elif pathname == ‘/about’:
@server.route(‘/about’)
def about():
return render_template(“about.html”)
else:
return ‘404’

It doesn’t return me an error, but simply the blank page.
Is there any solution by chance?

Hey! Did you manage to make it work ? I’m in the same situation, impossible to make it work.

Hi, you can see my example code for handle multiple dashboards.:slightly_smiling_face:

Good morning @bullybear .
Have you ever managed to get it to work? Also, any example of your main.csv and slice.csv files please? Thanks! :slight_smile:

Here is how you have multiple dashboards running at one time, each in different tabs on your preferred web browser:

In my code, plotlyMulti1 and plotlyMulti2 are just examples taken from the dash tutorial online so I could make this work. The only significant things you don’t see below are that in the code for both apps, I instantiated the app with url_base_pathname just like in the stack overflow example. Also, in a separate module, called “call_test” I do the flask import statement and create the server. I then import “call_test” in both plotlyMulti codes and in the one below. This works because importing variables from a module allows it to ask as a global variable between modules, so all three modules are utilizing the same server in memory.

import dash
import dash_html_components as html
from call_test import server

import plotlyMulti1 as app1
import plotlyMulti2 as app2

import webbrowser as wb



# Set-up endpoint 1
app_1 = app1.app#dash.Dash(__name__, server=server, url_base_pathname='/app1/')
app_1.layout = app1.app.layout#html.H1('App 1')

# Set-up endpoint 2
app_2 = app2.app#dash.Dash(__name__, server=server, url_base_pathname='/app2/')
app_2.layout = app2.app.layout#html.H1('App 2')

# Open URLs
wb.open('http://127.0.0.1:5000/app1')
wb.open('http://127.0.0.1:5000/app2')

# Run server
server.run()

I already success create dash multipage with 1 file, and multi dropdown too, but it takes 3000 lines, and make my self ‘lazy’ to fix something or try to add some page anymore.

now, I try to build new dashboard, which each page separate in different files.
can somebody review my code? It works no error, can change url, but the layout wouldn’t change…

my structure file:

+assets

  • logo.png
  • backgroud.png
  • reset.css

+menu

  • dashboard1.py
  • dashboard2.py
  • dashboard3.py
  • dashboard4.py
  • style.py

app.py
dashboard.py

script:

app.py

import dash
app = dash.Dash(__name__, suppress_callback_exceptions=True,assets_external_path='assets/')
server = app.server

app.scripts.config.serve_locally = True

dashboard.py

import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import pandas as pd

from app import app, server

from menu.dashboard1 import *
from menu.dashboard2 import *
from menu.dashboard3 import *
from menu.dashboard4 import *

app.scripts.config.serve_locally = True
app.config.suppress_callback_exceptions = True


start = server

sdbar = html.Div([])
ctnt = html.Div([])

def isi_sidebar():
    sidebar = html.Div([
              sdbar
              ], id='main_sidebar')
    return sidebar

def isi_content():
    content = html.Div(
              [ctnt],
              id='page-content'
        
              )
    return content

app.layout = html.Div([dcc.Location(id="url"),isi_sidebar(), isi_content()])


@app.callback(
    [Output(f"dashboard{i}", "active") for i in range(1, 5)],
    [Input("url", "pathname")],
)
def toggle_active_links(pathname):
    if pathname == "/" or "/dashboard1":
        # Treat page 1 as the homepage / index
        return True, False
    return [pathname == f"/dashboard{i}" for i in range(1, 5)]

@app.callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/' or '/dashboard1':
        ctnt = content1
        return ctnt

    elif pathname == '/dashboard2':
        ctnt = content2
        return ctnt

    elif pathname == '/dashboard3':
        ctnt = content3
        return ctnt

    elif pathname == '/dashboard4':
        ctnt = content4
        return ctnt

    else:
        return dbc.Jumbotron(
        [
            html.H1("404: Link not Found", className="Wrong Page"),
            html.Hr(),
            html.P(f"Halaman {pathname} belum gw buat bro..."),
        ]
    )

@app.callback(Output('main_sidebar', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname in ['/', '/dashboard1']:
        
        sdbar = sidebar1
        return sdbar

    elif pathname in ['/dashboard2']:
        
        sdbar = sidebar2
        return sdbar

    elif pathname in ['/dashboard3']:
        
        sdbar = sidebar3
        return sdbar

    elif pathname in ['/dashboard4']:
        
        sdbar = sidebar4
        return sdbar
    else:

        return ''

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

menu/dashboard1.py

import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
from menu.style import *
from app import app, server


BOX_STYLE1 = KOTAK_UTAMA_STYLE
SIDEBAR_STYLE1 = SIDEBAR_STYLE

#content
kolom_kiri1 = html.Div([])
kolom_tengah1 = html.Div([])
kolom_kanan1 = html.Div([])
kolom_peta1 = html.Div([])

kotak_utama1 = html.Div([
    kolom_kiri1,
    kolom_tengah1,
    kolom_kanan1,
    kolom_peta1],id='main box1',
      style=BOX_STYLE1
                      )

#sidebar
sidebar1 = html.Div(
    [html.Img(src=app.get_asset_url('logo.png'),style={
                        'height':'116px', 
                        'width':'138px',
                        'margin-top': '-9px',
                        'background-color' : 'rgba(0,0,0,0.03)'}),
        #html.Hr(),
        html.P([
            "TEXT FOR LOGO", html.Br(),"ANOTHER TEXT LINE", html.Br(), "MORE TEXT LINE"], className="lead", 
            style={
                'textAlign': 'center',
                'background-color' : 'rgba(0,0,0,0.03)',
                'color': '#f1a633', 
                'fontSize': '8',
                'margin-top': '-3px'
                  }),
        html.Hr(),
        html.Div(children=[
            html.A(html.Button('DASHBOARD I', className='tab-button'),
                href='/dashboard1'),
            html.Hr(),
            html.A(html.Button('DASHBOARD II', className='tab-button'),
                href='/dashboard2'),
        	html.Hr(),
        	html.A(html.Button('DASHBOARD III', className='tab-button'),
                href='/dashboard3'),
            html.Hr(),
            html.A(html.Button('DASHBOARD IV', className='tab-button'),
                href='/dashboard4'),
            html.Hr(),
            ],
            
            
        ),
    ],
    style=SIDEBAR_STYLE1,
)
content1 = html.Div([
					  html.H1(['TITLE FOR DASHBOARD I'],
					  	style={
					  	'margin-left': '340px',
					  	'margin-top': '20px',
					  	'color': 'rgba(255,255,255,1)',
					  	'fontSize': '18',
					  	}),			


					   kotak_utama1,
					  
					  	],style={
					  	'margin-left': '0px',
					  	'margin-top': '0px',}
					  	)


layout1 = html.Div([dcc.Location(id="url"), sidebar1, content1])

menu/dashboard2.py

import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
from menu.style import *
from app import app, server



BOX_STYLE2 = KOTAK_UTAMA_STYLE
SIDEBAR_STYLE2 = SIDEBAR_STYLE

#content
kolom_kiri2 = html.Div([])
kolom_tengah2 = html.Div([])
kolom_kanan2 = html.Div([])
kolom_peta2 = html.Div([])

mainbox2 = html.Div([
    kolom_kiri2,
    kolom_tengah2,
    kolom_kanan2,
    kolom_peta2],id='main box2',
      style=BOX_STYLE2
                      )

#sidebar
sidebar2 = html.Div(
    [html.Img(src=app.get_asset_url('logo.png'),style={
                        'height':'116px', 
                        'width':'138px',
                        'margin-top': '-9px',
                        'background-color' : 'rgba(0,0,0,0.03)'}),
        #html.Hr(),
        html.P([
            "TEXT FOR LOGO", html.Br(),"ANOTHER TEXT LINE", html.Br(), "MORE TEXT LINE"], className="lead", 
            style={
                'textAlign': 'center',
                'background-color' : 'rgba(0,0,0,0.03)',
                'color': '#f1a633', 
                'fontSize': '8',
                'margin-top': '-3px'
                  }),
        html.Hr(),
        html.Div(children=[
            html.A(html.Button('DASHBOARD I', className='tab-button'),
                href='/dashboard1'),
            html.Hr(),
            html.A(html.Button('DASHBOARD II', className='tab-button'),
                href='/dashboard2'),
        	html.Hr(),
        	html.A(html.Button('DASHBOARD III', className='tab-button'),
                href='/dashboard3'),
            html.Hr(),
            html.A(html.Button('DASHBOARD IV', className='tab-button'),
                href='/dashboard4'),
            html.Hr(),
            ],
            
            
        ),
    ],
    style=SIDEBAR_STYLE2,
)
content2 = html.Div([
					  html.H1(['TITLE FOR DASHBOARD II'],
					  	style={
					  	'margin-left': '340px',
					  	'margin-top': '20px',
					  	'color': 'rgba(255,255,255,1)',
					  	'fontSize': '18',
					  	}),			


					   mainbox2,
					  
					  	],style={
					  	'margin-left': '0px',
					  	'margin-top': '0px',}
					  	)


layout2 = html.Div([dcc.Location(id="url"), sidebar2, content2])

menu/dashboard3.py

import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
from menu.style import *
from app import app, server



BOX_STYLE3 = KOTAK_UTAMA_STYLE
SIDEBAR_STYLE3 = SIDEBAR_STYLE

#content
kolom_kiri3 = html.Div([])
kolom_tengah3 = html.Div([])
kolom_kanan3 = html.Div([])
kolom_peta3 = html.Div([])

mainbox3 = html.Div([
    kolom_kiri3,
    kolom_tengah3,
    kolom_kanan3,
    kolom_peta3],id='main box3',
      style=BOX_STYLE3
                      )

#sidebar
sidebar3 = html.Div(
    [html.Img(src=app.get_asset_url('logo.png'),style={
                        'height':'116px', 
                        'width':'138px',
                        'margin-top': '-9px',
                        'background-color' : 'rgba(0,0,0,0.03)'}),
        #html.Hr(),
        html.P([
            "TEXT FOR LOGO", html.Br(),"ANOTHER TEXT LINE", html.Br(), "MORE TEXT LINE"], className="lead", 
            style={
                'textAlign': 'center',
                'background-color' : 'rgba(0,0,0,0.03)',
                'color': '#f1a633', 
                'fontSize': '8',
                'margin-top': '-3px'
                  }),
        html.Hr(),
        html.Div(children=[
            html.A(html.Button('DASHBOARD I', className='tab-button'),
                href='/dashboard1'),
            html.Hr(),
            html.A(html.Button('DASHBOARD II', className='tab-button'),
                href='/dashboard2'),
          html.Hr(),
          html.A(html.Button('DASHBOARD III', className='tab-button'),
                href='/dashboard3'),
            html.Hr(),
            html.A(html.Button('DASHBOARD IV', className='tab-button'),
                href='/dashboard4'),
            html.Hr(),
            ],
            
            
        ),
    ],
    style=SIDEBAR_STYLE3,
)
content3 = html.Div([
            html.H1(['TITLE FOR DASHBOARD III'],
              style={
              'margin-left': '340px',
              'margin-top': '20px',
              'color': 'rgba(255,255,255,1)',
              'fontSize': '18',
              }),     


             mainbox3,
            
              ],style={
              'margin-left': '0px',
              'margin-top': '0px',}
              )


layout3 = html.Div([dcc.Location(id="url"), sidebar3, content3])

menu/dashboard4.py

import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
from menu.style import *
from app import app, server

# Add dashboard specific methods here

BOX_STYLE4 = KOTAK_UTAMA_STYLE
SIDEBAR_STYLE4 = SIDEBAR_STYLE

#content
kolom_kiri4 = html.Div([])
kolom_tengah4 = html.Div([])
kolom_kanan4 = html.Div([])
kolom_peta4 = html.Div([])

mainbox4 = html.Div([
    kolom_kiri4,
    kolom_tengah4,
    kolom_kanan4,
    kolom_peta4],id='main box4',
      style=BOX_STYLE4
                      )

#sidebar
sidebar4 = html.Div(
    [html.Img(src=app.get_asset_url('logo.png'),style={
                        'height':'116px', 
                        'width':'138px',
                        'margin-top': '-9px',
                        'background-color' : 'rgba(0,0,0,0.03)'}),
        #html.Hr(),
        html.P([
            "TEXT FOR LOGO", html.Br(),"ANOTHER TEXT LINE", html.Br(), "MORE TEXT LINE"], className="lead", 
            style={
                'textAlign': 'center',
                'background-color' : 'rgba(0,0,0,0.03)',
                'color': '#f1a633', 
                'fontSize': '8',
                'margin-top': '-3px'
                  }),
        html.Hr(),
        html.Div(children=[
            html.A(html.Button('DASHBOARD I', className='tab-button'),
                href='/dashboard1'),
            html.Hr(),
            html.A(html.Button('DASHBOARD II', className='tab-button'),
                href='/dashboard2'),
          html.Hr(),
          html.A(html.Button('DASHBOARD III', className='tab-button'),
                href='/dashboard3'),
            html.Hr(),
            html.A(html.Button('DASHBOARD IV', className='tab-button'),
                href='/dashboard4'),
            html.Hr(),
            ],
            
            
        ),
    ],
    style=SIDEBAR_STYLE4,
)
content4 = html.Div([
            html.H1(['TITLE FOR DASHBOARD IV'],
              style={
              'margin-left': '340px',
              'margin-top': '20px',
              'color': 'rgba(255,255,255,1)',
              'fontSize': '18',
              }),     


             mainbox4,
            
              ],style={
              'margin-left': '0px',
              'margin-top': '0px',}
              )


layout4 = html.Div([dcc.Location(id="url"), sidebar4, content4])

menu/style.py

SIDEBAR_STYLE = {
                  "position": "fixed",
                  "top": '0',
                  "left": '0',
                  "bottom": '0',
                  "width": "240px",
                  "padding": "2rem 1rem",
                  "background-color": "rgba(0, 0, 0, 0.4",
                  "textAlign": "center"
                  }

KOTAK_UTAMA_STYLE = {
          
            'margin-top': '30px',
            'margin-left': '320px',
            'width': '2000px',
            'height': '1022px',
            'background-color': 'rgba(0, 0, 0, 0.4)'
            }

reset.css

html {
  height: 100%;}
body{
  margin:0;
  width:100%;
  height:100%;
  background-image: url("./backgroud.png");
  background-size: cover;
  background-position: center;}

the dashboard layout looks like this one:

i already try, run python3 console in that folder, and run:


>> from menu.dashboard1 import *
>> from menu.dashboard2 import *
>> from menu.dashboard3 import *
>> from menu.dashboard4 import *
>>
>> dir() # to view did all variable definition can called or not, and it can, no variable miss.

can somebody tell me, what wrong with my code…
which one, I miss it…

Thanks for this thread, very helpful, but as a new be, I would have the following questions:

I wonder if we can benefit from serving the apps in different PORTS instead of paths (dash url) , e.g.
App1) address:8080
App2) address:8081
and not
App1) address:8080/app1
App2) address:8080/app2

And how can we do it in such architecture, i.e. having independent apps:

apps/
- app1
   |-- app.py
        - static/
           |-- ...
- app2
   |-- app.py
        - static/
           |-- ...

Maybe @Vlad can comment if he is still using his solution.

And maybe @chriddyp could comment if https://plot.ly/dash/urls is recommended (WSGI server/performance-wise) when the apps are in different contexts (i.e. apples and oranges), or if there is a better solution he is aware of, such as: running more than one Python WSGI HTTP Server (such as gunicorn, cheroot), different ports, or other.

Thanks!

Dear @chriddyp,
Would you also recommend CherryPy/Cheroot, or for gunicorn is still the best option for Dash?

Reference: [External Link] Benchmarking WSGI
Many thanks

i saw your code. but im still confused with how you are integrating dash under with flask login_required page???
please help me im struggling with that part