You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python调用SendGrid API时如何处理KeyError异常保障日报运行?

处理SendGrid API空统计数据的异常问题

嘿,我明白你的困扰!这个KeyError确实是因为当三天前没有可用数据时,API返回的stats是个空列表,导致后续处理DataFrame的时候找不到name列。咱们可以通过提前检查数据是否为空异常捕获两种方式来解决,让程序能稳定运行不中断。

方案1:提前检查返回的统计数据是否为空

在循环处理每个品牌的API响应时,先判断stats列表有没有内容,如果是空的就直接跳过当前品牌的处理,避免后续报错。修改后的代码如下:

import pandas as pd
import json
import datetime
import http.client

threedaysago = datetime.date.fromordinal(datetime.date.today().toordinal()-3).strftime("%F")
conn = http.client.HTTPSConnection("api.sendgrid.com")
payload = "{}"
keys = {
    # "CF" : "SG.UdhzjmjYR**.-",
}
df = [] # Create new Dataframe

for name, value in keys.items():
    headers = {
        'authorization': "Bearer " + value
    }
    conn.request("GET", "/v3/categories/stats/sums?aggregated_by=&start_date={d}&end_date={d}".format(d=threedaysago), payload, headers)
    res = conn.getresponse()
    data = res.read()
    print(data.decode("utf-8"))
    d = json.loads(data.decode("utf-8"))
    c = d['stats']
    
    # 新增:检查stats是否为空,为空则跳过当前品牌
    if not c:
        print(f"品牌 {name} 在 {threedaysago} 没有统计数据,跳过处理")
        continue
    
    df.append(c)

# 新增:检查是否有有效数据可以处理
if df:
    # Load data row into df #1
    df = pd.DataFrame(df[0])
    df_new = df[['name']]
    df_new.rename(columns={'name':'Category'}, inplace=True)
    df_metric =pd.DataFrame(list(df['metrics'].values))
    sendgrid = pd.concat([df_new, df_metric], axis=1, sort=False)
    sendgrid.set_index('Category', inplace = True)
    sendgrid.insert(0, 'Date', threedaysago)
    sendgrid.insert(1,'BrandId',99)
    sendgrid.rename(columns={
        'blocks':'Blocks',
        'bounce_drops' : 'BounceDrops',
        'bounces': 'Bounces',
        'clicks':'Clicks',
        'deferred':'Deferred',
        'delivered':'Delivered',
        'invalid_emails': 'InvalidEmails',
        'opens':'Opens',
        'processed':'Processed',
        'requests':'Requests',
        'spam_report_drops' : 'SpamReportDrops',
        'spam_reports' : 'SpamReports',
        'unique_clicks' : 'UniqueClicks',
        'unique_opens' : 'UniqueOpens',
        'unsubscribe_drops' : 'UnsubscribeDrops',
        'unsubscribes': 'Unsubscribes'
    }, inplace=True)
    # 这里可以添加保存或发送日报的代码
else:
    print(f"所有品牌在 {threedaysago} 都没有统计数据,本次日报无内容")
    # 可以选择生成空报表或者发送提示消息

方案2:用try-except捕获异常

如果担心还有其他可能的KeyError情况,可以用try-except块包裹DataFrame处理逻辑,这样即使出现意外错误,程序也不会中断:

# ... 前面的循环代码和方案1一样 ...

try:
    df = pd.DataFrame(df[0])
    df_new = df[['name']]
    df_new.rename(columns={'name':'Category'}, inplace=True)
    df_metric =pd.DataFrame(list(df['metrics'].values))
    sendgrid = pd.concat([df_new, df_metric], axis=1, sort=False)
    sendgrid.set_index('Category', inplace = True)
    sendgrid.insert(0, 'Date', threedaysago)
    sendgrid.insert(1,'BrandId',99)
    sendgrid.rename(columns={
        'blocks':'Blocks',
        'bounce_drops' : 'BounceDrops',
        # ... 其他列名映射 ...
    }, inplace=True)
except KeyError as e:
    print(f"处理日报数据时出错:{e},大概率是因为 {threedaysago} 没有可用统计数据")
    # 这里可以执行备选逻辑,比如生成空的日报模板

为什么这样有效?

当API返回"stats":[]时,c就是空列表,我们通过if not c直接跳过后续的数据处理步骤,避免了创建空DataFrame后去查找不存在的name列。而try-except则是兜底方案,能捕获任何KeyError异常,让程序继续运行。

内容的提问来源于stack exchange,提问作者user12384956

火山引擎 最新活动