Black Lives Matter. Please consider donating to Black Girls Code today.

Remove unnecessary exceptions during update method

Dear forum, I am building a stock look up dashboard using Alpha Vantage API.

API_URL = "https://www.alphavantage.co/query" 

app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])
app.config.suppress_callback_exceptions = True

app.layout = html.Div([
    html.Div(
    dcc.Input(
        placeholder='Search for stock symbol',
        type='text',
        value='',
        id = "input",
        size = 25
    ),),
    dcc.Dropdown(
        id = 'dropdown-to-show_or_hide-element',
        options=[
            {'label': 'Show search results', 'value': 'on'},
            {'label': 'Hide search results', 'value': 'off'}
        ],
        value = 'on'
    ),
    html.Div(
    id = "results",
      children = dash_table.DataTable(
        id = "tableid",
        columns=(
            [{'id': 'Symbol', 'name': 'Symbol'}, 
            {'id': "Name", 'name': "Name"},
            {"id":"Match_Score", "name":"Match Score"}]
        ),
        data=[{'Symbol': "", "Name": "", "Match_Score": ""} for i in range(len(symbols))],
), style={'width' : '100%', "display": 'table'}),
    html.Div(id="output")
])

@app.callback(
   Output(component_id='tableid', component_property='data'),
   [Input(component_id='input', component_property='value')])
def show_hide_element(text):
    print(text)
    if text is not None:
        data = { "function": "SYMBOL_SEARCH", 
        "keywords": text,
        "datatype": "json", 
        "apikey": '"apikey'} 
        response = requests.get(API_URL, data) 
        data = response.json()
        keys =['1. symbol', '2. name', '9. matchScore']
        search_result = []
        print(data)
        for i in range(len(data["bestMatches"])):
            for key in keys:
                search_result.append(data["bestMatches"][i].get(key)) 
        symbols = [search_result[i] for i in range(len(search_result)) if i % 3 == 0]
        fullname = [search_result[i] for i in range(len(search_result)) if i % 3 == 1]
        score = [search_result[i] for i in range(len(search_result)) if i % 3 == 2]
        return [{'Symbol':symbols[i], "Name":fullname[i], "Match_Score":score[i]} for i in range(len(symbols))]

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

The code works but due to the way the data is acquired there appear to be some time lag and somehow exceptions are guaranteed to occur before a call is completed. The exceptions are repeated several times. Is there a way to avoid the exceptions?

{Error Message': 'Invalid API call. Please retry or visit the documentation (https://www.alphavantage.co/documentation/) for SYMBOL_SEARCH.'}

Exception on /_dash-update-component [POST]
Traceback (most recent call last):
File “D:\Anaconda3\lib\site-packages\flask\app.py”, line 2446, in wsgi_app
response = self.full_dispatch_request()
File “D:\Anaconda3\lib\site-packages\flask\app.py”, line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File “D:\Anaconda3\lib\site-packages\flask\app.py”, line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File “D:\Anaconda3\lib\site-packages\flask_compat.py”, line 39, in reraise
raise value
File “D:\Anaconda3\lib\site-packages\flask\app.py”, line 1949, in full_dispatch_request
rv = self.dispatch_request()
File “D:\Anaconda3\lib\site-packages\flask\app.py”, line 1935, in dispatch_request
return self.view_functionsrule.endpoint
File “D:\Anaconda3\lib\site-packages\dash\dash.py”, line 1459, in dispatch
response.set_data(self.callback_map[output]“callback”)
File “D:\Anaconda3\lib\site-packages\dash\dash.py”, line 1339, in add_context
output_value = func(*args, **kwargs) # %% callback invoked %%
File “”, line 52, in show_hide_element
for i in range(len(data[“bestMatches”])):
KeyError: ‘bestMatches’

you probably need
if text != ‘’:
rather than
if text is not None
because you have initialized the input to be an empty string
(sorry on my phone with limited formatting capabilities)

I am not sure why what still throws the error (still a bit fuzzy about how plotly dash initiates at startup) but I found that

    try:
        if text != "":

    except UnboundLocalError:
        return ""

is the most intuition solution (I am using the text variable to assign for lists so if it will give local error)