跳转到主要内容

一个小型REST客户端,为您的设备充电

项目描述

PowerNap

Deployed to PyPI GitHub Repository Continuous Integration Coverage MIT License Contributor Covenant

一个小型REST客户端,为您的设备充电

PowerNap是一个简单的JSON REST API客户端,是httpx的小型包装器,可以让您的代码读起来更好。

安装

$ pip install powernap

用法

# You will need an httpx Client. Let's do a GitHub client!
httpx_client = httpx.Client(
    base_url="https://api.github.com/v3",
    headers={"Authorization": f"token {token}"}
)

# Instantiate the PowerNap client
github_client = powernap.PowerNap(httpx_client=httpx_client)

# PowerNap will help you build complex URLs in a pythonic-looking way:
repo = github_client.repos("ewjoachim/powernap").get()

# And access the json responses like objects
count_stars = repo.stargazers_count

# You can also easily send POST requests.
github_client.repos("ewjoachim/powernap").issues(42).comments.post(
    body=f"Wow look! This repo has {count_stars} stars!"
)

构建复杂URL

您可以使用client(something)client.something,并进行链式调用。在形式client(something)中,您可以传递多个参数,它们将被连接在一起

# The next calls are all identical and target:
#    {base_url}/repos/ewjoachim/powernap/stargazers
github_client.repos("ewjoachim/powernap").stargazers.get()
github_client.repos("ewjoachim").powernap("stargazers").get()
github_client.repos("ewjoachim", "powernap", "stargazers").get()
github_client.repos("ewjoachim", "powernap")("stargazers").get()
github_client("repos/ewjoachim/powernap/stargazers").get()

# The recommended way is to use client.something for static parts of the url and
# client(something) with a variable for dynamic parts.

# You can also target the base url directly
# {base_url}
github_client().get()

像对象一样访问json响应

在json响应中,所有对象(包括嵌套的)都配置为可以使用object.key语法获取键,除了经典的object["key"]

# GET /nested_json -> {"a": {"b":{"c": "d"}}}
response = some_api_client.nested_json.get()

assert response == {"a": {"b":{"c": "d"}}}
assert response["a"]["b"]["c"] == "d"
# But also the magic form:
assert response.a.b.c == "d"

参数

.get/delete()调用中的参数用作调用中的查询参数。

.post/put/patch()调用中的参数组合在一起,并作为调用中的JSON有效负载传递。

响应类型

如果响应包含Content-Type: application/json,则您将获得上面描述的“魔法”json响应。否则,如果内容类型是text/*,您将获得一个string,否则您将获得bytes

异常

如果您想避免 httpx 异常到达您的代码,以保持良好的抽象层,那么您可能想继承 Powernap 并实现 handle_exception(self, exc)。您将收到一个 httpx.HttpError,您需要根据情况抛出相应的异常。在这种情况下不抛出异常被视为错误。

from typing import NoReturn

class ApiError(MyProjectError):
    pass

class ForbiddenError(ApiError):
    pass

class ApiClient(PowerNap):
    def handle_exception(self, exc: httpx.HttpError) -> NoReturn:
        if exc.response.status_code == 403:
            raise ForbiddenError
        raise ApiError

更多对输入和输出的控制

这个魔法很棒,但有时您可能想要更多的控制。如果您想发送额外的头信息或非 JSON-dict 负载,或者如果您想读取响应头信息,这也是可能的。

不要调用 .get(),而是使用 .get.i().get.o().get.io()(这适用于任何方法:get/post/put/patch/delete

  • 如果您使用 .get.i(...)(或 .get.io(...)),您将控制输入。方法关键字参数将原样传递给底层的 httpx.Client().get(...)
  • 如果您使用 .get.o(...)(或 .get.io(...)),您将得到原始输出。函数将返回一个 httpx.Response 对象。(注意,在这种情况下,我们仍然调用了 .raise_for_status()

如果您经常使用 get.io(),那么 PowerNap 可能不是您需要的项目。直接使用 httpx.Client,构建一些帮助您构建 URL 的东西(您可以 偷取 复制相关的代码,别忘了复制许可证)

名称

在寻找这个库的名称时,我查阅了“小休息”的所有同义词。令人惊讶的是,有许多其他项目走了相同的路线。以下是一些例子:

  • nap 看起来很棒!虽然这个库与这个库无关,但目标相同。看起来没有维护,但我不确定这样的库是否需要大量的维护。
  • catnap
  • respite
  • snooze 没有被占用,但 snooze-server 已经被占用,我不想造成混淆。

有趣的是,许多这些项目都有与这个项目相同的目标,但它们的视觉效果与我想达到的并不完全一致。

致谢

这个库深受 githubpy 启发,后者采用 Apache 许可证。

由以下支持