I'm trying to build a multi-page app on Dash. I was able to get the index page come up on my localhost however, the content of the pages won't come up. Here's how my file structure looks like:
Multipage App (folder)
apps (folder)
__init__.py
page1.py
page2.py
assets(folder)
SQL (folder)
data1.sql
data2.sql
app.py
index.py
Here are the codes within the files:
app.py
import dash
# meta_tags are required for the app layout to be mobile responsive
app = dash.Dash(__name__, suppress_callback_exceptions=True, server=server
)
server = app.server
index.py
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
# Connect to main app.py file
from app import app
from app import server
# Connect to your app pages
from apps import page1, page2
app.layout = html.Div([
html.Div([
dcc.Link('Page 1', href='/page_1'),
dcc.Link('Page 2', href='/page_2'),
], className="row"),
dcc.Location(id='url', refresh=False),
html.Div(id='page-content', children=[])
])
@app.callback(Output('page-content', 'children'),
[Input('url', 'pathname')])
def display_page(pathname):
if pathname == '/page_1':
return page1.layout
if pathname == '/page_2':
return page2.layout
else:
return "404 Page Error! Please choose a link"
if __name__ == '__main__':
app.run_server(debug=False)
page1.py
from datetime import datetime as dt
import dash
from dash.dependencies import Input, Output
import dash_table
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd
import psycopg2
import pathlib
from app import app
# connect to db
conn = psycopg2.connect(
host="localhost",
database="postgres",
user="postgres",
port= "5432",
password="example")
# get relative data folder
PATH = pathlib.Path(__file__).parent
DATA_PATH = PATH.joinpath("../SQL").resolve()
fd = open(DATA_PATH.joinpath("data1.sql", "r"))
# read in the sql file
sqlFile = fd.read()
fd.close()
layout = html.Div(children=[
dcc.Dropdown(
id='demo-dropdown',
options=[
{'label': 'A', 'value': 1},
{'label': 'B', 'value': 2},
{'label': 'C', 'value': 3}
],
value=1
),
dash_table.DataTable(id='dd-output-container',
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns.values]) #
])
@app.callback(
dash.dependencies.Output('dd-output-container', 'data'),
[dash.dependencies.Input('demo-dropdown', 'value')])
def update_output(value):
dfs = df.loc[df['numbers'] == value]
return dfs.to_dict('records')
page2.py
from datetime import datetime as dt
import dash
from dash.dependencies import Input, Output
import dash_table
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd
import psycopg2
import pathlib
from app import app
# connect to db
conn = psycopg2.connect(
host="localhost",
database="postgres",
user="postgres",
port= "5432",
password="example")
# get relative data folder
PATH = pathlib.Path(__file__).parent
DATA_PATH = PATH.joinpath("../SQL").resolve()
fd = open(DATA_PATH.joinpath("data2.sql", "r"))
# read in the sql file
sqlFile = fd.read()
fd.close()
layout = html.Div(children=[
dcc.Dropdown(
id='demo-dropdown',
options=[
{'label': 'A', 'value': 1},
{'label': 'B', 'value': 2},
{'label': 'C', 'value': 3}
],
value=1
),
dash_table.DataTable(id='dd-output-container',
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns.values]) #
])
@app.callback(
dash.dependencies.Output('dd-output-container', 'data'),
[dash.dependencies.Input('demo-dropdown', 'value')])
def update_output(value):
dfs = df.loc[df['numbers'] == value]
return dfs.to_dict('records')
Here's the error I am getting:
File "index.py", line 29, in display_page
return page2.layout
AttributeError: module 'apps.page2' has no attribute 'layout'
I want the content of the pages 1 and 2 to come up whenever someone clicks on the links. Right now, the links come up on the page and they are clickable, however, the content of the pages don't come up when I click on them. The URLs update as well when clicked. It's really just the content of the pages that I am having a problem with. Thank you!