新的 Python API

我很高兴与大家分享 fluent-discourse,这是一个用于调用 Discourse API 的新 Python 包。

目前已有 几个包 可以通过 Python 调用 Discourse API。那么,为什么还要再开发一个呢?

现有的其他 Discourse 包通常采用类似的方法——为 API 的每个端点创建一个独立的 Python 函数。

这种方法有几个缺点:

  1. 很难实现与 API 的完整功能对等。Discourse 的 API 文档相对不足,通常需要逆向工程来理解端点。此外,还有许多插件暴露了不属于核心功能的 API 端点。这让库用户面临艰难的选择:要么提交拉取请求,将所需端点添加到库中;要么为额外的端点构建自定义解决方案。
  2. 你需要学习另一套 API。除了学习 Discourse API 的方法和端点外,你还得弄清楚在 Python 中对应的函数调用是什么。
  3. 需要测试的代码量更大,因此很难实现 100% 的测试覆盖率。这使得人们对所生成软件的质量缺乏信心。

与此方法相反,我采用了一种“流式”(fluent)接口,通过方法链式调用来构建请求。举个例子:
要获取 ID 为 5 的类别 ‘foo’ 中的最新主题,需使用以下端点:
GET /c/foo/5.json
使用此库发出该请求只需调用:
client.c.foo[5].json.get()

你可以看到,API 端点与 Python 中的对应调用之间存在语义对等。

这种方法的优势在于:

  1. 开箱即用即可实现与 Discourse API 的完整功能对等,包括未文档化的端点、插件提供的端点以及尚未定义的端点(面向未来)。
  2. 你只需学习 Discourse API。任何 API 调用都可以如此轻松地进行转换,因此无需搜索匹配的函数。
  3. 整个库仅约 150 行代码。这使得实现 100% 的测试覆盖率变得轻而易举。

该库拥有 100% 的测试覆盖率,并包含少量针对真实 Discourse 服务器的集成测试。

如果你对此感兴趣,希望你能试用这个包!

21 个赞

这是一个有趣的思路……

在 PHP 中实现类似功能,我们需要依赖魔术方法,从而失去 IDE 自动补全等优势。但这可能是一个值得付出的代价。

与直接将 URL 作为参数传递(client.get(url))相比,这种方法的优点是什么?

这是个很好的观点,IDE 自动补全在这里确实帮不上什么忙。如果这一点对你很重要,或许可以考虑使用其他库。

由于每个方法链都会返回一个新的客户端对象,我能想到的一个优势是可以将特定的方法链存储在变量中,并在后续调用中重复使用。例如,假设你有一个包含新帖子数据的列表,想要创建这些帖子。

post_data = [
  {
    "raw": "Hello World!",
    "topic_id": 123,
    ...
  },
  {
    "raw": "Tester",
    "topic_id": 501,
    ...
  },
  ...
]

你可以存储“新建帖子”的方法链,并重复使用它来创建列表中的每个帖子。

new_post_endpoint = client.posts.json

for post in post_data:
  new_post_endpoint.post(data=post) 

你可能还能想象出其他可以利用这种重用客户端能力的场景。除此之外,与直接像你所建议的那样传递 URL 相比,并没有太大的优势。我建议你阅读一下 Universal Client 库的相关资料,其中包含了一些关于采用此类方法理由的说明。

另外,关于 PHP 中这种方法的特定实现,可以查看 SendGrid 的 PHP API。我在阅读了 SendGrid 的 Python API 后,受到了启发而构建了此库。

3 个赞