aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenz Diener <[email protected]>2017-10-16 11:19:49 +0200
committerGitHub <[email protected]>2017-10-16 11:19:49 +0200
commit61552f9f84c736d447e0fccd54040d3b956a83e9 (patch)
tree553b2f69547ee5d476d08befe4cb5d8537dca146 /mastodon
parent186b7135ff970feebe9442f813e7ccd1c414cdc1 (diff)
parent0ff6abf2f4ac9ebdc13391fc8e52b3dcc297f1fa (diff)
downloadmastodon.py-61552f9f84c736d447e0fccd54040d3b956a83e9.tar.gz
Merge pull request #93 from codl/fix-ratelimit
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 6ffb0e4..b118421 100644
--- a/mastodon/Mastodon.py
+++ b/mastodon/Mastodon.py
@@ -1050,6 +1050,25 @@ class Mastodon:
1050 if response_object is None: 1050 if response_object is None:
1051 raise MastodonIllegalArgumentError("Illegal request.") 1051 raise MastodonIllegalArgumentError("Illegal request.")
1052 1052
1053 # Parse rate limiting headers
1054 if 'X-RateLimit-Remaining' in response_object.headers and do_ratelimiting:
1055 self.ratelimit_remaining = int(response_object.headers['X-RateLimit-Remaining'])
1056 self.ratelimit_limit = int(response_object.headers['X-RateLimit-Limit'])
1057
1058 try:
1059 ratelimit_reset_datetime = dateutil.parser.parse(response_object.headers['X-RateLimit-Reset'])
1060 self.ratelimit_reset = self.__datetime_to_epoch(ratelimit_reset_datetime)
1061
1062 # Adjust server time to local clock
1063 if 'Date' in response_object.headers:
1064 server_time_datetime = dateutil.parser.parse(response_object.headers['Date'])
1065 server_time = self.__datetime_to_epoch(server_time_datetime)
1066 server_time_diff = time.time() - server_time
1067 self.ratelimit_reset += server_time_diff
1068 self.ratelimit_lastcall = time.time()
1069 except Exception as e:
1070 raise MastodonRatelimitError("Rate limit time calculations failed: %s" % e)
1071
1053 # Handle response 1072 # Handle response
1054 if self.debug_requests: 1073 if self.debug_requests:
1055 print('Mastodon: Response received with code ' + str(response_object.status_code) + '.') 1074 print('Mastodon: Response received with code ' + str(response_object.status_code) + '.')
@@ -1071,6 +1090,19 @@ class Mastodon:
1071 if response_object.status_code == 500: 1090 if response_object.status_code == 500:
1072 raise MastodonAPIError('General API problem.') 1091 raise MastodonAPIError('General API problem.')
1073 1092
1093 # Handle rate limiting
1094 if response_object.status_code == 429:
1095 if self.ratelimit_method == 'throw' or not do_ratelimiting:
1096 raise MastodonRatelimitError('Hit rate limit.')
1097 elif self.ratelimit_method in ('wait', 'pace'):
1098 to_next = self.ratelimit_reset - time.time()
1099 if to_next > 0:
1100 # As a precaution, never sleep longer than 5 minutes
1101 to_next = min(to_next, 5 * 60)
1102 time.sleep(to_next)
1103 request_complete = False
1104 continue
1105
1074 try: 1106 try:
1075 response = response_object.json(object_hook=self.__json_date_parse) 1107 response = response_object.json(object_hook=self.__json_date_parse)
1076 except: 1108 except:
@@ -1121,36 +1153,6 @@ class Mastodon:
1121 del prev_params['max_id'] 1153 del prev_params['max_id']
1122 response[0]['_pagination_prev'] = prev_params 1154 response[0]['_pagination_prev'] = prev_params
1123 1155
1124 # Handle rate limiting
1125 if 'X-RateLimit-Remaining' in response_object.headers and do_ratelimiting:
1126 self.ratelimit_remaining = int(response_object.headers['X-RateLimit-Remaining'])
1127 self.ratelimit_limit = int(response_object.headers['X-RateLimit-Limit'])
1128
1129 try:
1130 ratelimit_reset_datetime = dateutil.parser.parse(response_object.headers['X-RateLimit-Reset'])
1131 self.ratelimit_reset = self.__datetime_to_epoch(ratelimit_reset_datetime)
1132
1133 # Adjust server time to local clock
1134 if 'Date' in response_object.headers:
1135 server_time_datetime = dateutil.parser.parse(response_object.headers['Date'])
1136 server_time = self.__datetime_to_epoch(server_time_datetime)
1137 server_time_diff = time.time() - server_time
1138 self.ratelimit_reset += server_time_diff
1139 self.ratelimit_lastcall = time.time()
1140 except Exception as e:
1141 raise MastodonRatelimitError("Rate limit time calculations failed: %s" % e)
1142
1143 if "error" in response and response["error"] == "Throttled":
1144 if self.ratelimit_method == "throw":
1145 raise MastodonRatelimitError("Hit rate limit.")
1146
1147 if self.ratelimit_method == "wait" or self.ratelimit_method == "pace":
1148 to_next = self.ratelimit_reset - time.time()
1149 if to_next > 0:
1150 # As a precaution, never sleep longer than 5 minutes
1151 to_next = min(to_next, 5 * 60)
1152 time.sleep(to_next)
1153 request_complete = False
1154 1156
1155 return response 1157 return response
1156 1158
Powered by cgit v1.2.3 (git 2.41.0)