I’m trying to build a Dash app in Flask following this example: openDashAuth/dashboard.py at main · seanmajorpayne/openDashAuth · GitHub
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
from app.auth import routes
from app.models import User
def create_dashboard(server):
"""Create a Plotly Dash dashboard embedded within Flask"""
dash_app = dash.Dash(
server=server,
routes_pathname_prefix="/dashapp/",
external_stylesheets=[dbc.themes.CERULEAN],
)
dash_app.layout = html.Div(
children=[
html.Div(
[
html.Div(
[
html.H1(id="my-header", className="text-center"),
],
className="col-md-12",
)
],
className="row",
),
html.A("Login", id="login-link", href="/login"),
html.Div(id="my-div", className="text-center"),
html.Button(
id="submit-button-state",
n_clicks=1,
children="Submit",
style={"display": "none"},
),
]
)
@dash_app.callback(
[
Output(component_id="my-header", component_property="children"),
Output(component_id="my-div", component_property="children"),
Output(component_id="login-link", component_property="style"),
],
[Input(component_id="submit-button-state", component_property="n_clicks")],
)
def get_user_name(n_clicks):
"""
The dashboard only loads if a user is authenticated
"""
if routes.get_user().is_authenticated:
welcome_msg = "Welcome back, " + routes.get_user().username
user_data = load_data()
link_style = {"display": "none"}
return welcome_msg, user_data, link_style
return "Your Princess is in another castle", ""
def load_data():
"""
The user's data is pulled from a database. As the user has already been
authenticated, the 'current_user' from 'flask_login' is used within a database
query, ensuring that the correct user's data is loaded. This is the key to
having multiple user authentication with dedicated views for each user.
"""
x = []
y = []
u = routes.get_user()
data = u.data_for_user.all()
for d in data:
x_data = [d.x1, d.x2, d.x3]
y_data = [d.y1, d.y2, d.y3]
return html.Div(
[
html.Div(
[
dcc.Graph(
id="client-data",
figure={
"data": [
{
"x": x_data,
"y": y_data,
"type": "scatter",
"name": "Data",
}
],
"layout": {
"title": "Customer Data",
"plot_bgcolor": "#252e3f",
"paper_bgcolor": "#252e3f",
"font": dict(color="#FFFFFF"),
"xaxis": dict(
title="x axis",
color="#98FB98",
),
"yaxis": dict(title="y axis", color="#98FB98"),
"line": dict(color="#98FB98"),
},
},
)
],
className="col-md-8",
)
],
className="row justify-content-center",
)
return dash_app.server
When I don’t use @Callback everything works and each user gets only their data after identification. The problem is that this is a static state that is not all filtered by month.
When I add @Callback with a filter, I only get the first user, and after logging out or just refreshing the page, I get a blank page.
My try:
imports...
def create_dashboard(server):
"""Create a Plotly Dash dashboard embedded within Flask"""
dash_app = dash.Dash(
server=server,
routes_pathname_prefix="/dashapp/",
external_stylesheets=[dbc.themes.CERULEAN],
)
dash_app.layout = html.Div(
children=[
html.Div(
[
html.Div(
[
html.H1(id="my-header", className="text-center", style={'color': 'black', 'fontSize': 10}),
],
className="col-md-12",
)
],
className="row",
),
html.A("Login", id="login-link", href="/login"),
html.Div(id="my-div", className="text-center"),
html.Button(
id="submit-button-state",
n_clicks=1,
children="Submit",
style={"display": "none"},
),
]
)
@dash_app.callback(
[
Output(component_id="my-header", component_property="children"),
Output(component_id="my-div", component_property="children"),
Output(component_id="login-link", component_property="style")
],
[Input(component_id="submit-button-state", component_property="n_clicks")],
)
def get_user_name(n_clicks):
"""
The dashboard only loads if a user is authenticated
"""
if routes.get_user().is_authenticated:
welcome_msg = "Welcome back, " + routes.get_user().username
user_data = load_data()
link_style = {"display": "none"}
return welcome_msg, user_data, link_style
return "Your Princess is in another castle", ""
def load_data():
"""
The user's data is pulled from a database. As the user has already been
authenticated, the 'current_user' from 'flask_login' is used within a database
query, ensuring that the correct user's data is loaded. This is the key to
having multiple user authentication with dedicated views for each user.
"""
u = routes.get_user()
df = pd.DataFrame([(d.month, d.userid, d.amount) for d in u.data_for_user.all()],columns=['month', 'userid', 'amount'])
# SlicerMonth
month_Selector = dcc.Dropdown(id='Month_dropdown',
options=[{'label': i, 'value': i}
for i in df.sort_values(by=['Month'], ascending=False)['Month Name'].unique()],
placeholder="Select Month")
header = html.Div([
html.H1(df['userid'][1], style={'color': 'darkblue', 'fontSize': 20}),
html.Div(id='object'),
html.Div(Month_Selector, style={'width': '200px'})
])
# Callbacks
@dash_app.callback(
Output(component_id='object', component_property='figure'),
Input(component_id='Month_dropdown', component_property='value')
)
def update_graph(selected_month):
filtered_df = df[df['month'] == selected_month)]
fig = html.Div(filtered_df ['amount'].sum(), style={'color': 'darkblue', 'fontSize': 20})
return fig
return header
return dash_app.server
Can’t figure out where and how to place @callback. Please help me figure out how to add a month filter using @callback and make a dynamic dashboard. Thanks !!