I’m building an app that uses Dash and Plotly to show data in graphs. With Dash, I’ve been able to get the page layout to render, but when I add @app.callback
I get output_spec = kwargs.pop("outputs_list") KeyError: 'outputs_list'
. There’s not a lot of answers regarding this error from Dash so It has been hard to get to the bottom of what’s causing it.
@app.callback(
Output("conversion_rate_text", "children"),
Output("ttr_text", "children"),
Output("cpa_text", "children"),
Output("cpt_text", "children"),
Output("installs_text", "children"),
Input('org-picker-dropdown', 'value'),
Input('my-date-picker-range', 'start_date'),
Input('my-date-picker-range', 'end_date')
)
def generate_report(client, appId):
print("START")
start_date = "2020-11-01"
end_date = "2020-12-20"
firebaseBucket = storage.bucket()
print(firebaseBucket)
url = "https://api.searchads.apple.com/api/v2/acls"
keyBlobText = 'users/{client}/asa_accounts/{appId}/api_certificates/account.key'.format(client = client, appId = appId)
pemBlobText = 'users/{client}/asa_accounts/{appId}/api_certificates/account.pem'.format(client = client, appId = appId)
if firebaseBucket.blob(keyBlobText):
print("GETTING KEY AND PEM")
key = firebaseBucket.blob(keyBlobText)
pem = firebaseBucket.blob(pemBlobText)
key.download_to_filename("client.key")
pem.download_to_filename("client.pem")
asa_response = requests.get(url, cert=(asa_pem, asa_key))
orgId = asa_response.json()['data'][0]['orgId']
blobs = firebaseBucket.list_blobs()
for blob in blobs:
print(blob.name)
allCampaigns = get_campaigns(client, appId, orgId, start_date, end_date)
conversion_rate = format_rate(allCampaigns[0]['conversionRate']) + '%'
ttr = format_rate(allCampaigns[0]['ttr']) + '%'
cpa = format_num(allCampaigns[0]['avgCPA']['amount']) + ' ' + allCampaigns[0]['avgCPA']['currency']
cpt = format_num(allCampaigns[0]['avgCPT']['amount']) + ' ' + allCampaigns[0]['avgCPT']['currency']
installs = format_num(allCampaigns[0]['installs'])
if allCampaigns:
new_re_downloads_chart = {
'data': [{
'y': ['New Downloads ', 'Re-downloads '],
'x': [grand_totals['newDownloads'], grand_totals['redownloads']],
'orientation':'h',
'type': 'bar',
'name': 'New/Re - Downloads'
}],
'layout': {
'yaxis': {
'automargin': True
}
}
}
else:
new_re_downloads_chart = {}
return allCampaigns, conversion_rate, ttr, cpa, cpt, installs, orgId
def get_layout(client, appId):
print("PLOTLY")
client = "client"
appId = "id"
user_id = client
current_asa_account_id = appId
campaing_frames = generate_report(client, appId)
company_name ="THE COMPANY"
orgs = {'orgName': "THEORG", 'orgId': campaing_frames[6]}
layout = html.Div(
[
dcc.Store(id="aggregate_data"),
# empty Div to trigger javascript file for graph resizing
html.Div(id="output-clientside"),
html.Div(
[
html.Div(
[
html.Img(
src=app.get_asset_url("logo.png"),
id="plotly-image",
style={
"height": "60px",
"width": "auto",
"margin-bottom": "25px",
},
)
],
className="one-third column",
),
html.Div(
[
html.Div(
[
html.H3(
client,
style={"margin-bottom": "0px"},
),
html.H5(
company_name, style={"margin-top": "0px"}
)
]
)
],
className="one-half column",
id="title",
),
],
id="header",
className="row flex-display",
style={"margin-bottom": "25px"},
),
html.Div(
[
html.Div(
[
html.P("Choose an Organization (Campaign Group):"),
dcc.Dropdown(
options= [{'label':org[0], 'value': org[1]} for org in orgs],
##value= orgs[0]['orgId'],
value= campaing_frames[6],
searchable=False,
id='org-picker-dropdown'
),
html.P("Report Date Range:"),
dcc.DatePickerRange(
id='my-date-picker-range',
min_date_allowed=datetime(2010, 1, 1),
max_date_allowed=datetime.now().date(),
initial_visible_month=get_last_month_start(),
# initialize as past 30 days
start_date= datetime.now().date() - relativedelta(days=30), # get_last_month_start(),
end_date= datetime.now().date() # get_last_month_end()
),
],
className="pretty_container",
id="cross-filter-options",
),
html.Div(
[
html.Div(
[
html.Div(
[html.H6(id="conversion_rate_text"), html.P("Conversion Rate")],
id="conversion_rate_card",
className="mini_container",
),
html.Div(
[html.H6(id="ttr_text"), html.P("TTR")],
id="ttr_card",
className="mini_container",
),
html.Div(
[html.H6(id="cpa_text"), html.P("CPI")],
id="oicpa_cardl",
className="mini_container",
),
html.Div(
[html.H6(id="cpt_text"), html.P("CPT")],
id="cpt_card",
className="mini_container",
),
html.Div(
[html.H6(id="installs_text"), html.P("Total Installs")],
id="installs_card",
className="mini_container",
),
],
id="info-container",
className="row container-display",
),
],
id="right-column",
className="container one-half column",
),
],
className="row flex-display",
),
html.Div(
[dcc.Graph(id="installs_time_series_chart")],
id="installs_time_series_chart_container",
className="pretty_container four column",
),
html.Div(
[dcc.Graph(id="cpi_time_series_chart")],
id="cpi_time_series_chart_container",
className="pretty_container four column",
),
html.Div(
[dcc.Graph(id="new_re_downloads_chart")],
id="new_re_downloads_chart_container",
className="pretty_container four column",
),
],
id="mainContainer",
style={"display": "flex", "flex-direction": "column"},
)
return layout
if __name__ == '__main__':
get_layout("aaa", "sss")
The full error:
Traceback (most recent call last):
File "/home/computer/Documents/app/report.py", line 522, in <module>
get_layout("aaa", "sss")
File "/home/computer/Documents/app/report.py", line 373, in get_layout
campaing_frames = generate_report(client, appId)
File "/home/computer/Documents/app/ENV/lib/python3.8/site-packages/dash/dash.py", line 1004, in add_context
output_spec = kwargs.pop("outputs_list")
KeyError: 'outputs_list'
To add context of what is returned from allCampaigns = get_campaigns(client, appId, orgId, start_date, end_date)
a_campaign = {"campaignName": row.campaign.name, "campaignId": row.campaign.id,
"clicks": row.metrics.clicks, "conversions": row.metrics.conversions,
"costPerClick": row.metrics.average_cpc, "costPerConversion": costPerConv}
ga_campaign
is then turned into a dataframe: return ga_dataFrame = pd.DataFrame([ga_campaign])
Is there something wrong with how I set up the callback? Is this a data issue from generate_report(client, appId)
?