简体   繁体   English

从 python 重试异常判断状态码

[英]Determine status code from python Retry exception

import requests
from requests.adapters import HTTPAdapter
from urllib3 import Retry

DEFAULT_RETRIES = 5
DEFAULT_BACKOFF = 0.3


def session_with_retries(max_retries: int = DEFAULT_RETRIES,
                         backoff_factor: float = DEFAULT_BACKOFF,
                         proxies: dict = None) -> requests.Session:
    new_session = requests.Session()
    retries = Retry(total=max_retries,
                    connect=max_retries,
                    read=max_retries,
                    status=max_retries,
                    allowed_methods=frozenset(['HEAD', 'GET', 'POST']),
                    status_forcelist=frozenset([500, 502, 503, 504]),
                    backoff_factor=backoff_factor,
                    )
    retry_adapter = HTTPAdapter(max_retries=retries)
    new_session.mount('http://', retry_adapter)
    new_session.mount('https://', retry_adapter)

    if proxies is not None:
        new_session.proxies.update(proxies)

    return new_session

This code is for retry logic with python requests.此代码用于 python 请求的重试逻辑。 And is working fine too.并且工作正常。 As expected it will throw exception on 503 status code after max_retries .正如预期的那样,它会在max_retries之后抛出503状态代码的异常。 So collectively it will throw exception for [500, 502, 503, 504] .因此,它将共同为[500, 502, 503, 504]抛出异常。

How I can get the status code on which the exception was thrown from this method.如何从该方法中获取引发异常的状态代码 As exception messages i could see something作为异常消息,我可以看到一些东西

HTTPSConnectionPool(host='some-host', port=443): Max retries exceeded with url: /services/data/v52.0/connect/communities?pageSize=100 (Caused by ResponseError('too many 503 error responses',))

I traced back the exceptions urllib3.exceptions.MaxRetryError , requests.exceptions.RetryError but could not find about its status code for exception.我追溯了异常urllib3.exceptions.MaxRetryErrorrequests.exceptions.RetryError但找不到其异常状态代码。

Strictly NO for other libraries like tenacity坚韧等其他图书馆严格禁止

You can handle this by turning off raising an error on 5xx responses, getting the response, and then either raising the last exception or examining the retry history.您可以通过关闭在 5xx 响应上引发错误、获取响应,然后引发最后一个异常或检查重试历史记录来处理此问题。

The connect , read , and status are over-ridden when a value for total is passed. connectreadstatus在传递total的值时被覆盖。

import requests
from requests.exceptions import HTTPError
from requests.adapters import HTTPAdapter
from urllib3 import Retry

DEFAULT_RETRIES = 5
DEFAULT_BACKOFF = 0.3

def session_with_retries(max_retries: int = DEFAULT_RETRIES,
                         backoff_factor: float = DEFAULT_BACKOFF,
                         proxies: dict = None
                         ) -> requests.Session:
    """Creates a new Session with `max_retries` retry attempts at 5xx status
    codes.
    """
    new_session = requests.Session()
    retries = Retry(
        total=max_retries,
        allowed_methods=frozenset(['HEAD', 'GET', 'POST']),
        status_forcelist=frozenset([500, 502, 503, 504]),
        backoff_factor=backoff_factor,
        # ensure a response is returned:
        raise_on_status=False,
    )

    retry_adapter = HTTPAdapter(max_retries=retries)
    new_session.mount('http://', retry_adapter)
    new_session.mount('https://', retry_adapter)

    if proxies is not None:
        new_session.proxies.update(proxies)

    return new_session

Now when you send a request, the response will be returned without raising a MaxRetryError .现在,当您发送请求时,将在不引发MaxRetryError的情况下返回响应。 To get the last response code, you simply call raise_for_status .要获得最后的响应代码,您只需调用raise_for_status

sess = session_with_retries()
res = sess.get('https://httpbin.org/status/500')

try:
    res.raise_for_status()
except HTTPError:
    print(f'The request failed with code: {res.status_code}')

# prints:
# The request failed with code: 500

If you want to see the complete retry status code history, you can use:如果想查看完整的重试状态码历史记录,可以使用:

sess = session_with_retries()
res = sess.get('https://httpbin.org/status/500')

try:
    res.raise_for_status()
except HTTPError:
    print('The request retries failed with codes:')
    print([h.status for h in res.raw.retries.history])

# prints:
# The request retries failed with codes:
# [500, 500, 500]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM