Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b5fd8bb

Browse files
committed
handle rate limit errors exposing the reset header value
1 parent af0c61b commit b5fd8bb

File tree

3 files changed

+35
-16
lines changed

3 files changed

+35
-16
lines changed

auth0/v3/authentication/base.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
import sys
44
import platform
55
import requests
6-
from ..exceptions import Auth0Error
7-
6+
from ..exceptions import Auth0Error, RateLimitError
87

98
UNKNOWN_ERROR = 'a0.sdk.internal.unknown'
109

1110

1211
class AuthenticationBase(object):
13-
1412
"""Base authentication object providing simple REST methods.
1513
1614
Args:
@@ -69,12 +67,19 @@ def _parse(self, response):
6967

7068

7169
class Response(object):
72-
def __init__(self, status_code, content):
70+
def __init__(self, status_code, content, headers):
7371
self._status_code = status_code
7472
self._content = content
73+
self._headers = headers
7574

7675
def content(self):
7776
if self._is_error():
77+
if self._status_code == 429:
78+
reset_at = int(self._headers.get('x-ratelimit-reset', '-1'))
79+
raise RateLimitError(error_code=self._error_code(),
80+
message=self._error_message(),
81+
reset_at=reset_at)
82+
7883
raise Auth0Error(status_code=self._status_code,
7984
error_code=self._error_code(),
8085
message=self._error_message())
@@ -95,7 +100,7 @@ def _error_message(self):
95100
class JsonResponse(Response):
96101
def __init__(self, response):
97102
content = json.loads(response.text)
98-
super(JsonResponse, self).__init__(response.status_code, content)
103+
super(JsonResponse, self).__init__(response.status_code, content, response.headers)
99104

100105
def _error_code(self):
101106
if 'error' in self._content:
@@ -111,7 +116,7 @@ def _error_message(self):
111116

112117
class PlainResponse(Response):
113118
def __init__(self, response):
114-
super(PlainResponse, self).__init__(response.status_code, response.text)
119+
super(PlainResponse, self).__init__(response.status_code, response.text, response.headers)
115120

116121
def _error_code(self):
117122
return UNKNOWN_ERROR
@@ -122,7 +127,7 @@ def _error_message(self):
122127

123128
class EmptyResponse(Response):
124129
def __init__(self, status_code):
125-
super(EmptyResponse, self).__init__(status_code, '')
130+
super(EmptyResponse, self).__init__(status_code, '', {})
126131

127132
def _error_code(self):
128133
return UNKNOWN_ERROR

auth0/v3/exceptions.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,11 @@ def __str__(self):
88
return '{}: {}'.format(self.status_code, self.message)
99

1010

11+
class RateLimitError(Auth0Error):
12+
def __init__(self, error_code, message, reset_at):
13+
super(RateLimitError, self).__init__(status_code=429, error_code=error_code, message=message)
14+
self.reset_at = reset_at
15+
16+
1117
class TokenValidationError(Exception):
1218
pass

auth0/v3/management/rest.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
import sys
2-
import platform
3-
import json
41
import base64
2+
import json
3+
import platform
4+
import sys
5+
56
import requests
6-
from ..exceptions import Auth0Error
77

8+
from ..exceptions import Auth0Error, RateLimitError
89

910
UNKNOWN_ERROR = 'a0.sdk.internal.unknown'
1011

1112

1213
class RestClient(object):
13-
1414
"""Provides simple methods for handling all RESTful api endpoints.
1515
1616
Args:
@@ -21,6 +21,7 @@ class RestClient(object):
2121
both values separately or a float to set both to it.
2222
(defaults to 5.0 for both)
2323
"""
24+
2425
def __init__(self, jwt, telemetry=True, timeout=5.0):
2526
self.jwt = jwt
2627
self.timeout = timeout
@@ -96,12 +97,19 @@ def _parse(self, response):
9697

9798

9899
class Response(object):
99-
def __init__(self, status_code, content):
100+
def __init__(self, status_code, content, headers):
100101
self._status_code = status_code
101102
self._content = content
103+
self._headers = headers
102104

103105
def content(self):
104106
if self._is_error():
107+
if self._status_code == 429:
108+
reset_at = int(self._headers.get('x-ratelimit-reset', '-1'))
109+
raise RateLimitError(error_code=self._error_code(),
110+
message=self._error_message(),
111+
reset_at=reset_at)
112+
105113
raise Auth0Error(status_code=self._status_code,
106114
error_code=self._error_code(),
107115
message=self._error_message())
@@ -122,7 +130,7 @@ def _error_message(self):
122130
class JsonResponse(Response):
123131
def __init__(self, response):
124132
content = json.loads(response.text)
125-
super(JsonResponse, self).__init__(response.status_code, content)
133+
super(JsonResponse, self).__init__(response.status_code, content, response.headers)
126134

127135
def _error_code(self):
128136
if 'errorCode' in self._content:
@@ -141,7 +149,7 @@ def _error_message(self):
141149

142150
class PlainResponse(Response):
143151
def __init__(self, response):
144-
super(PlainResponse, self).__init__(response.status_code, response.text)
152+
super(PlainResponse, self).__init__(response.status_code, response.text, response.headers)
145153

146154
def _error_code(self):
147155
return UNKNOWN_ERROR
@@ -152,7 +160,7 @@ def _error_message(self):
152160

153161
class EmptyResponse(Response):
154162
def __init__(self, status_code):
155-
super(EmptyResponse, self).__init__(status_code, '')
163+
super(EmptyResponse, self).__init__(status_code, '', {})
156164

157165
def _error_code(self):
158166
return UNKNOWN_ERROR

0 commit comments

Comments
 (0)