一个带鸟类 API 的仪表盘工具
扎卡里·萨缪尔斯
2022年3月24日
电子邮件
1 min read

关键要点
Bird APIs 可以与 Python 和 Plotly Dash 结合来构建强大的交互式仪表板,无需使用完整的 Bird UI。
该项目展示了如何使用 Bird 的指标 API 和事件 API 在自定义 web 应用中可视化指标和事件。
Plotly Dash 提供了快速的开源框架,用于构建下拉菜单、图表和表格等 UI 元素。
开发人员可以扩展工具,增强可送达性分析、过滤和分页,以创建更加丰富的仪表板。
未来的增强包括缓存、改进 UI 以及与其他 Bird 产品或第三方 API 的集成。
代码库(可在 GitHub 上获取)为任何想要构建 Bird 驱动的仪表板或面向客户的门户的人提供了强大的起点。
Q&A 精华
这个dashboarding项目的目标是什么?
这展示了开发人员如何使用 Bird 的 API 与 Python 和 Plotly Dash 来创建数据驱动的仪表板,以可视化活动指标和近期事件。
为什么使用 Plotly Dash 来进行 Bird APIs?
Dash 是开源的,易于定制,且非常适合创建交互式用户界面,无需前端专业知识。
仪表板显示什么?
它可视化来自Bird的Metrics API的时间序列指标和来自Events API的最新事件数据,具有在自定义时间范围内过滤和选择指标的选项。
该工具如何进一步扩展?
通过添加可交付性分析、先进的过滤器、数据缓存以及大数据集的分页来提高性能和可用性。
需要什么技能或工具来运行它?
基本的Python知识和安装requests、dash和pandas。需要一个来自Bird的API密钥来拉取数据。
这个项目如何融入Bird的生态系统?
它展示了如何利用Bird的开放API为没有访问完整平台的团队或客户创建自定义仪表板和报告工具。
这个脚本只是触及了利用 Python、Plotly Dash 和我们的 API 所能实现的可能性的表面。
Bird Metrics API + 使用Python进行仪表板创建
大约一年前,Bird的客户成功总监Tom Mairs开发了一个使用Bird APIs的邮件工具。在这篇文章中,我接续他的工作。他的工具允许定时传输工作任务,但如果我们想创建自己的仪表板和事件日志呢?
也许我想为某个业务群体创建一个特定的仪表板或一个面向客户的仪表板,但不提供用户对Bird UI的完全访问权限。这个脚本只是触及了使用Python、Plotly Dash和我们的API所能实现的可能性的表面。在构建处理高吞吐量API数据的仪表板时,要注意像DNS这样的基础设施组件可能会成为瓶颈——我们曾经遇到过AWS DNS扩展挑战,影响了我们的数据处理能力。对于视觉工作流爱好者,你还可以探索将Flow Builder与Google Cloud Functions和Vision API集成来为数据处理管道添加AI驱动的自动化。
当我开始在线搜索时,我想找到阻力最小的路径。我本可以在HTML和Python中自己创建所有仪表板和UI,然而,经过一些谷歌搜索,我遇到了Plotly的Dash,它与Python轻松集成。我选择Dash的原因有两个:1) 它是开源的,2) 在阅读文档后发现它很容易定制,以实现我想要做的事情。Dash是一个开源库,适合使用定制用户界面构建和部署数据应用。这使得创建UI非常简单。问题变成了,我想把这个应用做得多复杂?我花的时间越多,我想添加的功能就越多。
对于初始项目,我想确保我有一个可定制指标和可选择时间框架的仪表板。最初,我开始使用一个只能从下拉菜单中选择一个指标的仪表板。然后,随着同事的反馈,我稍微改进了一下仪表板,增加了多选择和轴标题。我还决定为事件日志添加一个额外的标签。最后,我对现有的成果感到满意,作为任何希望构建自己仪表板的人的良好起点。对于希望将实时Webhook数据输入到其仪表板的开发人员,请查看我们的关于使用Azure Functions构建Webhook消费者的指南。当然,我把这个项目放在Github上供你克隆或分支。
Bird Metrics API + 使用Python进行仪表板创建
大约一年前,Bird的客户成功总监Tom Mairs开发了一个使用Bird APIs的邮件工具。在这篇文章中,我接续他的工作。他的工具允许定时传输工作任务,但如果我们想创建自己的仪表板和事件日志呢?
也许我想为某个业务群体创建一个特定的仪表板或一个面向客户的仪表板,但不提供用户对Bird UI的完全访问权限。这个脚本只是触及了使用Python、Plotly Dash和我们的API所能实现的可能性的表面。在构建处理高吞吐量API数据的仪表板时,要注意像DNS这样的基础设施组件可能会成为瓶颈——我们曾经遇到过AWS DNS扩展挑战,影响了我们的数据处理能力。对于视觉工作流爱好者,你还可以探索将Flow Builder与Google Cloud Functions和Vision API集成来为数据处理管道添加AI驱动的自动化。
当我开始在线搜索时,我想找到阻力最小的路径。我本可以在HTML和Python中自己创建所有仪表板和UI,然而,经过一些谷歌搜索,我遇到了Plotly的Dash,它与Python轻松集成。我选择Dash的原因有两个:1) 它是开源的,2) 在阅读文档后发现它很容易定制,以实现我想要做的事情。Dash是一个开源库,适合使用定制用户界面构建和部署数据应用。这使得创建UI非常简单。问题变成了,我想把这个应用做得多复杂?我花的时间越多,我想添加的功能就越多。
对于初始项目,我想确保我有一个可定制指标和可选择时间框架的仪表板。最初,我开始使用一个只能从下拉菜单中选择一个指标的仪表板。然后,随着同事的反馈,我稍微改进了一下仪表板,增加了多选择和轴标题。我还决定为事件日志添加一个额外的标签。最后,我对现有的成果感到满意,作为任何希望构建自己仪表板的人的良好起点。对于希望将实时Webhook数据输入到其仪表板的开发人员,请查看我们的关于使用Azure Functions构建Webhook消费者的指南。当然,我把这个项目放在Github上供你克隆或分支。
Bird Metrics API + 使用Python进行仪表板创建
大约一年前,Bird的客户成功总监Tom Mairs开发了一个使用Bird APIs的邮件工具。在这篇文章中,我接续他的工作。他的工具允许定时传输工作任务,但如果我们想创建自己的仪表板和事件日志呢?
也许我想为某个业务群体创建一个特定的仪表板或一个面向客户的仪表板,但不提供用户对Bird UI的完全访问权限。这个脚本只是触及了使用Python、Plotly Dash和我们的API所能实现的可能性的表面。在构建处理高吞吐量API数据的仪表板时,要注意像DNS这样的基础设施组件可能会成为瓶颈——我们曾经遇到过AWS DNS扩展挑战,影响了我们的数据处理能力。对于视觉工作流爱好者,你还可以探索将Flow Builder与Google Cloud Functions和Vision API集成来为数据处理管道添加AI驱动的自动化。
当我开始在线搜索时,我想找到阻力最小的路径。我本可以在HTML和Python中自己创建所有仪表板和UI,然而,经过一些谷歌搜索,我遇到了Plotly的Dash,它与Python轻松集成。我选择Dash的原因有两个:1) 它是开源的,2) 在阅读文档后发现它很容易定制,以实现我想要做的事情。Dash是一个开源库,适合使用定制用户界面构建和部署数据应用。这使得创建UI非常简单。问题变成了,我想把这个应用做得多复杂?我花的时间越多,我想添加的功能就越多。
对于初始项目,我想确保我有一个可定制指标和可选择时间框架的仪表板。最初,我开始使用一个只能从下拉菜单中选择一个指标的仪表板。然后,随着同事的反馈,我稍微改进了一下仪表板,增加了多选择和轴标题。我还决定为事件日志添加一个额外的标签。最后,我对现有的成果感到满意,作为任何希望构建自己仪表板的人的良好起点。对于希望将实时Webhook数据输入到其仪表板的开发人员,请查看我们的关于使用Azure Functions构建Webhook消费者的指南。当然,我把这个项目放在Github上供你克隆或分支。
入门
要访问这个app,您需要确保运行的是python 3.10或以上版本,并安装以下库:
Python Library | 目的 |
|---|---|
requests | API与Bird服务的通信 |
dash | UI和仪表盘渲染 |
pandas | 数据处理和表格生成 |
然后,将您的API密钥输入App.py并运行该app。它将在http://localhost:8050运行。有关将其部署到面向公众的服务器(例如AWS)的更多信息,请参阅以下资源:
要访问这个app,您需要确保运行的是python 3.10或以上版本,并安装以下库:
Python Library | 目的 |
|---|---|
requests | API与Bird服务的通信 |
dash | UI和仪表盘渲染 |
pandas | 数据处理和表格生成 |
然后,将您的API密钥输入App.py并运行该app。它将在http://localhost:8050运行。有关将其部署到面向公众的服务器(例如AWS)的更多信息,请参阅以下资源:
要访问这个app,您需要确保运行的是python 3.10或以上版本,并安装以下库:
Python Library | 目的 |
|---|---|
requests | API与Bird服务的通信 |
dash | UI和仪表盘渲染 |
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"), # Multi-select dropdown 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)", ), # Date selector (max date allowed is set to today's date) 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, ), ), # Graph object dcc.Graph(id="Emails", figure=fig)
注意dash如何简单地创建带有多选和可搜索下拉框的仪表板UI。要禁用多选或搜索,可以轻松修改创建下拉框的参数。我发现这个项目中最复杂的部分是从输入中构建实际数据框,以及使HTML+CSS在UI中正确工作。
Time Series Metrics API允许基于日期/时间范围提取33个单独指标。您可以通过域、活动、IP池、发送域、子账户进行更深入的过滤,并指定时间序列数据的精度。这些额外的过滤器以及可交付性分析可能是将来这个项目的改进(需要为没有访问可交付性分析的客户端实施错误捕获)。
利用和调用Metrics API,我构建了一个仪表板,包含用户选择的参数和指定的时间范围。初始化仪表板然后更新。
仪表板视图 (Time Series Metrics API)
# Build the API call utilizing the parameters provided 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(",") # Build out a new dashboard utilizing the new metrics and dates from the updated API call 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
以下是选择多个指标和扩展时间范围的示例。

