I am building a dash plotly web app that uses callbacks. I have created a callback manager that handles the callbacks in a class. But it seems like my callback manager can’t update the components within the original Dash app callback “running” state. Any recommendation and help would be great!
For context, this is my callbackmanager.py:
from dataclasses import dataclass, field
from typing import Callable, List, Union
from dash.dependencies import handle_callback_args
from dash.dependencies import Input, Output, State
@dataclass
class Callback:
func: Callable
outputs: Union[Output, List[Output]]
inputs: Union[Input, List[Input]]
states: Union[State, List[State]] = field(default_factory=list)
kwargs: dict = field(default_factory=lambda: {"prevent_initial_call": False})
class CallbackManager:
def __init__(self):
self._callbacks = []
def callback(self, *args, **kwargs):
output, inputs, state, prevent_initial_call = handle_callback_args(
args, kwargs
)
def wrapper(func):
self._callbacks.append(
Callback(
func,
output,
inputs,
state,
{"prevent_initial_call": prevent_initial_call}
)
)
return wrapper
def attach_to_app(self, app):
for callback in self._callbacks:
app.callback(
callback.outputs, callback.inputs, callback.states, **callback.kwargs
)(callback.func)
And I am using this in my app.py:
from callbacks.callbacks import callback_manager
...
app = Dash(__name__, use_pages=True, external_stylesheets=stylesheets)
callback_manager.attach_to_app(app)
...
app.layout
...
if __name__ == '__main__':
app.run(debug=True, port=8000)
And in my callbacks.py:
from models.callbackmanager.callbackmanager import CallbackManager
from componentcallbacks import register_component_callbacks
...
callback_manager = CallbackManager()
register_component_callbacks(callback_manager)
...
Inside my componentcallbacks.py:
def register_component_callbacks(callback_manager):
@callback_manager.callback(
...
running=[
(Output('submit-button', 'loading'), True, False),
(Output('loading-for-component', 'custom_spinner'), loader_component(title="loading..."), loader_component(title=None)),
],
prevent_initial_call=True
)
def update_something(inputs...):
return ...