Reach

Grow

Manage

Automate

Reach

Grow

Manage

Automate

一个带鸟类 API 的仪表盘工具

扎卡里·萨缪尔斯

2022年3月24日

电子邮件

1 min read

一个带鸟类 API 的仪表盘工具

扎卡里·萨缪尔斯

2022年3月24日

电子邮件

1 min read

一个带鸟类 API 的仪表盘工具

这个脚本只是触及了利用 Python、Plotly Dash 和我们的 API 所能实现的可能性的表面。

几乎一年前,Bird的客户成功总监Tom Mairs写了一个邮件工具,利用了Bird APIs。在这篇文章中,我接着他的话题。他的工具允许定时传输工作,但如果我们想创建自己的仪表盘和事件日志呢?

也许我想为业务组创建一个特定的仪表盘或面向客户的仪表盘,但不提供用户对Bird UI的完整访问权限。这个脚本只是触及了利用PythonPlotly Dash我们的APIs的可能性。在构建处理大量API数据的仪表盘时,请注意基础设施组件如DNS可能成为瓶颈 - 我们曾遇到AWS DNS扩展挑战,影响了我们的数据处理能力。对于热衷于可视化工作流的人士,你也可以探索将Flow Builder与Google Cloud Functions和Vision API集成,为你的数据处理管道添加AI驱动的自动化。

当我开始在网上搜索时,我想找到阻力最小的路径。我本可以自己用HTML和python创建所有的仪表盘和UI,然而,在进行了一些Google搜索后,我遇到了Plotly的Dash,它很容易集成到python中。我选择Dash的原因有两个:1) 它是开源的,2) 阅读文档后,它似乎很容易为我想做的事情定制。Dash是一个开源库,非常适合构建和部署具有定制用户界面的数据应用。 这使得创建UI极其简单。然后问题变成,我想让这个应用程序有多复杂呢?花的时间越多,我想添加的特性就越多。

对于初始项目,我想确保我有一个具有可定制指标和可选择时间框架的仪表盘。最初,我开始使用一个只能从下拉菜单中选择一个指标的仪表盘。后来,在从同事那里获得反馈后,我稍微完善了仪表盘,增加了多选和轴标题。我还决定为事件日志添加一个附加的选项卡。我达到了一点,即我对作为任何想构建自己仪表盘的人的良好起点已经感到满意。对于希望将实时webhook数据输入其仪表盘的开发者,请查看我们的使用Azure Functions构建webhook消费者的指南。当然,我把项目放在Github上以供你克隆或分支。

入门

要访问此app,您需要确保正在运行 python 3.10 或更高版本,并安装以下库:

  • requests

  • dash

  • pandas

然后,将您的 API 密钥输入到 App.py 并运行该 app。它将在http://localhost:8050上运行。有关将其部署到面向公众的服务器(例如 AWS)的更多信息,请参阅以下资源:

Creating the Dashboard Page

首先,初始化数据框和仪表板。在初始化仪表板之前,UI中将不会出现仪表板。

df = pd.DataFrame({

"Count": [0,0],

"Time": [0,0]

})

fig = px.line(df,x="Time",y="Count")

然后,构建第一个标签页。这是一个应用回调的组合(用于检查正在使用哪个标签页);以及一个条件函数,用于检查当前选择的标签页。下面的代码仅构建空白仪表板和UI元素(稍后我们将处理事件标签页)。dcc元素是Dash核心组件HTML组件,允许在UI中轻松使用HTML。

html.H2('Analytics Dashboard'),

#多选下拉菜单

dcc.Dropdown(['Count Accepted','Count Admin Bounce','Count Block Bounce','Count Bounce','Count Clicked','Count Delayed', 'Count Delayed First','Count Delivered','Count Delivered First','Count Delivered Subsequent','Count Generation Failed', 'Count Generation Rejection','Count Hard Bounce','Count Inband Bounce','Count Initial Rendered','Count Injected', 'Count Out of Band Bounce', 'Count Policy Rejection','Count Rejected','Count Rendered','Count Sent','Count Soft Bounce', 'Count Spam Complaint','Count Targeted','Count Undetermined Bounce','Count Unique Clicked','Count Unique Confirmed Opened', 'Count Unique Initial Rendered','Count Unique Rendered','Count Unsubscribe','Total Delivery Time First','Total Delivery Time Subsequent', 'Total Message Volume'], id="y-axis", multi=True, searchable=True, placeholder="Select metrics(s)"),

