Как получить доступ к ответу сервера, когда библиотека запросов Python встречает ограничение на повторную попытку

Я использую библиотеку запросов Python для реализации логики повтора. Вот простой script, который я сделал, чтобы воспроизвести проблему, которая у меня есть. В случае, когда у нас заканчиваются попытки, я хотел бы иметь возможность регистрировать хотя бы один из ответов сервера, чтобы помочь отлаживать. Однако мне не ясно, как получить доступ к этой информации. Конечно, я мог бы повторить попытку каким-то другим способом для достижения моей цели, но казалось, что это не так уж и много, и я был бы удивлен, узнав, что запросы не поддерживают мой прецедент.

Я просмотрел request.exceptions.RetryError, request.packages.urllib3.exceptions.MaxRetryError, который он обертывает, и request.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, запуск в предел повтора приводит к возврату ответа вместо генерируемого исключения. В приведенном ниже коде показано, что я вызываю HTTPError (содержащий Response) с помощью метода raise_for_status на 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 ]=-

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