Black Lives Matter. Please consider donating to Black Girls Code today.
Dash HoloViews is now available! Check out the docs.

DASH app producing error, but python function works outside of the app

Hi I’m trying to create a DASH app to pull financial data from yahoo finance.

The code is below. If you take the code in between “ticker = args” (and replace this with either an input function ,or just specify a stock symbol as a string), and is_df = is_df.astype(float), the code works fine and you can create graphs of the data using seaborn or matplotlib. However when I place the code within the callback, it tells me that it’s getting this error: TypeError: can only concatenate str (not “tuple”) to str

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
from dash.dependencies import Input, Output
import pandas as pd  
import numpy as np
from bs4 import BeautifulSoup
import requests
import json

app = dash.Dash(__name__)
app.layout = html.Div([
    # Input the stock ticker
    html.Div([
        dcc.Input(id="input",
                  placeholder='Please insert stock', type="text"),
        dcc.Graph(id = 'revenue')
    ])
])

@app.callback(Output("input", "value"),
              [Input("input", "n_submit")])   
def enter_key(n_sub):
    return n_sub
    
@app.callback(Output('revenue', 'figure'),
             Input('input', 'value'))
def update_figs(*args):
    ticker = args
    url_stem = 'https://finance.yahoo.com/quote/'
    url_full = url_stem + ticker+'/financials'
    response = requests.get(url_full)
    soup = BeautifulSoup(response.content, 'lxml')
    income_statement_data = soup.find_all('div', {'class':'D(tbr)'})
    columns = []
    for x in income_statement_data[0]:
        temp = x.text
        columns.append(temp)
    rows = []
    for x in income_statement_data:
        temp = x.find_all('div', class_= 'D(tbc)')
        rows.append(temp)
    rows = rows[1:] #Get rid of the first row since it's just None
    r = []
    for x in rows:
        s = []
        for i in x:
            temp = i.text
            s.append(temp)
        r.append(s)
    is_df = pd.DataFrame(r)
    is_df.columns = columns
    is_df = is_df.set_index('Breakdown')
    columns = list(is_df.columns)
    for x in columns:
        is_df[x] = is_df[x].str.replace(',','')
        is_df[x] = is_df[x].str.replace('-','')
        is_df[x] = is_df[x].replace(r'^\s*$', np.nan, regex=True)
        is_df[x] = is_df[x].fillna(0)
        is_df[x] = is_df[x].astype(float)
    dash_is_df = is_df.T.reset_index()
    figure = px.bar(dash_is_df, x = 'index', y = 'Total Revenue')`
    return figure

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

Hi @jwang25 and welcome to the Dash community! :grinning:

I’m just guessing here — since I didn’t test this…

but try removing the errant ` from the very end of this statement:

figure = px.bar(dash_is_df, x = 'index', y = 'Total Revenue')`

Haha no, that was just a typo when I copy pasted for my post, the script runs, the problem is that it’s not taking inputs correctly

Hi @jwang25,

Why you are using a callback to overwrite the Input value?

The problem is solved if you change the def argument directy for ticker:

def update_figs(ticker):

Also include the debounce=True property in the Input to avoid sending incompleate or None Ticker value to the callback.

Sorry I’m a bit slow to this. I had tried update_figs(ticker, input, etc) but it said that the value was not found