Python请求库遇到重试限制时如何访问服务器响应

Posted

技术标签:

【中文标题】Python请求库遇到重试限制时如何访问服务器响应【英文标题】:How to access server response when Python requests library encounters the retry limit 【发布时间】:2017-09-14 19:45:49 【问题描述】:

我正在使用 Python 请求库来实现重试逻辑。这是我制作的一个简单脚本,用于重现我遇到的问题。在我们用完重试的情况下,我希望能够记录至少一个来自服务器的响应以帮助调试。但是,我不清楚如何访问该信息。当然,我可以通过其他方式实现重试以实现我的目标,但这似乎并不是什么极端情况,我会惊讶地发现请求不支持我的用例。

我查看了 requests.exceptions.RetryError,它包装的 requests.packages.urllib3.exceptions.MaxRetryError,以及包装所有无用的 requests.packages.urllib3.exceptions.ResponseError。

我错过了什么吗?

#!/usr/bin/env python

import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
from requests.exceptions import RetryError


def main():
    retry_policy = Retry(
        total=3,
        status_forcelist=[418])

    session = requests.Session()
    session.mount('http://', HTTPAdapter(max_retries=retry_policy))

    try:
        session.get('http://httpbin.org/status/418')
    except RetryError as retry_error:
        print retry_error
        print retry_error.response is None


if __name__ == '__main__':
    main()

$ python test.py

HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /status/418 (Caused by ResponseError('too many 418 error responses',))

True

【问题讨论】:

【参考方案1】:

查看 urllib3 源代码,我发现 Retry 对象采用名为 raise_on_status 的命名参数。 True 是默认值。当设置为False 时,运行到重试限制会导致返回响应而不是引发异常。下面的代码显示我使用Response 上的raise_for_status 方法导致HTTPError(包含Response)被抛出,但也可以直接使用Response

#!/usr/bin/env python

import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
from requests.exceptions import HTTPError


def main():
    retry_policy = Retry(
        total=3,
        status_forcelist=[418],
        raise_on_status=False)

    session = requests.Session()
    session.mount('http://', HTTPAdapter(max_retries=retry_policy))

    try:
        response = session.get('http://httpbin.org/status/418')
        response.raise_for_status()
    except HTTPError as e:
        print e.response.status_code
        print e.response.content


if __name__ == '__main__':
    main()

$ python test.py

418

-=[ teapot ]=-

   _...._
 .'  _ _ `.
| ."` ^ `". _,
\_;`"---"`|//
  |       ;/
  \_     _/
    `"""`

【讨论】:

非常清晰和乐于助人,很高兴看到 httpbin 也为我们准备了什么 ;)

以上是关于Python请求库遇到重试限制时如何访问服务器响应的主要内容,如果未能解决你的问题,请参考以下文章

tenacity库 重试代码

trigger.io 如何处理文件上传请求中的带宽限制、超时和重试?

ASP.NET Core中如何限制响应发送速率(不是调用频率)

如何保证微服务接口的幂等性

如何保证接口的幂等性。。。。。

40.少有人知的 Python“重试机制”