
这个脚本只是触及了利用 Python、Plotly Dash 和我们的 API 所能实现的可能性的表面。
几乎一年前,Bird的客户成功总监Tom Mairs写了一个邮件工具,利用了Bird APIs。在这篇文章中,我接着他的话题。他的工具允许定时传输工作,但如果我们想创建自己的仪表盘和事件日志呢?
也许我想为业务组创建一个特定的仪表盘或面向客户的仪表盘,但不提供用户对Bird UI的完整访问权限。这个脚本只是触及了利用Python、Plotly 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
创建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)) ]) ]) ])
在用户界面中看起来像这样。

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