I was’t sure what to title this… in my app, I have some API calls which I’d like to minimize for financial implications. The user will have some text boxes to type into, I take those contents and some other options, build an API call and make the request. Currently, I’m using a button as an Input
and the dcc.Input
boxes are passed via State
to avoid the callback trying to fire with every changed character.
I’d like to figure out how to only run the API call for changed elements when the button is pushed. Here’s a rough example, representing doing something based on a click with the box contents:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, Event, State
import numpy as np
app = dash.Dash(__name__)
server = app.server
app.css.append_css({'external_url': 'https://codepen.io/chriddyp/pen/bWLwgP.css'})
app.layout = html.Div([
html.H2('non-redundant callbacks'),
html.Label('enter up to 2 numbers'),
dcc.Input(id='box_1', type='number'),
dcc.Input(id='box_2', type='number'),
html.Button('run!', id='run', n_clicks=0),
html.Div(id='out')])
@app.callback(
Output('out', 'children'),
[Input('run', 'n_clicks')],
[State('box_1', 'value'),
State('box_2', 'value')])
def contents(clicks, box_1, box_2):
boxes = [box_1, box_2]
message = list()
for i in range(len(boxes)):
if boxes[i] is not None:
message.append('{}: {}'.format(i, boxes[i]**2))
return(str(message))
if __name__ == '__main__':
app.run_server(debug=True)
So, let’s say the user puts in 2
and 3
, then clicks the button. Squaring represents an “expensive” computation (or API call). Let’s say the user changes 3
to 4
. I’d like to keep the value of 2
and it’s associated return the same. After all, we did the work once already, why do it again? I can’t find it at the moment, but I know I’ve seen a post somewhere about global variables being frowned upon. What might be a different approach to this?
Ideally I’d find a solution that ignored order ([2, 3]
has the same generated output as [3, 2]
), but for now I’d just like it such that for a single given input, if it’s contents don’t change between button clicks, I don’t re-run the API call with it.
Thanks for any ideas!