Skip to content

Commit

Permalink
Merge pull request IgnoredAmbience#32 from lennier1/master
Browse files Browse the repository at this point in the history
Limit NotAuthenticated retries
  • Loading branch information
marked authored Nov 28, 2019
2 parents 57d176d + cb19595 commit ffe5a9a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 6 deletions.
2 changes: 1 addition & 1 deletion test_yahoogroupsapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def test_unauthorized_error(yahoo_response):
def test_not_authenticated_error(yahoo_response):
r = yahoo_response('v1/groups/groupname/', status=307)
yga = YahooGroupsAPI('groupname')
with raises(yahoogroupsapi.Recoverable): # Temporary fix, replaced: yahoogroupsapi.NotAuthenticated
with raises(yahoogroupsapi.NotAuthenticated):
yga.HackGroupInfo()
assert len(r.calls) == 15

Expand Down
19 changes: 14 additions & 5 deletions yahoogroupsapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,15 @@ class Unrecoverable(YGAException):
"""An error that can not be resolved by retrying the request."""
pass


class BadSize(YGAException):
"""The filesize is between 60 and 68 bytes, which could be in error"""
pass


class AuthenticationError(Unrecoverable):
pass


class NotAuthenticated(AuthenticationError):
class NotAuthenticated(YGAException):
"""307, with Yahoo errorCode 1101, user is not logged in and attempting to read content requiring authentication."""
pass

Expand Down Expand Up @@ -83,6 +81,8 @@ class YahooGroupsAPI:
s = None
ww = None
http_context = dummy_contextmanager
authenticationFailures = 0


def __init__(self, group, cookie_jar=None, headers={}, min_delay=0, retries=15):
self.s = requests.Session()
Expand Down Expand Up @@ -173,8 +173,15 @@ def get_json(self, target, *parts, **opts):
r = self.s.get(uri, params=opts, verify=VERIFY_HTTPS, allow_redirects=False, timeout=15)

code = r.status_code
# 307 authentication errors have frequently proven to be transient, but enough in a row might indicate something like an expired cookie.
if code == 307:
raise Recoverable() # NotAuthenticated()
self.authenticationFailures += 1
if (self.authenticationFailures > 50):
self.logger.debug("Terminating due to %d consecutive authentication failures.", self.authenticationFailures)
raise Unrecoverable()
else:
self.logger.debug("There have been %d consecutive authentication failures. Retrying.", self.authenticationFailures)
raise NotAuthenticated()
elif code == 401 or code == 403:
raise Unauthorized()
elif code == 404:
Expand All @@ -185,8 +192,10 @@ def get_json(self, target, *parts, **opts):
# TODO: Test ygError response?
raise Recoverable()

# Reset authentical failure count upon successful json download.
self.authenticationFailures = 0
return r.json()['ygData']
except (ConnectionError, Timeout, Recoverable, BadSize) as e:
except (ConnectionError, Timeout, Recoverable, BadSize, NotAuthenticated) as e:
self.logger.info("API query failed for '%s': %s", uri, e)
self.logger.debug("Exception detail:", exc_info=e)

Expand Down

0 comments on commit ffe5a9a

Please sign in to comment.