Multi-Page Apps and global variables

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.