#日期选择器(最大允许日期设置为今天) dcc.DatePickerRange( id='date-picker-range', start_date=date(2022,1,1), end_date=date(2022, 2, 1), max_date_allowed=date(datetime.today().year,datetime.today().month,datetime.today().day), ),

#图表对象 dcc.Graph( id='Emails', figure=fig )

注意使用dash如何简单地创建带有多选、可搜索下拉菜单的仪表板UI。要禁用多选或搜索,创建下拉菜单的参数可以轻松修改。我发现这个项目最复杂的部分是从输入中构建实际数据框架,以及让HTML + CSS在UI中正确工作。

时间序列指标API允许基于日期/时间范围提取33个单独的指标。您可以通过域、广告系列、IP池、发送域、子账户进行更深入筛选,并指定时间序列数据的精度。结合可交付能力分析的这些附加过滤器可能是这个项目的未来改进(需要为没有可交付能力分析访问权限的客户实现错误捕获)。

利用并调用指标API,我根据用户选择的参数和指定的时间框架构建一个仪表板。初始化的仪表板随后会更新。

#利用提供的参数构建API调用 params = { "from" : start_date + "T00:00", "to" : end_date + "T00:00", "delimiter" : ",", "precision" : "day", "metrics" : joined_values } api_url = BASE_URL + "/metrics/deliverability/time-series" response_API = requests.get(api_url, headers = {"Authorization" : API_KEY}, params=params) response_info = json.loads(response_API.text) new_df = pd.json_normalize(response_info, record_path=['results']) value_array = joined_values.split(",") #利用更新API调用的新指标和日期构建一个新的仪表板 fig = px.line(new_df, x=new_df['ts'], y=value_array, labels={"value": "Count", "variable": "Metric","ts":"Date"}) fig.update_xaxes(title_text="Time") fig.update_yaxes(title_text="Count") return fig

以下是选择多个指标和扩展时间框架的示例。


Sparkpost analytics dashboard

注意:dash图表中有许多内置项目(悬停、缩放、自动缩放)。

首先,初始化数据框和仪表板。在初始化仪表板之前,UI中将不会出现仪表板。

df = pd.DataFrame({

"Count": [0,0],

"Time": [0,0]

})

fig = px.line(df,x="Time",y="Count")

然后,构建第一个标签页。这是一个应用回调的组合(用于检查正在使用哪个标签页);以及一个条件函数,用于检查当前选择的标签页。下面的代码仅构建空白仪表板和UI元素(稍后我们将处理事件标签页)。dcc元素是Dash核心组件HTML组件,允许在UI中轻松使用HTML。

html.H2('Analytics Dashboard'),

#多选下拉菜单

dcc.Dropdown(['Count Accepted','Count Admin Bounce','Count Block Bounce','Count Bounce','Count Clicked','Count Delayed', 'Count Delayed First','Count Delivered','Count Delivered First','Count Delivered Subsequent','Count Generation Failed', 'Count Generation Rejection','Count Hard Bounce','Count Inband Bounce','Count Initial Rendered','Count Injected', 'Count Out of Band Bounce', 'Count Policy Rejection','Count Rejected','Count Rendered','Count Sent','Count Soft Bounce', 'Count Spam Complaint','Count Targeted','Count Undetermined Bounce','Count Unique Clicked','Count Unique Confirmed Opened', 'Count Unique Initial Rendered','Count Unique Rendered','Count Unsubscribe','Total Delivery Time First','Total Delivery Time Subsequent', 'Total Message Volume'], id="y-axis", multi=True, searchable=True, placeholder="Select metrics(s)"),

#日期选择器(最大允许日期设置为今天) dcc.DatePickerRange( id='date-picker-range', start_date=date(2022,1,1), end_date=date(2022, 2, 1), max_date_allowed=date(datetime.today().year,datetime.today().month,datetime.today().day), ),

#图表对象 dcc.Graph( id='Emails', figure=fig )

注意使用dash如何简单地创建带有多选、可搜索下拉菜单的仪表板UI。要禁用多选或搜索,创建下拉菜单的参数可以轻松修改。我发现这个项目最复杂的部分是从输入中构建实际数据框架,以及让HTML + CSS在UI中正确工作。

时间序列指标API允许基于日期/时间范围提取33个单独的指标。您可以通过域、广告系列、IP池、发送域、子账户进行更深入筛选,并指定时间序列数据的精度。结合可交付能力分析的这些附加过滤器可能是这个项目的未来改进(需要为没有可交付能力分析访问权限的客户实现错误捕获)。

