I’m experiencing an issue with my Dash app where I encounter the error:
“In the callback for output(s):
selected-shade-data.data
Output 0 (selected-shade-data.data) is already in use.”
This error occurs whenever I refresh the page. I’ve ensured that my callbacks are registered only once and that the layout loading logic should not be causing multiple callback registrations. Despite these precautions, the error persists.
Here’s a brief overview of my setup:
- My app uses Flask for server-side routing and authentication.
- The layout is dynamically set based on the user ID from the URL route.
- Callbacks are registered outside the layout loading logic to ensure they are only registered once.
- I have set
suppress_callback_exceptions=True
in my app initialization.
Below is a simplified version of my code:
from utils.connections import get_database_data
from utils.layouts import get_main_layout
#other dependencies
external_stylesheets = [
dbc.themes.LUX,
"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css",
]
server = Flask(__name__)
server.secret_key = 'secret_key'
app = dash.Dash(__name__, server=server, external_stylesheets=external_stylesheets, suppress_callback_exceptions=True)
@app.server.route('/<user_id>')
def index(user_id):
username = get_username_from_user_id(user_id)
if username:
data, all_data, names = get_database_data(username)
app.layout = get_main_layout(app, username)
@app.callback(
Output("selected-shade-data", "data"), [Input("cie-2000-each-shades", "clickData")]
)
def update_selected_shade_data(clickData):
if clickData is None:
return {}
# Récupérer les données du point cliqué
point_data = clickData["points"][0]["customdata"]
# Extraction des données
(
shade1_name,
shade1_rgb,
shade1_undertone,
deltaE,
shade2_name,
shade2_rgb,
shade2_undertone,
) = point_data
shade1 = {
"shade_name": shade1_name,
"rgb": shade1_rgb,
"undertone": shade1_undertone,
}
shade2 = {
"shade_name": shade2_name,
"rgb": shade2_rgb,
"undertone": shade2_undertone,
}
return {"shade1": shade1, "deltaE": deltaE, "shade2": shade2}
return app.index()
else:
return "User not found", 404
if __name__ == '__main__':
app.run_server(host='0.0.0.0', port=8050, debug=True)
here is my layouts.py:
from dash import html
import dash_bootstrap_components as dbc
from dash import dcc
from utils.connections import get_database_data
def get_main_layout(app, username):
data, all_data, names = get_database_data(username)
layout = html.Div(
id='app-content',
style={
"backgroundColor": "#0C0C0C",
"color": "white",
"padding-left": "15vh",
"padding-right": "15vh",
"padding-bottom": "15vh",
},
children=[
dbc.Row(
[
dbc.Col(
[
html.Div(
id="part-4-plot-22",
style={"padding": "10px"},
children=[
html.H3(
"Depth of shade range between each shade",
style={
"color": "white",
"padding-top": "10px",
"padding-bottom": "10px",
},
),
html.Div(
id="part-4-plot-2-description",
style={
"padding": "10px"
},
children=[
html.H5(
[
html.I(
className="fas fa-caret-right",
id="part-4-plot-2-trigger-icon",
),
" Comprendre la profondeur entre 2 teintes voisines",
],
id="part-4-plot-2-trigger",
style={
"cursor": "pointer"
},
),
dcc.Interval(
id="part-4-plot-2-dummy-interval",
interval=60
* 60
* 1000, # en millisecondes, donc ici 60 minutes
max_intervals=1, # ce composant déclenchera le callback une seule fois
),
dbc.Collapse(
html.Div(
id="part-4-plot-2-content",
children="",
),
id="collapse-part-4-plot-2",
is_open=False,
),
],
),
dcc.Store(
id="selected-shade-data",
data={},
),
html.Div(
id="part-4-plot-2",
children=[
dcc.Loading(
id="loading-part-4-plot-2",
type="circle",
color="#1f77b4",
children=[
dcc.Graph(
id="heatmap-cie-2000-each-shades",
),
],
)
],
),
html.Div(id='description-container-10', style={'marginTop': '20px'}),
html.Br(),
html.Div(
id="shade-detail-display",
children=[],
),
html.Div(
id="each-shade-detail-display",
children=[
dcc.Loading(
id="loading-each-shade-detail-display",
type="circle",
color="#1f77b4",
children=[
dcc.Graph(
id="cie-2000-each-shades",
),
],
)
],
),
],
),
#other components
])])])
return layout