注意: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"), # Multi-select dropdown 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)", ), # Date selector (max date allowed is set to today's date) 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, ), ), # Graph object dcc.Graph(id="Emails", figure=fig)
注意dash如何简单地创建带有多选和可搜索下拉框的仪表板UI。要禁用多选或搜索,可以轻松修改创建下拉框的参数。我发现这个项目中最复杂的部分是从输入中构建实际数据框,以及使HTML+CSS在UI中正确工作。
Time Series Metrics API允许基于日期/时间范围提取33个单独指标。您可以通过域、活动、IP池、发送域、子账户进行更深入的过滤,并指定时间序列数据的精度。这些额外的过滤器以及可交付性分析可能是将来这个项目的改进(需要为没有访问可交付性分析的客户端实施错误捕获)。
利用和调用Metrics API,我构建了一个仪表板,包含用户选择的参数和指定的时间范围。初始化仪表板然后更新。
仪表板视图 (Time Series Metrics API)
# Build the API call utilizing the parameters provided 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(",") # Build out a new dashboard utilizing the new metrics and dates from the updated API call 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
以下是选择多个指标和扩展时间范围的示例。

注意: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"), # Multi-select dropdown 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)", ), # Date selector (max date allowed is set to today's date) 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, ), ), # Graph object dcc.Graph(id="Emails", figure=fig)
注意dash如何简单地创建带有多选和可搜索下拉框的仪表板UI。要禁用多选或搜索,可以轻松修改创建下拉框的参数。我发现这个项目中最复杂的部分是从输入中构建实际数据框,以及使HTML+CSS在UI中正确工作。
Time Series Metrics API允许基于日期/时间范围提取33个单独指标。您可以通过域、活动、IP池、发送域、子账户进行更深入的过滤,并指定时间序列数据的精度。这些额外的过滤器以及可交付性分析可能是将来这个项目的改进(需要为没有访问可交付性分析的客户端实施错误捕获)。
利用和调用Metrics API,我构建了一个仪表板,包含用户选择的参数和指定的时间范围。初始化仪表板然后更新。
仪表板视图 (Time Series Metrics API)
# Build the API call utilizing the parameters provided 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(",") # Build out a new dashboard utilizing the new metrics and dates from the updated API call 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
以下是选择多个指标和扩展时间范围的示例。