利用并调用指标API,我根据用户选择的参数和指定的时间框架构建一个仪表板。初始化的仪表板随后会更新。

#利用提供的参数构建API调用 params = { "from" : start_date + "T00:00", "to" : end_date + "T00:00", "delimiter" : ",", "precision" : "day", "metrics" : joined_values } api_url = BASE_URL + "/metrics/deliverability/time-series" response_API = requests.get(api_url, headers = {"Authorization" : API_KEY}, params=params) response_info = json.loads(response_API.text) new_df = pd.json_normalize(response_info, record_path=['results']) value_array = joined_values.split(",") #利用更新API调用的新指标和日期构建一个新的仪表板 fig = px.line(new_df, x=new_df['ts'], y=value_array, labels={"value": "Count", "variable": "Metric","ts":"Date"}) fig.update_xaxes(title_text="Time") fig.update_yaxes(title_text="Count") return fig

以下是选择多个指标和扩展时间框架的示例。


Sparkpost analytics dashboard

注意:dash图表中有许多内置项目(悬停、缩放、自动缩放)。

首先,初始化数据框和仪表板。在初始化仪表板之前,UI中将不会出现仪表板。

df = pd.DataFrame({

"Count": [0,0],

"Time": [0,0]

})

fig = px.line(df,x="Time",y="Count")

然后,构建第一个标签页。这是一个应用回调的组合(用于检查正在使用哪个标签页);以及一个条件函数,用于检查当前选择的标签页。下面的代码仅构建空白仪表板和UI元素(稍后我们将处理事件标签页)。dcc元素是Dash核心组件HTML组件,允许在UI中轻松使用HTML。

html.H2('Analytics Dashboard'),

#多选下拉菜单

dcc.Dropdown(['Count Accepted','Count Admin Bounce','Count Block Bounce','Count Bounce','Count Clicked','Count Delayed', 'Count Delayed First','Count Delivered','Count Delivered First','Count Delivered Subsequent','Count Generation Failed', 'Count Generation Rejection','Count Hard Bounce','Count Inband Bounce','Count Initial Rendered','Count Injected', 'Count Out of Band Bounce', 'Count Policy Rejection','Count Rejected','Count Rendered','Count Sent','Count Soft Bounce', 'Count Spam Complaint','Count Targeted','Count Undetermined Bounce','Count Unique Clicked','Count Unique Confirmed Opened', 'Count Unique Initial Rendered','Count Unique Rendered','Count Unsubscribe','Total Delivery Time First','Total Delivery Time Subsequent', 'Total Message Volume'], id="y-axis", multi=True, searchable=True, placeholder="Select metrics(s)"),

#日期选择器(最大允许日期设置为今天) dcc.DatePickerRange( id='date-picker-range', start_date=date(2022,1,1), end_date=date(2022, 2, 1), max_date_allowed=date(datetime.today().year,datetime.today().month,datetime.today().day), ),

#图表对象 dcc.Graph( id='Emails', figure=fig )

注意使用dash如何简单地创建带有多选、可搜索下拉菜单的仪表板UI。要禁用多选或搜索,创建下拉菜单的参数可以轻松修改。我发现这个项目最复杂的部分是从输入中构建实际数据框架,以及让HTML + CSS在UI中正确工作。

时间序列指标API允许基于日期/时间范围提取33个单独的指标。您可以通过域、广告系列、IP池、发送域、子账户进行更深入筛选,并指定时间序列数据的精度。结合可交付能力分析的这些附加过滤器可能是这个项目的未来改进(需要为没有可交付能力分析访问权限的客户实现错误捕获)。

利用并调用指标API,我根据用户选择的参数和指定的时间框架构建一个仪表板。初始化的仪表板随后会更新。

#利用提供的参数构建API调用 params = { "from" : start_date + "T00:00", "to" : end_date + "T00:00", "delimiter" : ",", "precision" : "day", "metrics" : joined_values } api_url = BASE_URL + "/metrics/deliverability/time-series" response_API = requests.get(api_url, headers = {"Authorization" : API_KEY}, params=params) response_info = json.loads(response_API.text) new_df = pd.json_normalize(response_info, record_path=['results']) value_array = joined_values.split(",") #利用更新API调用的新指标和日期构建一个新的仪表板 fig = px.line(new_df, x=new_df['ts'], y=value_array, labels={"value": "Count", "variable": "Metric","ts":"Date"}) fig.update_xaxes(title_text="Time") fig.update_yaxes(title_text="Count") return fig

