I attempting to deploy a multi-tab dash app to Heroku server, however I get a dash.exceptions.NoLayoutException
. I am following the Structuring a Multi-Page App example here: URL Routing and Multiple Apps | Dash for Python Documentation | Plotly
The App works fine locally.
My file structure looks like this:
index.py
app.py
requirements.txt
Procfile
Tabs
--- Tab1.py
--- Tab2.py
assets
--- style.css
The contents of app.py :
import dash
import flask
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
app = dash.Dash(__name__, suppress_callback_exceptions=True)
server = app.server
app = dash.Dash(
meta_tags=[
{"name": "viewport", "content": "width=device-width, initial-scale=1"}
],
external_stylesheets=[dbc.themes.SLATE],
)
Contents of index.py
import pandas as pd
import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html
import dash_core_components as dcc
import plotly as py
from plotly import graph_objs as go
from plotly.graph_objs import *
import flask
from app import app
import os
from tabs import reporting, portfolio, market, deal, revenue, comps, analysis
# In[8]:
server = app.server
# App Layout
app.layout = html.Div([
# header
html.Div([
html.H2("Product"),
),
# tabs
html.Div([
dcc.Tabs(
id="tabs",
children=[
dcc.Tab(label="Port", value="p_tab"),
dcc.Tab(label="Leads", value="r_tab"),
],
)
],
className="row tabs_div"
),
# Tab content
html.Div(id="tab_content"),
])
# In[9]:
# Render tabs/subtabs
@app.callback(
Output("tab_content", "children"),
[
Input("tabs", "value"),
Input("subtabs", "value")
],
)
def render_content(tab, subtab):
"""
For user selections, return the relevant tab
"""
if tab == "p_tab":
return tab1.layout
if tab == "r_tab":
return tab2.layout
else:
return (dash.no_update)
# In[10]:
if __name__ == '__main__':
# Production
app.run_server(debug=True)
Traceback
2020-08-13T04:23:11.192175097Z app[web.1]: Traceback (most recent call last):
2020-08-13T04:23:11.192180799Z app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 2447, in wsgi_app
2020-08-13T04:23:11.192185482Z app[web.1]: response = self.full_dispatch_request()
2020-08-13T04:23:11.192189928Z app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1945, in full_dispatch_request
2020-08-13T04:23:11.192194507Z app[web.1]: self.try_trigger_before_first_request_functions()
2020-08-13T04:23:11.192198903Z app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1993, in try_trigger_before_first_request_functions
2020-08-13T04:23:11.192203399Z app[web.1]: func()
2020-08-13T04:23:11.192207530Z app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/dash/dash.py", line 1500, in _setup_server
2020-08-13T04:23:11.192212198Z app[web.1]: self._validate_layout()
2020-08-13T04:23:11.192216422Z app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/dash/dash.py", line 1465, in _validate_layout
2020-08-13T04:23:11.192220923Z app[web.1]: "The layout was `None` "