I am currently trying to host multiple apps with several global variables. When I just run it without trying to use global variables, the Dash app works fine, and I’ve been using it for a while now. But when I added serve_layout1 and serve_layout2 (see code below) the Dash app has stopped working.
Here is my file structure:
- app.py
- index.py
- apps
|-- __init__.py
|-- app1.py
|-- app2.py
where:
app.py:
import dash
app = dash.Dash(__name__, suppress_callback_exceptions=True)
server = app.server
index.py:
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from app import app
from apps import app1, app2
from apps.app1 import serve_layout1
from apps.app2 import serve_layout2
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':
app1.layout = serve_layout1
return app1.layout
elif pathname == '/apps/app2':
app2.layout = serve_layout2
return app2.layout
else:
return '404'
if __name__ == '__main__':
app.run_server(debug=True)
app1:
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from app import app
def serve_layout1():
global df
app_layout1 = 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')
])
return app_layout1
@app.callback(
Output('app-1-display-value', 'children'),
Input('app-1-dropdown', 'value'))
def display_value(value):
return 'You have selected "{}"'.format(value)
app2:
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from app import app
def serve_layout2():
global df
app_layout2 = 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 2', href='/apps/app1')
])
return app_layout2
@app.callback(
Output('app-1-display-value', 'children'),
Input('app-1-dropdown', 'value'))
def display_value(value):
return 'You have selected "{}"'.format(value)
The traceback is the following:
Traceback (most recent call last):
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\dash\dash.py", line 1039, in add_context
response, cls=plotly.utils.PlotlyJSONEncoder
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\json\__init__.py", line 238, in dumps
**kw).encode(obj)
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\_plotly_utils\utils.py", line 45, in encode
encoded_o = super(PlotlyJSONEncoder, self).encode(o)
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\_plotly_utils\utils.py", line 115, in default
return _json.JSONEncoder.default(self, obj)
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\json\encoder.py", line 180, in default
o.__class__.__name__)
TypeError: Object of type 'function' is not JSON serializable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\dash\dash.py", line 1072, in dispatch
response.set_data(func(*args, outputs_list=outputs_list))
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\dash\dash.py", line 1042, in add_context
_validate.fail_callback_output(output_value, output)
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\dash\_validate.py", line 256, in fail_callback_output
_validate_value(val, index=i)
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\dash\_validate.py", line 251, in _validate_value
toplevel=True,
File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\dash\_validate.py", line 205, in _raise_invalid
bad_val=bad_val,
dash.exceptions.InvalidCallbackReturnValue: The callback for `<Output `page-content.children`>`
returned a value having type `function`
which is not JSON serializable.
The value in question is either the only value returned,
or is in the top level of the returned list,
and has string representation
`<function serve_layout1 at 0x000002F917B3BB70>`
In general, Dash properties can only be
dash components, strings, dictionaries, numbers, None,
or lists of those.