以下是选择多个指标和扩展时间框架的示例。


Sparkpost analytics dashboard

注意:dash图表中有许多内置项目(悬停、缩放、自动缩放)。

创建Event Details 页面

活动详情页面稍微困难一点,因为我不知道如何以易于阅读的方式呈现所有活动指标。我考虑过在此页面上添加过滤参数,但是,我决定这样做将为这个项目增加大量时间,因为表格需要变得动态(以及添加参数、回调等)。最后,我选择显示所有活动,并将时间戳放在首位(因为如果不放在首位,图表就不好阅读)。最初,我发现仅凭原始HTML,表格在视觉上非常困难。没有边框和标题与行之间的颜色差异。为了让表格更易读,我在Dash中使用了CSS。

活动详情的想法几乎和仪表板一样,除了这次,我调用Events API并带入所有事件。注意活动详情仅显示最近的10个事件(利用max_rows参数和API过滤)。这可以增加,不过,我选择展示最近的10个事件,因为显示的事件越多,API调用耗时越长。可以做的一个重大改进是能够分页并在用户界面中包含下一页/上一页。

要构建活动标签(页面),首先,我调用Events API并将JSON响应解析为数据框。然后我对数据框进行排序和重新排序,将时间戳放在第一列。最后,我通过遍历数据框来构建HTML表格。

#构建并调用事件API params = { "events" : "delivery,injection,bounce,delay,policy_rejection,out_of_band,open,click,generation_failure,generation_rejection,spam_complaint,list_unsubscribe,link_unsubscribe", "delimiter" : ",", "page" : "1", "per_page" : "10" } api_url = BASE_URL + "/events/message" response_API = requests.get(api_url, headers = {"Authorization" : API_KEY}, params=params) response_info = json.loads(response_API.text) new_df = pd.json_normalize(response_info, record_path=['results']) max_rows=10 #事件表中显示的最大结果数 #将时间戳放在表中的第一列 new_df = new_df.reindex(sorted(new_df.columns), axis=1) cols = ['timestamp'] new_df = new_df[cols + [c for c in new_df.columns if c not in cols]] #显示带有事件表的新HTML(注意,该表还引用table.css) return html.Div([ html.H2("Event Details"), html.Table([ html.Thead( html.Tr([html.Th(col) for col in new_df.columns],className="table_css") ), html.Tbody([ html.Tr([ html.Td(new_df.iloc[i][col],className="table_css") for col in new_df.columns ]) for i in range(min(len(new_df), max_rows)) ]) ]) ])

在用户界面中看起来像这样。

Sparkpost event details

下一步

对于希望创建自己的仪表板或事件日志的人来说,这是一个好的开始。通过此处的自定义功能,天空才是极限。

如上所述,未来可以进行的一些改进包括:

  • 向仪表板添加可交付性分析

  • 向仪表板添加更多过滤器

  • 可能的缓存选项以便每次显示页面时不会调用API

  • UI 改进

  • 向事件详情页面添加过滤和分页

我很感兴趣听任何反馈或关于扩展此项目的建议。

~ Zach Samuels, Bird 高级解决方案工程师

让我们为您联系Bird专家。
在30分钟内见证Bird的全部威力。

通过提交,您同意 Bird 可能会就我们的产品和服务与您联系。

您可以随时取消订阅。查看Bird的隐私声明以获取有关数据处理的详细信息。

Newsletter

通过每周更新到您的收件箱,随时了解 Bird 的最新动态。

让我们为您联系Bird专家。
在30分钟内见证Bird的全部威力。

通过提交,您同意 Bird 可能会就我们的产品和服务与您联系。

您可以随时取消订阅。查看Bird的隐私声明以获取有关数据处理的详细信息。

Newsletter

通过每周更新到您的收件箱,随时了解 Bird 的最新动态。

让我们为您联系Bird专家。
在30分钟内见证Bird的全部威力。

通过提交,您同意 Bird 可能会就我们的产品和服务与您联系。

您可以随时取消订阅。查看Bird的隐私声明以获取有关数据处理的详细信息。

R

Reach

G

Grow

M

Manage

A

Automate

Newsletter

通过每周更新到您的收件箱,随时了解 Bird 的最新动态。