I went ahead and slightly modified the /pages example to try and highlight the issue.
app.py
:
from dash_extensions.enrich import (
Dash,
FileSystemStore,
)
import dash
import dash_bootstrap_components as dbc
import dash_labs as dl
# Setup file caching
fss = FileSystemStore(cache_dir="cache")
output_defaults = dict(
backend=fss, session_check=False
) # Turned off session check in order to share global data
# App Instance
app = Dash(
__name__,
plugins=[dl.plugins.pages],
external_stylesheets=[dbc.themes.BOOTSTRAP],
output_defaults=output_defaults,
)
navbar = dbc.NavbarSimple(
dbc.DropdownMenu(
[
dbc.DropdownMenuItem(page["name"], href=page["path"])
for page in dash.page_registry.values()
if page["module"] != "pages.not_found_404"
],
nav=True,
label="More Pages",
),
brand="Multi Page App Plugin Demo",
color="primary",
dark=True,
className="mb-2",
)
app.layout = dbc.Container(
[
navbar,
dl.plugins.page_container,
],
fluid=True,
)
if __name__ == "__main__":
app.run_server(debug=True, host="0.0.0.0")
The home page shown below uses the dash-extensions callback and results in a 404 error. This can be fixed by commenting out from app import app
and adding from dash import callback
then using the @callback
syntax. However, the serverside outputs will no longer work correctly once you do this. The resulting error when using a serverside output is that the object returned is not “JSON serializable” . I assume this is because dash-extensions is no longer taking care of the serialization and the callback is trying to return the entire object to the browser instead of just the key.
pages/home.py
:
from dash_extensions.enrich import (
Output,
Input,
)
import dash
dash.register_page(__name__, path="/")
from app import app
from dash import dcc, html
import plotly.express as px
df = px.data.medals_wide(indexed=True)
layout = html.Div(
[
html.H1("Dash Extensions:"),
dcc.Checklist(
id="heatmaps-medals",
options=[{"label": x, "value": x} for x in df.columns],
value=df.columns.tolist(),
),
dcc.Graph(id="heatmaps-graph"),
]
)
@app.callback(Output("heatmaps-graph", "figure"), Input("heatmaps-medals", "value"))
def filter_heatmap(cols):
fig = px.imshow(df[cols])
return fig
This is the standard dash syntax that works without issue.
standard.py
import dash
dash.register_page(__name__, path="/test")
from dash import dcc, html, Output, Input, callback
import plotly.express as px
df = px.data.medals_wide(indexed=True)
layout = html.Div(
[
html.H1("Standard Dash Library"),
dcc.Checklist(
id="heatmaps-medals",
options=[{"label": x, "value": x} for x in df.columns],
value=df.columns.tolist(),
),
dcc.Graph(id="heatmaps-graph2"),
]
)
@callback(Output("heatmaps-graph2", "figure"), Input("heatmaps-medals", "value"))
def filter_heatmap(cols):
return px.imshow(df[cols])