diff options
Diffstat (limited to 'mastodon')
-rw-r--r-- | mastodon/Mastodon.py | 62 |
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 | ||