Adding communications Retry functionality into requests via urllib3 retry object. (#1002)

This is a continuation of the work started by @allevin on https://github.com/PyGithub/PyGithub/pull/860.

I have refactored the testing Framework to use the `httpretty` library in order to use the urllib3 retry feature and therefore be able to test it.

Please refer to https://github.com/PyGithub/PyGithub/pull/860 for additional context.

cc: @allevin @mfonville @jrouquie @sfdye

Closes #757 
Closes #860
This commit is contained in:
Isac Souza
2019-04-05 13:49:01 +08:00
committed by Wan Liuyang
parent 6efd631890
commit 5ae7af55ea
13 changed files with 311 additions and 28 deletions
+18 -7
View File
@@ -89,13 +89,18 @@ class RequestsResponse:
class HTTPSRequestsConnectionClass(object):
# mimic the httplib connection object
def __init__(self, host, port=None, strict=False, timeout=None, **kwargs):
def __init__(self, host, port=None, strict=False, timeout=None, retry=None, **kwargs):
self.port = port if port else 443
self.host = host
self.protocol = "https"
self.timeout = timeout
self.verify = kwargs.get("verify", True)
self.session = requests.Session()
# Code to support retries
if retry:
self.retry = retry
self.adapter = requests.adapters.HTTPAdapter(max_retries=self.retry)
self.session.mount('https://', self.adapter)
def request(self, verb, url, input, headers):
self.verb = verb
@@ -115,13 +120,18 @@ class HTTPSRequestsConnectionClass(object):
class HTTPRequestsConnectionClass(object):
# mimic the httplib connection object
def __init__(self, host, port=None, strict=False, timeout=None, **kwargs):
def __init__(self, host, port=None, strict=False, timeout=None, retry=None, **kwargs):
self.port = port if port else 80
self.host = host
self.protocol = "http"
self.timeout = timeout
self.verify = kwargs.get("verify", True)
self.session = requests.Session()
# Code to support retries
if retry:
self.retry = retry
self.adapter = requests.adapters.HTTPAdapter(max_retries=self.retry)
self.session.mount('http://', self.adapter)
def request(self, verb, url, input, headers):
self.verb = verb
@@ -214,7 +224,7 @@ class Requester:
#############################################################
def __init__(self, login_or_token, password, jwt, base_url, timeout, client_id, client_secret, user_agent, per_page, api_preview, verify):
def __init__(self, login_or_token, password, jwt, base_url, timeout, client_id, client_secret, user_agent, per_page, api_preview, verify, retry):
self._initializeDebugFeature()
if password is not None:
@@ -237,6 +247,7 @@ class Requester:
self.__port = o.port
self.__prefix = o.path
self.__timeout = timeout
self.__retry = retry # NOTE: retry can be either int or an urllib3 Retry object
self.__scheme = o.scheme
if o.scheme == "https":
self.__connectionClass = self.__httpsConnectionClass
@@ -283,9 +294,9 @@ class Requester:
(o.port and o.port != self.__port) or \
(o.scheme != self.__scheme and not (o.scheme == "https" and self.__scheme == "http")): # issue80
if o.scheme == 'http':
cnx = self.__httpConnectionClass(o.hostname, o.port)
cnx = self.__httpConnectionClass(o.hostname, o.port, retry = self.__retry)
elif o.scheme == 'https':
cnx = self.__httpsConnectionClass(o.hostname, o.port)
cnx = self.__httpsConnectionClass(o.hostname, o.port, retry = self.__retry)
return cnx
def __createException(self, status, headers, output):
@@ -459,7 +470,7 @@ class Requester:
if self.__persist and self.__connection is not None:
return self.__connection
self.__connection = self.__connectionClass(self.__hostname, self.__port, **kwds)
self.__connection = self.__connectionClass(self.__hostname, self.__port, retry = self.__retry, **kwds)
return self.__connection
@@ -475,4 +486,4 @@ class Requester:
requestHeaders["Authorization"] = "Bearer (jwt removed)"
else: # pragma no cover (Cannot happen, but could if we add an authentication method => be prepared)
requestHeaders["Authorization"] = "(unknown auth removed)" # pragma no cover (Cannot happen, but could if we add an authentication method => be prepared)
logger.debug("%s %s://%s%s %s %s ==> %i %s %s", str(verb), self.__scheme, self.__hostname, str(url), str(requestHeaders), str(input), status, str(responseHeaders), str(output))
logger.debug("%s %s://%s%s %s %s ==> %i %s %s", verb, self.__scheme, self.__hostname, url, requestHeaders, input, status, responseHeaders, output)