[BUG] Background callbacks with different outputs not working
Describe your context Please provide us your environment, so we can easily reproduce the issue.
- replace the result of
pip list | grep dashbelow
dash 2.6.1
dash-bootstrap-components 1.2.0
dash-core-components 2.0.0
dash-html-components 2.0.0
dash-table 5.0.0
Describe the bug
Background callbacks don't work if they are generated with a function/loop. For example, I've created a function gen_callback that creates a new callback given a css id.
def gen_callback(css_id, x):
@app.callback(
Output(css_id, 'children'),
Input('my-dropdown', 'value'),
background=True,
)
def callback_name(value):
print(f"Inside callback_name {self._css_id} for {org_id}")
return int(value) + x
The background callback manager uses a hash function to know the key to get. This hash function just takes into account the code of the function, but not the variables used to generate that function.
https://github.com/plotly/dash/blob/c897b2b094543e930a862fe51d48abfb78057df7/dash/long_callback/managers/init.py#L101-L105
I think the hash should also take into account the Output list of the callback.
Expected behavior
Using a variable as the id of one of the outputs creates multiple different, valid callbacks, that should work fine with background=True.
Possible temporary solution
Generate a function with exec(), replacing parts of a template code, and decorate the compiled function.
I have a very similar problem. In case this is useful, I have been using the following workaround for now. I do not know if the workaround breaks any other Dash functionality.
In the file that defines the Dash app, I added:
from dash.long_callback.managers import BaseLongCallbackManager
import uuid
def monkeypatched_hash_function(fn):
return uuid.uuid4()
BaseLongCallbackManager.hash_function = monkeypatched_hash_function
But then it won't be cached, because every time the hash function is called it will return a different uuid.
If I am not mistaken, the only time the hash function is called is when registering a function, and this is done only once per function (i.e., only once each time Dash's callback function is invoked). By looking at the code, it seems that the hash is only used as a key to then find the function that must be run when a certain callback is triggered. Thus, it seems that the only purpose of the hash is to assign a unique key each time a function is registered. Since I am not a Dash developer, I can of course be wrong, and please do let me know if I have misunderstood your issue. In any event, the workaround I proposed does work for me.
Sorry, I meant that it wouldn't be cached between runs. If you restart the program, the uuids will be different.
Thank you for fixing this issue! I recently ran into this exact problem, and it went away after I updated dash to the latest version.