SOUNDCLOUD API:使用 soundcloud-python 获取错误 429 的响应正文

SOUNDCLOUD API: get body of the response for error 429 with soundcloud-python

我在 Ubuntu Server 16.04.1(随 pip install soundcloud 一起安装)上使用 soundcloud-python https://github.com/soundcloud/soundcloud-python for Soundcloud API。

Soundcloud API 速率限制官方页面 https://developers.soundcloud.com/docs/api/rate-limits#play-requests 表示,如果应用程序超过 API 速率限制,429 Client Error 响应的正文将是JSON 对象,包含一些附加信息。

我对获取 reset_time 字段感兴趣,以便在阻止结束时通知用户。

问题是,例如,当超出点赞速率限制时,执行 response = client.put('/me/favorites/%d' % song_id) 应用程序崩溃并且 responsenull

如何获取 JSON 响应正文?

你为什么不阅读包的源代码并自己找出来呢?

让我们看看...你没有解释你得到了那个 client 对象但是 browsing the source code we can see there's a "client.py" module that defines a Client class. This class does'nt not define a put method explicitely but it defines the __getattr__ hook :

def __getattr__(self, name, **kwargs):
    """Translate an HTTP verb into a request method."""
    if name not in ('get', 'post', 'put', 'head', 'delete'):
        raise AttributeError
    return partial(self._request, name, **kwargs)

好的,所以 Client.put(...) returns 一个 partial object 包装 Client._request,这是将 Client.put(**kwargs) 定义为 return self._request("put", **kwargs) 的一种非常无用的复杂方法].

现在让我们看看 Client._request:它基本上进行了一些健全性检查,更新 **kwargs 和 returns wrapped_resource(make_request(method, url, kwargs)).

查看模块开头的导入,我们可以看到 make_request 来自 "request.py",wrapped_resource 来自 "resources.py"。

你提到在超过速率限制时进行 api 调用 "crashes the application" - 我假设你的意思是 "raises an exception" (顺便说一句 post 处理此类问题时的异常和回溯)-因此假设这是在较低级别处理的,让我们从 request.make_request. A lot of data formatting / massaging obviously and finally the interesting part: a call to response.raise_for_status(). This is a hint that we are actually delegating to the famous python-requests package, which is actually confirmed a few lines above and in the requirements file

开始

如果我们阅读 python-requests fine manual,我们会发现 raise_for_status 做了什么 - 它为客户端 (4XX) 和服务器 (5XX) 状态代码引发了 requests.exceptions.HTTPError

好的,现在我们知道我们遇到了什么异常。 请注意,您的异常和回溯中已经包含了所有这些信息,如果您post对其进行了编辑,这本可以为我们省去很多麻烦。

但不管怎么说...看起来我们不会得到响应内容,是吗?好吧,等等,我们还没有完成 - python-requests 是一个设计得很好的包,所以我们有可能 still 挽救我们的响应。事实上,如果我们查看 requests.exceptions source code,我们会发现 HttpErrorRequestException 的子类,而 RequestException 是 "Initialize(d)" 且“requestresponse 个对象。”

万岁,我们确实有我们的回应 - 在例外情况下。所以我们所要做的就是捕获异常并检查它的 response 属性——它应该包含 "additional informations".

现在请理解,这花了我半个多小时,但整理了大约 7 分钟没有回溯 - 有了回溯,它会被归结为仅仅 2 分钟,这是转到 requests.exceptions 源代码并确保它保留请求和响应的时间。好吧,我在作弊,我习惯阅读源代码并且我经常使用 python-requests,但仍然:你可以在不到一个小时的时间内自己解决这个问题,特别是 python的交互式 shell 让您实时探索和测试活动对象。