Set_props with a Serverside output from dash-extensions

Is it possible to use set_props to update a Serverside output (from dash-extensions)? From my attempts below, it seems like you cannot return a Serverside object while using set_props

Package Versions

dash==2.17.1
dash-extensions==1.0.18

MRE

from dash_extensions.enrich import (
    DashProxy,
    Output,
    Input,
    Serverside,
    html,
    dcc,
    ServersideOutputTransform,
    callback,
    FileSystemBackend,
)
from dash import set_props
from dash.exceptions import PreventUpdate
from random import randint

"""
CONIG
"""

backend = FileSystemBackend(cache_dir="/tmp/")

app = DashProxy(
    __name__,
    suppress_callback_exceptions=True,
    transforms=[ServersideOutputTransform(backends=[backend])],
    prevent_initial_callbacks=True,
)

"""
LAYOUT
"""
app.layout = html.Div(
    [
        dcc.Store(id="store"),
        html.Button(id="init-button", children="INIT"),
        html.Button(id="update-button", children="UPDATE"),
        html.Div(id="output"),
        html.Div(id="output-2"),
    ]
)

"""
CALLBACKS
"""
# Click on the init button to randomly generate a number and store in a dcc.Store
@callback(
    [
        Output("store", "data", allow_duplicate=True),
    ],
    [
        Input("init-button", "n_clicks"),
    ],
    prevent_initial_call=True,
)
def display_selected_chip(init_button):
    if init_button:
        return Serverside(randint(1, 1000))
    raise PreventUpdate

# Display stored value
@callback(
    [
        Output("output", "children"),
    ],
    [
        Input("store", "data"),
    ],
    prevent_initial_call=True,
)
def display_selected_chip(store):
    if store:
        return f"{store}"

    raise PreventUpdate

# Update button tries to use set_props to change the number in the store, as well as return text in a div to confirm the number of times the update button was clicked
@callback(
    [
        Output("output-2", "children"),
    ],
    [
        Input("update-button", "n_clicks"),
    ],
    prevent_initial_call=True,
)
def display_selected_chip(update_button):
    if update_button:
        set_props("store", {"data": Serverside(randint(2000, 3000))})
        return f"The update button was clicked {update_button} times"
    raise PreventUpdate


if __name__ == "__main__":
    app.run_server(host="0.0.0.0", debug=True, port=8282)

However, if you do not wrap the object in Serverside, the application works as expected - I am not sure if this causes the output to then be transferred over the network and lose its ‘Serverside-ness’ - would really appreciate some clarity on this specific point.

Hello @uns123,

set_props works by attaching it to the outgoing response from the server, @Emil would have to adjust how dash-extensions works in that manner.

Did not realize how set_props works. Thanks!

1 Like