aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcodl <[email protected]>2017-10-04 16:08:21 +0200
committercodl <[email protected]>2017-10-04 16:08:21 +0200
commit0ff6abf2f4ac9ebdc13391fc8e52b3dcc297f1fa (patch)
tree0a2630de6a135f14de1e2c7fd19f658e6c8d6a23 /mastodon
parentb18b6f201b75f704655e0784930a74050fb196b9 (diff)
downloadmastodon.py-0ff6abf2f4ac9ebdc13391fc8e52b3dcc297f1fa.tar.gz
fix #92, check for throttling by status code, and do it before the catchall error handler
Diffstat (limited to 'mastodon')
-rw-r--r--mastodon/Mastodon.py62
1 files changed, 32 insertions, 30 deletions
diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py
index 5b198a5..7a1d701 100644
--- a/mastodon/Mastodon.py
+++ b/mastodon/Mastodon.py
@@ -1047,6 +1047,25 @@ class Mastodon:
1047 if response_object is None: 1047 if response_object is None:
1048 raise MastodonIllegalArgumentError("Illegal request.") 1048 raise MastodonIllegalArgumentError("Illegal request.")
1049 1049
1050 # Parse rate limiting headers
1051 if 'X-RateLimit-Remaining' in response_object.headers and do_ratelimiting:
1052 self.ratelimit_remaining = int(response_object.headers['X-RateLimit-Remaining'])
1053 self.ratelimit_limit = int(response_object.headers['X-RateLimit-Limit'])
1054
1055 try:
1056 ratelimit_reset_datetime = dateutil.parser.parse(response_object.headers['X-RateLimit-Reset'])
1057 self.ratelimit_reset = self.__datetime_to_epoch(ratelimit_reset_datetime)
1058
1059 # Adjust server time to local clock
1060 if 'Date' in response_object.headers:
1061 server_time_datetime = dateutil.parser.parse(response_object.headers['Date'])
1062 server_time = self.__datetime_to_epoch(server_time_datetime)
1063 server_time_diff = time.time() - server_time
1064 self.ratelimit_reset += server_time_diff
1065 self.ratelimit_lastcall = time.time()
1066 except Exception as e:
1067 raise MastodonRatelimitError("Rate limit time calculations failed: %s" % e)
1068
1050 # Handle response 1069 # Handle response
1051 if self.debug_requests: 1070 if self.debug_requests:
1052 print('Mastodon: Response received with code ' + str(response_object.status_code) + '.') 1071 print('Mastodon: Response received with code ' + str(response_object.status_code) + '.')
@@ -1068,6 +1087,19 @@ class Mastodon:
1068 if response_object.status_code == 500: 1087 if response_object.status_code == 500:
1069 raise MastodonAPIError('General API problem.') 1088 raise MastodonAPIError('General API problem.')
1070 1089
1090 # Handle rate limiting
1091 if response_object.status_code == 429:
1092 if self.ratelimit_method == 'throw' or not do_ratelimiting:
1093 raise MastodonRatelimitError('Hit rate limit.')
1094 elif self.ratelimit_method in ('wait', 'pace'):
1095 to_next = self.ratelimit_reset - time.time()
1096 if to_next > 0:
1097 # As a precaution, never sleep longer than 5 minutes
1098 to_next = min(to_next, 5 * 60)
1099 time.sleep(to_next)
1100 request_complete = False
1101 continue
1102
1071 try: 1103 try:
1072 response = response_object.json(object_hook=self.__json_date_parse) 1104 response = response_object.json(object_hook=self.__json_date_parse)
1073 except: 1105 except:
@@ -1118,36 +1150,6 @@ class Mastodon:
1118 del prev_params['max_id'] 1150 del prev_params['max_id']
1119 response[0]['_pagination_prev'] = prev_params 1151 response[0]['_pagination_prev'] = prev_params
1120 1152
1121 # Handle rate limiting
1122 if 'X-RateLimit-Remaining' in response_object.headers and do_ratelimiting:
1123 self.ratelimit_remaining = int(response_object.headers['X-RateLimit-Remaining'])
1124 self.ratelimit_limit = int(response_object.headers['X-RateLimit-Limit'])
1125
1126 try:
1127 ratelimit_reset_datetime = dateutil.parser.parse(response_object.headers['X-RateLimit-Reset'])
1128 self.ratelimit_reset = self.__datetime_to_epoch(ratelimit_reset_datetime)
1129
1130 # Adjust server time to local clock
1131 if 'Date' in response_object.headers:
1132 server_time_datetime = dateutil.parser.parse(response_object.headers['Date'])
1133 server_time = self.__datetime_to_epoch(server_time_datetime)
1134 server_time_diff = time.time() - server_time
1135 self.ratelimit_reset += server_time_diff
1136 self.ratelimit_lastcall = time.time()
1137 except Exception as e:
1138 raise MastodonRatelimitError("Rate limit time calculations failed: %s" % e)
1139
1140 if "error" in response and response["error"] == "Throttled":
1141 if self.ratelimit_method == "throw":
1142 raise MastodonRatelimitError("Hit rate limit.")
1143
1144 if self.ratelimit_method == "wait" or self.ratelimit_method == "pace":
1145 to_next = self.ratelimit_reset - time.time()
1146 if to_next > 0:
1147 # As a precaution, never sleep longer than 5 minutes
1148 to_next = min(to_next, 5 * 60)
1149 time.sleep(to_next)
1150 request_complete = False
1151 1153
1152 return response 1154 return response
1153 1155
Powered by cgit v1.2.3 (git 2.41.0)