emilhe / dash-extensions

The dash-extensions package is a collection of utility functions, syntax extensions, and Dash components that aim to improve the Dash development experience

Home Page:https://www.dash-extensions.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Error] Can't use ServersideOutput with Flexible callback signature

DeKhaos opened this issue · comments

Hi, I'm not sure if flexible signature isn't supported in dash-extension for ServersideOutput or it's an error so I'll be stating my question anyway.

Example code:

from dash_extensions.enrich import DashProxy,ServersideOutput,ServersideOutputTransform,\
    Input, Output,State,callback,MultiplexerTransform,dcc
import dash
from dash import html,DiskcacheManager
import dash_bootstrap_components as dbc
import diskcache,time
import plotly.express as px

cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)

app = DashProxy(__name__,
               external_stylesheets=[dbc.themes.CYBORG,dbc.icons.BOOTSTRAP],
               suppress_callback_exceptions=True,
               background_callback_manager=background_callback_manager,
               transforms=[ServersideOutputTransform(),
                           MultiplexerTransform()]
               )
server = app.server

app.layout = html.Div(
    [dcc.Store(id='store_data'),
     dcc.Store(id='store_data_2'),
     dbc.Col(dbc.Input(id="input_1_group1",type='number',
                       min=1,max=50,value=25),
             width=2),
     html.Br(),
     dbc.Col(dbc.Input(id="input_2_group1",type='number',
                        min=1,max=100,value=75),
              width=2),
     html.Br(),
     dbc.Col(dbc.Input(id="input_3_group1",type='number',
                        min=1,max=50,value=10),
              width=2),
     html.Br(),
     dbc.Col(dbc.Input(id="input_1_group2",type='number',
                        min=1,max=100,value=65),
              width=2),
     html.Br(),
     dbc.Col(dbc.Input(id="input_2_group2",type='number',
                        min=1,max=50,value=35),
              width=2),
     html.Br(),
     dbc.Col(dbc.Input(id="input_1_group3",type='number',
                        min=1,max=100,value=45),
              width=2),
     html.Br(),
     dbc.Col(dbc.Input(id="input_2_group3",type='number',
                        min=1,max=50,value=20),
              width=2),
     html.Br(),
     dbc.Button("Click me",id="button",n_clicks=0),
                
     html.P(id='result'),
     html.P(id='result_2'),
     html.P(id='result_3')
     ])

@callback(ServersideOutput('store_data','data'),
          ServersideOutput('store_data_2','data'),
          Output('result','children'),
          Input('button','n_clicks')
          )
def store_data(click):
    if click==0:
        return px.data.gapminder(),px.data.election(),"Initial loaded."
    else:
        return dash.no_update,dash.no_update,dash.no_update


@callback(output=[Output('result','children'),
                  Output('result_2','children'),
                  Output('result_3','children')],
          inputs=dict(button=(Input('button','n_clicks')),
                       group1=(Input('input_1_group1','value'),
                               Input('input_2_group1','value'),
                               Input('input_3_group1','value')),
                       group2=(Input('input_1_group2','value'),
                               Input('input_2_group2','value')),
                       group3=(Input('input_1_group3','value'),
                               Input('input_2_group3','value')),
                       group4=(State('store_data','data'),
                               State('store_data_2','data'))
                       ),
          prevent_initial_call=True
          )
def testing_funct(button,group1,group2,group3,group4):
    time.sleep(1)
    return ["Output 1","Output 2","Output 3"]

if __name__ == '__main__':
    app.run(debug=True)

Environment: dash 2.7.0, dash-extension 0.1.7

Error:

Python\envs\testing2\Lib\site-packages\dash_extensions\enrich.py", line 1151, in decorated_function
args[i] = serverside_output.backend.get(args[i], ignore_expired=True)
IndexError: list index out of range

If I comment out the group4 in testing_funct callback, the result is ok. But if I keep group4, I get that error.
A solution I found to work around this is to define all Input,State in a list then group then later inside the function, but it's messy if input list is really long and I need to group them up.

I can see in the code, that unpacking of serverside outputs into flexible structues has not been implemented. I don't see that is should be impossibily to do so, and I haven't made any notes in the docs on this limitation, so I would consider it a bug.

I can see in the code, that unpacking of serverside outputs into flexible structues has not been implemented. I don't see that is should be impossibily to do so, and I haven't made any notes in the docs on this limitation, so I would consider it a bug.

Thank you, noted. I hope this will get updated in later versions.