注意:dash图表自动内置许多项目(悬停、缩放、自动缩放)。
创建Event Details 页面
活动详情页面较为困难,因为我不知道如何以易于阅读的方式呈现所有的事件指标。我考虑过在此页面中增加过滤参数,但我决定这样做会导致该项目需要花费大量时间,因为表格可能需要动态调整(同时还要添加参数、回调等)。我最终决定展示所有事件,并将时间戳放在第一位(因为不这样放的话,图表不容易阅读)。最初,我发现仅用原始HTML时,表格非常难以阅读。没有边框,标题和行之间没有颜色差异。为了让表格更容易阅读,我在Dash中使用了CSS。
事件详情视图 (Events API)
事件详情的想法几乎与仪表板相同,不过这次我调用Events API并引入所有事件。注意,事件详情只显示最近的10个事件(利用max_rows参数和API过滤)。这可以增加,但我决定只显示最近的10个事件,因为显示更多事件会延长API调用时间。一个重大改进可以是能够分页并在UI中包含下一页/上一页的功能。
为了构建事件选项卡(页面),首先,我调用Events API并将JSON响应解析为数据框。然后,我对数据框进行排序和重排序,使时间戳成为第一列。最后,我通过遍历数据框构建HTML表格。
# Build out and call the events 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 = f"{BASE_URL}/events/message" response_API = requests.get(api_url, headers={"Authorization": API_KEY}, params=params) response_info = response_API.json() new_df = pd.json_normalize(response_info, record_path=["results"]) max_rows = 10 # Max number of results to show in the events table # Sort columns and place timestamp as the first column in the table 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]] # Show the new HTML with the events table (note: this table also references 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)) ]) ]) ])
在UI中看起来是这样的。

