sourcecode

requests.requests에 max_retries를 설정할 수 있습니까?

copyscript 2022. 11. 17. 21:23
반응형

requests.requests에 max_retries를 설정할 수 있습니까?

Python requests module은 단순하고 우아하지만 한 가지 문제가 있습니다.요청을 받을 수 있습니다.예외입니다.ConnectionError와 다음과 같은 메시지가 표시됩니다.

Max retries exceeded with url: ...

이는 요청이 데이터에 대한 액세스를 여러 번 시도할 수 있음을 의미합니다.그러나 문서 어디에도 이 가능성에 대한 언급은 없습니다.소스 코드를 살펴본 결과 기본값(아마도 0)을 변경할 수 있는 위치를 찾을 수 없었습니다.

그래서 어떻게 해서라도 요청의 최대 재시도 횟수를 설정할 수 있을까요?

이렇게 하면 max_retries가 변경될 뿐만 아니라 모든 http:// 주소에 대한 요구를 재시도하기 전에 일정 시간 동안 sleep 상태로 만드는 백오프 전략이 활성화됩니다(총 5회).

import requests

from requests.adapters import HTTPAdapter, Retry

s = requests.Session()

retries = Retry(total=5,
                backoff_factor=0.1,
                status_forcelist=[ 500, 502, 503, 504 ])

s.mount('http://', HTTPAdapter(max_retries=retries))

s.get('http://httpstat.us/500')

매뉴얼에 따르면 backoff_factor가 0.1인 경우 sleep()은 재시도 사이에 [0.05, 0.1, 0.2, 0.4, ...] 동안 sleep합니다.또한 반환된 상태 코드가 500, 502, 503 또는 504인 경우에도 강제로 재시도합니다.

양양양 の to options の to to to to 의 기타 다양한 :Retry하다

  • total : 허용되는 총 재시도 횟수.
  • connect : 재시도할 연결 관련 오류 .
  • read – 읽기 오류 시 재시도 횟수.
  • redirect : 실행할 리다이렉트 수
  • method_whitelist: 재시도해야 하는 상위 캐시의 HTTP 메서드 동사 세트.
  • status_forcelist: 강제로 재시도해야 하는 HTTP 상태 코드 세트.
  • backoff_factor : 시행 사이에 적용되는 백오프 요인.
  • raise_on_redirect : 리다이렉트 수가 모두 사용되었을 경우, 리다이렉트 수를 올리지 않을지 여부MaxRetryError또는 3xx 범위의 응답 코드를 사용하여 응답을 반환합니다.
  • raise_on_status : raise_on_redirect와 같은 의미: 상태가 status_forcelist 범위에 속하고 재시도 횟수가 모두 소진된 경우 예외를 발생시킬지 응답을 반환할지를 지정합니다.

주의: raise_on_status는 비교적 새로운 것으로 아직 urlib3 또는 요청 릴리스에 포함되지 않았습니다. raise_on_status 키워드 인수는 python 버전 3.6에서는 최대 표준 라이브러리가 된 것으로 보입니다.

특정 HTTP 상태 코드에서 요청을 재시도하려면 status_forcelist를 사용합니다.예를 들어 status_forcelist=[503]는 상태 코드 503(서비스를 사용할 수 없음)에서 재시도합니다.

기본적으로는 리트라이는 다음 상황에서만 실행됩니다.

  • 풀에서 연결을 가져올 수 없습니다.
  • TimeoutError
  • HTTPException(Python 3의 http.client에서, 그렇지 않으면 httplib에서).이것은 URL 또는 프로토콜이 올바르게 형성되지 않은 것과 같은 낮은 수준의 HTTP 예외인 것으로 보입니다.
  • SocketError
  • ProtocolError

이것들은 모두, 통상의 HTTP 응답을 수신할 수 없는 예외입니다.정기적인 응답이 생성되면 재시도되지 않습니다.status_forcelist를 사용하지 않으면 상태가 500인 응답도 재시도되지 않습니다.

리모트 API 또는 웹 서버에서 보다 직관적으로 동작하도록 하기 위해 위의 코드 스니펫을 사용합니다. 코드 스니펫은 모두 웹에서 드물지 않은 상태 500, 502, 503504를 강제로 재시도합니다.또한 이 모든 것은 충분히 긴 백오프 기간 동안 복구가 가능합니다.

에 있는 것이다.urllib3재시도하는 라이브러리입니다.다른 최대 재시도 횟수를 설정하려면 대체 전송 어댑터를 사용하십시오.

from requests.adapters import HTTPAdapter

s = requests.Session()
s.mount('http://stackoverflow.com', HTTPAdapter(max_retries=5))

max_retries인수는 정수 또는 객체를 취합니다.인수는 재시도되는 장애의 종류를 세밀하게 제어할 수 있습니다(정수값은 다음 명령어로 변환됩니다).Retry()접속 장애만을 처리하는 인스턴스.접속 후 오류는 부작용으로 이어질 수 있으므로 기본적으로 처리되지 않습니다).


요구 1.2.1 릴리스오래된 답변:

requests라이브러리는 실제로 이 설정을 할 수 없으며, 의도도 없습니다(이 풀 요청 참조).현재(요구 1.1) 재시도 횟수는 0으로 설정되어 있습니다.이 값을 더 높게 설정하려면 , 이것을 글로벌하게 설정할 필요가 있습니다.

import requests

requests.adapters.DEFAULT_RETRIES = 5

이 상수는 문서화되어 있지 않습니다.향후 릴리스에 따라 처리 방법이 변경될 수 있으므로 위험을 감수하고 사용하십시오.

업데이트: 그리고 이것은 변경되었습니다.버전 1.2.1에서는 클래스에 파라미터설정하는 옵션이 추가되어 대체 트랜스포트 어댑터를 사용해야 합니다(위 참조).이 원숭이 패치의 접근방식은 더 이상 기능하지 않습니다.패치 패치도 적용하지 않으면HTTPAdapter.__init__()★★★★★★★★★★★★★★★★★★」

Martijn Pieters의 답변은 버전 1.2.1+에 적합하지 않습니다.라이브러리에 패치를 적용하지 않고 글로벌하게 설정할 수 없습니다.

대신 이 작업을 수행할 수 있습니다.

import requests
from requests.adapters import HTTPAdapter

s = requests.Session()
s.mount('http://www.github.com', HTTPAdapter(max_retries=5))
s.mount('https://www.github.com', HTTPAdapter(max_retries=5))

여기서 몇 가지 답을 찾느라 좀 고생한 후, 저는 백오프라는 이름의 라이브러리가 제 상황에 더 잘 맞는다는 것을 발견했습니다.기본적인 예:

import backoff

@backoff.on_exception(
    backoff.expo,
    requests.exceptions.RequestException,
    max_tries=5,
    giveup=lambda e: e.response is not None and e.response.status_code < 500
)
def publish(self, data):
    r = requests.post(url, timeout=10, json=data)
    r.raise_for_status()

라이브러리의 네이티브 기능을 사용할 것을 권장합니다만, 문제가 발생하거나 보다 폭넓은 제어가 필요한 경우는, 백오프를 선택할 수 있습니다.

제어 능력을 높이는 보다 깔끔한 방법은 재시도 내용을 함수로 패키징하고 데코레이터와 화이트리스트를 사용하여 해당 함수를 검색할 수 있도록 하는 것입니다.

여기서도 같은 내용을 작성했습니다.http://www.praddy.in/retry-decorator-whitelisted-exceptions/

해당 링크의 코드 재생:

def retry(exceptions, delay=0, times=2):
"""
A decorator for retrying a function call with a specified delay in case of a set of exceptions

Parameter List
-------------
:param exceptions:  A tuple of all exceptions that need to be caught for retry
                                    e.g. retry(exception_list = (Timeout, Readtimeout))
:param delay: Amount of delay (seconds) needed between successive retries.
:param times: no of times the function should be retried


"""
def outer_wrapper(function):
    @functools.wraps(function)
    def inner_wrapper(*args, **kwargs):
        final_excep = None  
        for counter in xrange(times):
            if counter > 0:
                time.sleep(delay)
            final_excep = None
            try:
                value = function(*args, **kwargs)
                return value
            except (exceptions) as e:
                final_excep = e
                pass #or log it

        if final_excep is not None:
            raise final_excep
    return inner_wrapper

return outer_wrapper

@retry(exceptions=(TimeoutError, ConnectTimeoutError), delay=0, times=3)
def call_api():

요청 라이브러리를 사용하여 한 번에 모든 작업을 수행할 수 있습니다.다음 코드는 429,500,502,503 또는 504 상태 코드를 수신할 경우 매번 "backoff_factor"를 통해 더 긴 지연을 설정합니다.자세한 튜토리얼은 https://findwork.dev/blog/advanced-usage-python-requests-timeouts-retries-hooks/참조하십시오.

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

retry_strategy = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[429, 500, 502, 503, 504],
    method_whitelist=["HEAD", "GET", "OPTIONS"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)

response = http.get("https://en.wikipedia.org/w/api.php")

언급URL : https://stackoverflow.com/questions/15431044/can-i-set-max-retries-for-requests-request

반응형