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
I manage to get data and view my dashboard. But a problem I do not understand is where to place @callback ( in def load_data()).
My try:
import pandas as pd
import dash
from dash import dcc
from dash import html
import dash_bootstrap_components as dbc
from dash.dependencies import Output, Input, State
import plotly.express as px
import base64
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.
"""
u = routes.get_user()
data = u.data_for_user.all()
df= pd.DataFrame([(d.month, d.id_user, d.shop, d.amount) for d in data],
columns=([('month', 'id_user', 'shop', 'amount'])
# Logo
logo_png = "image.png"
logo_base64 = base64.b64encode(open(logo_png, 'rb').read()).decode('ascii')
# 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",
value=df.sort_values(by=['Month'], ascending=False)['Month Name'].unique()[
0],
searchable=False
)
# Layout
dash_app.layout = html.Div([
# Row 1
dbc.Row([
# Col 1
dbc.Col(html.Img(Image.png)),
# Col 2
dbc.Col(html.H1("Text")),
# Col 3
dbc.Col(html.Div(Month_Selector)),
# Row 2
dbc.Row(
dbc.Col([dcc.Graph(id='sales_subplot')], width=12)),
],
style={'margin-left': '80px',
'margin-right': '80px'}
)
# Callbacks
@dash_app.callback(
Output(component_id='sales_subplot', component_property='figure'),
Input(component_id='Month_dropdown', component_property='value')
)
def update_graph(selected_month):
# Filtered Data
filtered_df = df[(df['month'] == selected_month)]
fig = px.bar(filtered_df,x="month",y="amount")
return fig
return dash_app.server
The location where I put @callback in a dashboard works, but a user does not change even when another user logs in. Only after disconnecting an app and re-run, it change. When I try to put before function def load_data (): then it does not work at all…
But where does it need to be placed correctly?
2 posts - 2 participants