본문 바로가기
Coding/Python

Python Requests Retry

by Hide­ 2019. 9. 5.
반응형

일반적으로 파이썬에서 리퀘스트를 보낼 때 requests 라이브러리를 사용한다. 사용법이 간단하고 직관적이므로 처음 사용하는 사용자들이라도 손쉽게 사용할 수 있기 때문이다. (https://2.python-requests.org/en/master/)

만약 리퀘스트를 보낸 후 돌려받은 Response를 통해 어떠한 로직을 거쳐야하는 상황이 있다고 가정해보자. 만약 단 한번의 리퀘스트를 전송했는데 대상 서버의 상태가 죽어있을 경우 정상적인 Repsonse를 받을 수 없고 그 이후에 거치는 로직또한 정상적으로 탈 수 없다. 따라서 대상 서버의 응답이 정상이 아니라면, 일정한 횟수동안 재시도(Retry)를 하도록 구현해야한다.

이러한 재시도 로직이 필요할 경우 개발자가 직접 특정한 로직을 구현할 필요없이 라이브러리 자체적으로 제공하는 기능을 사용할 수 있다. 순서는 다음과 같다.

  1. Session 객체 생성
  2. Retry 객체 생성
  3. 생성한 Session 객체에 HTTPAdapter객체 마운트
  4. 생성한 Session 객체를 사용하여 요청 전송
from requests import Session
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry


session = Session()
retries = Retry(total=retry_count, backoff_factor=1, status_forcelist=[502, 503, 504])
session.mount('http://', HTTPAdapter(max_retries=retries))
result = session.get(url='http://localhost:8000')
print(result.text)

대상 서버는 로컬에서 장고 서버를 띄워놓고 진행했으며 서버를 끈 상태에서 위 코드를 실행시키고 그 이후에 서버를 킨다면 재시도를 통해 추후에는 Response를 뿌려줌을 확인할 수 있다.

추가적인 설명을 덧붙인다.

  • session.mount(prefix, adapter)에 http:// 라는 prefix를 붙인다. 이는 해당 세션을 사용하고 http:// 로 시작하는 모든 주소에 대한 요청에 adapter를 마운트 한다는 의미이다.
  • Retry() 객체 생성 시 total은 총 시도 횟수, backoff_factor는 재시도 횟수 간 대기 시간을 점차적으로 얼만큼의 크기만큼 늘릴지에 대한 설정이다. status_forcelist는 재시도를 해야하는 status code이다.
  • 만약 리퀘스트에 헤더를 추가하고 싶다면, session.headers.update({'Authorization': 'Bearer 123'}) 형태로 추가하면 된다.
  • Retry() 객체를 생성할 때 total 파라미터에 재시도 횟수를 적어주는데 Retry, 즉 재시도이기 때문에 1을 기입하면 리퀘스트를 1번 보내고 실패했다면 1번 더 보내는것으로 생각했지만 실제로는 총 리퀘스트를 1번만 보낸다. 따라서 해당 파라미터는 총 시도 횟수라고 생각하는것이 좋다. 1번 리퀘스트를 보내고 실패했을 때 딱 한번만 더 재시도를 진행하고 싶다면 total=2라고 적어줘야 한다.