DashExtensions - MultiplexTransforms now works with client-side callbacks!

dash==1.19.0
dash_core_components
dash_html_components
dash_bootstrap_components
dash-extensions==0.0.51
plotly==4.14.1
pandas==1.1.5
numpy===1.19.3
ipywidgets==7.5.1
statsmodels==0.12.1
scikit-learn==0.23.2
matplotlib==3.3.3
scipy==1.5.4
mariadb==1.0.5
gunicorn==20.0.4

Letting you know that MultiplexTransforms only works if all callbacks/defs that point to the same Output are server-side code. If one of the callbacks is a clientside-callback, you get the Duplicate callback outputs error message and the page won’t load.

The project I am working on is quite large/unwieldy, and I am under a tight deadline, so cannot take time away to create a demo. Apologies. But I duplicated the client-side callback with a server-side callback that does the same thing, and was able to comment-out one or the other and produce/remove the error on demand. No doubt about it.

PS - Would it make sense to create either a category or a tag for the Dash Extensions?

My advice is to call @Emil , if he can’t solve it nobody will do. :thinking:

That is correct. The multiplexer was designed only for ‘normal’ callbacks.

That being said, I guess it could be implemented for clientside callbacks too. I’ll think about it (:

Thanks Emil - we had to make a decision about whether to keep using clientside-callbacks for super-fast screen updating, or MultiplexTransforms for much simpler/more streamlined callbacks. Ultimately, we decided on the UI speed offered by the clientside-callbacks, but many kleenex tissues were used as we bid a sad farewell to the mux. Be glad that I withheld the terrible pun about our hopes being… well, you know.

1 Like

I couldn’t handle the thought of your suffering, @DPly . Plus it turned out to be much less complex that i initially imagined to incorporate clientside callbacks :slight_smile: . So if you install my latest build,

pip install dash-extensions==0.0.52rc1

you should be able to use the multiplexer with clientside callbacks too. Here is the example i used during development,

import time
import dash_html_components as html
import dash_core_components as dcc
from dash_extensions.enrich import Output, DashProxy, Input, MultiplexerTransform

# Small example app.
proxy_container = dcc.Loading()
app = DashProxy(transforms=[MultiplexerTransform(proxy_location=proxy_container)])
app.layout = html.Div([html.Button("left", id="left", n_clicks=0),
                       html.Button("right", id="right", n_clicks=0),
                       html.Div("Initial value", id="log"), proxy_container])
# Client side function.
f = "function(n_clicks){return 'left (' + n_clicks + ')';}"
app.clientside_callback(f, Output("log", "children"), Input("left", "n_clicks"), prevent_initial_call=True)


@app.callback(Output("log", "children"), Input("right", "n_clicks"), prevent_initial_call=True)
def right(n_clicks):
    time.sleep(2)
    return f"right ({n_clicks})"


if __name__ == '__main__':
    app.run_server(port=7777, debug=True)

I haven’t tested it much, but since the logical changes required were so few, i would expect it to work just as for normal callbacks. Please let me know of you encounter any issue. I will move the feature to a non-rc version when i get time to update the docs.

2 Likes

Haha - you guys are pretty funny. And @Emil saves the day again :slight_smile:

I updated the title to say it “now works” instead of “does not work”

2 Likes

A perfect end-of-week treat, thank you Emil. I’ll implement now and let you know if we find any glitches.

As the clientside-callbacks continue to catch on (which they will do because they make such a noticeable speed difference to such UX as show/hiding buttons, etc), I believe this particular update will be deeply appreciated by the larger community. You’ve once again proven yourself a most Dashing fellow. Merci encore, Emil.

2 Likes

I told you so. :grinning: :joy: :joy: