Merge pull request #93 from codl/fix-ratelimit
fix #92, check for throttling by status code, and do it before the catchall error handler
This commit is contained in:
commit
61552f9f84
S'han modificat 1 arxius amb 32 adicions i 30 eliminacions
|
@ -1050,6 +1050,25 @@ class Mastodon:
|
||||||
if response_object is None:
|
if response_object is None:
|
||||||
raise MastodonIllegalArgumentError("Illegal request.")
|
raise MastodonIllegalArgumentError("Illegal request.")
|
||||||
|
|
||||||
|
# Parse rate limiting headers
|
||||||
|
if 'X-RateLimit-Remaining' in response_object.headers and do_ratelimiting:
|
||||||
|
self.ratelimit_remaining = int(response_object.headers['X-RateLimit-Remaining'])
|
||||||
|
self.ratelimit_limit = int(response_object.headers['X-RateLimit-Limit'])
|
||||||
|
|
||||||
|
try:
|
||||||
|
ratelimit_reset_datetime = dateutil.parser.parse(response_object.headers['X-RateLimit-Reset'])
|
||||||
|
self.ratelimit_reset = self.__datetime_to_epoch(ratelimit_reset_datetime)
|
||||||
|
|
||||||
|
# Adjust server time to local clock
|
||||||
|
if 'Date' in response_object.headers:
|
||||||
|
server_time_datetime = dateutil.parser.parse(response_object.headers['Date'])
|
||||||
|
server_time = self.__datetime_to_epoch(server_time_datetime)
|
||||||
|
server_time_diff = time.time() - server_time
|
||||||
|
self.ratelimit_reset += server_time_diff
|
||||||
|
self.ratelimit_lastcall = time.time()
|
||||||
|
except Exception as e:
|
||||||
|
raise MastodonRatelimitError("Rate limit time calculations failed: %s" % e)
|
||||||
|
|
||||||
# Handle response
|
# Handle response
|
||||||
if self.debug_requests:
|
if self.debug_requests:
|
||||||
print('Mastodon: Response received with code ' + str(response_object.status_code) + '.')
|
print('Mastodon: Response received with code ' + str(response_object.status_code) + '.')
|
||||||
|
@ -1071,6 +1090,19 @@ class Mastodon:
|
||||||
if response_object.status_code == 500:
|
if response_object.status_code == 500:
|
||||||
raise MastodonAPIError('General API problem.')
|
raise MastodonAPIError('General API problem.')
|
||||||
|
|
||||||
|
# Handle rate limiting
|
||||||
|
if response_object.status_code == 429:
|
||||||
|
if self.ratelimit_method == 'throw' or not do_ratelimiting:
|
||||||
|
raise MastodonRatelimitError('Hit rate limit.')
|
||||||
|
elif self.ratelimit_method in ('wait', 'pace'):
|
||||||
|
to_next = self.ratelimit_reset - time.time()
|
||||||
|
if to_next > 0:
|
||||||
|
# As a precaution, never sleep longer than 5 minutes
|
||||||
|
to_next = min(to_next, 5 * 60)
|
||||||
|
time.sleep(to_next)
|
||||||
|
request_complete = False
|
||||||
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = response_object.json(object_hook=self.__json_date_parse)
|
response = response_object.json(object_hook=self.__json_date_parse)
|
||||||
except:
|
except:
|
||||||
|
@ -1121,36 +1153,6 @@ class Mastodon:
|
||||||
del prev_params['max_id']
|
del prev_params['max_id']
|
||||||
response[0]['_pagination_prev'] = prev_params
|
response[0]['_pagination_prev'] = prev_params
|
||||||
|
|
||||||
# Handle rate limiting
|
|
||||||
if 'X-RateLimit-Remaining' in response_object.headers and do_ratelimiting:
|
|
||||||
self.ratelimit_remaining = int(response_object.headers['X-RateLimit-Remaining'])
|
|
||||||
self.ratelimit_limit = int(response_object.headers['X-RateLimit-Limit'])
|
|
||||||
|
|
||||||
try:
|
|
||||||
ratelimit_reset_datetime = dateutil.parser.parse(response_object.headers['X-RateLimit-Reset'])
|
|
||||||
self.ratelimit_reset = self.__datetime_to_epoch(ratelimit_reset_datetime)
|
|
||||||
|
|
||||||
# Adjust server time to local clock
|
|
||||||
if 'Date' in response_object.headers:
|
|
||||||
server_time_datetime = dateutil.parser.parse(response_object.headers['Date'])
|
|
||||||
server_time = self.__datetime_to_epoch(server_time_datetime)
|
|
||||||
server_time_diff = time.time() - server_time
|
|
||||||
self.ratelimit_reset += server_time_diff
|
|
||||||
self.ratelimit_lastcall = time.time()
|
|
||||||
except Exception as e:
|
|
||||||
raise MastodonRatelimitError("Rate limit time calculations failed: %s" % e)
|
|
||||||
|
|
||||||
if "error" in response and response["error"] == "Throttled":
|
|
||||||
if self.ratelimit_method == "throw":
|
|
||||||
raise MastodonRatelimitError("Hit rate limit.")
|
|
||||||
|
|
||||||
if self.ratelimit_method == "wait" or self.ratelimit_method == "pace":
|
|
||||||
to_next = self.ratelimit_reset - time.time()
|
|
||||||
if to_next > 0:
|
|
||||||
# As a precaution, never sleep longer than 5 minutes
|
|
||||||
to_next = min(to_next, 5 * 60)
|
|
||||||
time.sleep(to_next)
|
|
||||||
request_complete = False
|
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
Loading…
Referencia en una nova incidència