0
votes

When I run the code below the function program_exe.update_data() is executed twice. What is the best way of avoiding that? The function is relatively time consuming to execute so running through it twice is not ideal. Any suggestions would be appreciated!

app = dash.Dash(__name__)
server = app.server

dict_main = program_exe.update_data() #this creates a nested dictionary
rpm = list(dict_main.keys())
channels = dict_main[rpm[0]]

app.layout = html.Div(
    [
        html.Div([
            dcc.Dropdown(
                id='rpm-dropdown',
                options=[{'label': speed, 'value': speed} for speed in rpm],
                value=list(dict_main.keys())[0],
                # I removed the multi=True because it requires a distinction between the columns in the next dropdown...
                searchable=False
            ),
        ], style={'width': '20%', 'display': 'inline-block'}),
        html.Div([
            dcc.Dropdown(
                id='channel-dropdown',
                multi=True
            ),
        ], style={'width': '20%', 'display': 'inline-block'}
        ),
        html.Div([
            dcc.Graph(
                id='Main-Graph'  # the initial graph is in the callback
            ),
        ], style={'width': '98%', 'display': 'inline-block'}
        )
    ]
)


@app.callback(
    Output('channel-dropdown', 'options'),
    [Input('rpm-dropdown', 'value')])
def update_date_dropdown(speed):
    return [{'label': i, 'value': i} for i in dict_main[speed]]


@app.callback(
    Output('Main-Graph', 'figure'),
    [Input('channel-dropdown', 'value')],
    [State('rpm-dropdown', 'value')])  # This is the way to inform the callback which dataframe is to be charted
def updateGraph(channels, speed):
    if channels:
        # return the entire figure with the different traces
        return go.Figure(data=[go.Scatter(x=dict_main[speed]['Manager'], y=dict_main[speed][i]) for i in channels])
    else:
    # at initialization the graph is returned empty
        return go.Figure(data=[])


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




1

1 Answers

1
votes

You can use caching to hit the function just once. See this page for more details.

Short example:

from flask_caching import Cache
cache = Cache(app.server, config={
    'CACHE_TYPE': 'filesystem',
    'CACHE_DIR': 'cache-directory',
})

@cache.memoize(timeout=6000)
def my_cached_function():
    return program_exe.update_data()

I don't have your func but, when I tested it locally with a placeholder, it was originally called twice, but only once after adding caching.