活动详情页面较为困难,因为我不知道如何以易于阅读的方式呈现所有的事件指标。我考虑过在此页面中增加过滤参数,但我决定这样做会导致该项目需要花费大量时间,因为表格可能需要动态调整(同时还要添加参数、回调等)。我最终决定展示所有事件,并将时间戳放在第一位(因为不这样放的话,图表不容易阅读)。最初,我发现仅用原始HTML时,表格非常难以阅读。没有边框,标题和行之间没有颜色差异。为了让表格更容易阅读,我在Dash中使用了CSS。
事件详情视图 (Events API)
事件详情的想法几乎与仪表板相同,不过这次我调用Events API并引入所有事件。注意,事件详情只显示最近的10个事件(利用max_rows参数和API过滤)。这可以增加,但我决定只显示最近的10个事件,因为显示更多事件会延长API调用时间。一个重大改进可以是能够分页并在UI中包含下一页/上一页的功能。
为了构建事件选项卡(页面),首先,我调用Events API并将JSON响应解析为数据框。然后,我对数据框进行排序和重排序,使时间戳成为第一列。最后,我通过遍历数据框构建HTML表格。
# Build out and call the events 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 = f"{BASE_URL}/events/message" response_API = requests.get(api_url, headers={"Authorization": API_KEY}, params=params) response_info = response_API.json() new_df = pd.json_normalize(response_info, record_path=["results"]) max_rows = 10 # Max number of results to show in the events table # Sort columns and place timestamp as the first column in the table 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]] # Show the new HTML with the events table (note: this table also references 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)) ]) ]) ])
在UI中看起来是这样的。

活动详情页面较为困难,因为我不知道如何以易于阅读的方式呈现所有的事件指标。我考虑过在此页面中增加过滤参数,但我决定这样做会导致该项目需要花费大量时间,因为表格可能需要动态调整(同时还要添加参数、回调等)。我最终决定展示所有事件,并将时间戳放在第一位(因为不这样放的话,图表不容易阅读)。最初,我发现仅用原始HTML时,表格非常难以阅读。没有边框,标题和行之间没有颜色差异。为了让表格更容易阅读,我在Dash中使用了CSS。
事件详情视图 (Events API)
事件详情的想法几乎与仪表板相同,不过这次我调用Events API并引入所有事件。注意,事件详情只显示最近的10个事件(利用max_rows参数和API过滤)。这可以增加,但我决定只显示最近的10个事件,因为显示更多事件会延长API调用时间。一个重大改进可以是能够分页并在UI中包含下一页/上一页的功能。
为了构建事件选项卡(页面),首先,我调用Events API并将JSON响应解析为数据框。然后,我对数据框进行排序和重排序,使时间戳成为第一列。最后,我通过遍历数据框构建HTML表格。
# Build out and call the events 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 = f"{BASE_URL}/events/message" response_API = requests.get(api_url, headers={"Authorization": API_KEY}, params=params) response_info = response_API.json() new_df = pd.json_normalize(response_info, record_path=["results"]) max_rows = 10 # Max number of results to show in the events table # Sort columns and place timestamp as the first column in the table 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]] # Show the new HTML with the events table (note: this table also references 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)) ]) ]) ])
在UI中看起来是这样的。

下一步
对于想要创建自己仪表盘或事件日志的人来说,这是一个不错的开始。由于这里的可定制性,天空是无限的。
如上所述,可以进行的一些未来改进包括:
添加交付分析功能到仪表板
为仪表板添加更多过滤器
可能的缓存选择,以便不必每次都调用API来显示页面
UI 改进
为事件详情页面添加过滤和分页功能
我很感兴趣听取任何反馈或关于扩展此项目的建议。
~ Zach Samuels, Bird高级解决方案工程师
对于想要创建自己仪表盘或事件日志的人来说,这是一个不错的开始。由于这里的可定制性,天空是无限的。
如上所述,可以进行的一些未来改进包括:
添加交付分析功能到仪表板
为仪表板添加更多过滤器
可能的缓存选择,以便不必每次都调用API来显示页面
UI 改进
为事件详情页面添加过滤和分页功能
我很感兴趣听取任何反馈或关于扩展此项目的建议。
~ Zach Samuels, Bird高级解决方案工程师
对于想要创建自己仪表盘或事件日志的人来说,这是一个不错的开始。由于这里的可定制性,天空是无限的。
如上所述,可以进行的一些未来改进包括:
添加交付分析功能到仪表板
为仪表板添加更多过滤器
可能的缓存选择,以便不必每次都调用API来显示页面
UI 改进
为事件详情页面添加过滤和分页功能
我很感兴趣听取任何反馈或关于扩展此项目的建议。
~ Zach Samuels, Bird高级解决方案工程师



