diff --git a/mangopay/api.py b/mangopay/api.py index 308cb85..68f7577 100644 --- a/mangopay/api.py +++ b/mangopay/api.py @@ -2,21 +2,19 @@ from __future__ import print_function from __future__ import unicode_literals -import requests -import time import logging -import six -import copy -import mangopay -from mangopay.ratelimit import RateLimit +import time +import requests +import six +from requests.exceptions import ConnectionError, Timeout +import mangopay from mangopay.auth import AuthorizationTokenManager +from mangopay.ratelimit import RateLimit from .exceptions import APIError, DecodeError from .signals import request_finished, request_started, request_error -from .utils import reraise_as, truncatechars - -from requests.exceptions import ConnectionError, ConnectTimeout, Timeout +from .utils import reraise_as try: import urllib.parse as urlrequest @@ -34,8 +32,8 @@ requests_session = requests.Session() rate_limits = None -class APIRequest(object): +class APIRequest(object): def __init__(self, client_id=None, apikey=None, api_url=None, api_sandbox_url=None, sandbox=None, timeout=30.0, storage_strategy=None, proxies=None, uk_header_flag=False): @@ -181,44 +179,45 @@ def custom_request(self, method, url, data=None, idempotency_key=None, oauth_req else: self._create_decodeerror(result, url=url) - def init_rate_limits(self): - rate_limits = [RateLimit(15), RateLimit(30), RateLimit(60), RateLimit(24 * 60)] - return rate_limits - def read_response_headers(self, headers): - update_rate_limits = None - - for k, v in headers.items(): - lower_case_header = k.lower() - if lower_case_header == "x-ratelimit-remaining": - if update_rate_limits is None: - update_rate_limits = self.init_rate_limits() - calls_remaining = list(eval(v)) - update_rate_limits[0].calls_remaining = int(calls_remaining[3]) - update_rate_limits[1].calls_remaining = int(calls_remaining[2]) - update_rate_limits[2].calls_remaining = int(calls_remaining[1]) - update_rate_limits[3].calls_remaining = int(calls_remaining[0]) - - if lower_case_header == "x-ratelimit": - if update_rate_limits is None: - update_rate_limits = self.init_rate_limits() - calls_made = list(eval(v)) - update_rate_limits[0].calls_made = int(calls_made[3]) - update_rate_limits[1].calls_made = int(calls_made[2]) - update_rate_limits[2].calls_made = int(calls_made[1]) - update_rate_limits[3].calls_made = int(calls_made[0]) - - if lower_case_header == "x-ratelimit-reset": - if update_rate_limits is None: - update_rate_limits = self.init_rate_limits() - reset_times = list(eval(v)) - update_rate_limits[0].reset_time_millis = int(reset_times[3]) - update_rate_limits[1].reset_time_millis = int(reset_times[2]) - update_rate_limits[2].reset_time_millis = int(reset_times[1]) - update_rate_limits[3].reset_time_millis = int(reset_times[0]) - - if update_rate_limits is not None: - self.set_rate_limit(update_rate_limits) + rate_limit_reset = headers.get('x-ratelimit-reset') + rate_limit_remaining = headers.get('x-ratelimit-remaining') + rate_limit_made = headers.get('x-ratelimit') + + if rate_limit_reset is not None and rate_limit_remaining is not None and rate_limit_made is not None: + rate_limit_reset = rate_limit_reset.split(',') + rate_limit_remaining = rate_limit_remaining.split(',') + rate_limit_made = rate_limit_made.split(',') + + if len(rate_limit_reset) == len(rate_limit_remaining) and len(rate_limit_reset) == len(rate_limit_made): + current_time = int(time.time()) + updated_rate_limits = [] + + for i, rlr in enumerate(rate_limit_reset): + rate_limit = RateLimit() + number_of_minutes = (int(rate_limit_reset[i].strip()) - current_time) / 60 + + if number_of_minutes <= 15: + rate_limit.interval_minutes = 15 + elif number_of_minutes <= 30: + rate_limit.interval_minutes = 30 + elif number_of_minutes <= 60: + rate_limit.interval_minutes = 60 + elif number_of_minutes <= 60 * 24: + rate_limit.interval_minutes = 60 * 24 + + rate_limit.reset_time_millis = int(rate_limit_reset[i].strip()) + rate_limit.calls_remaining = int(rate_limit_remaining[i].strip()) + rate_limit.calls_made = int(rate_limit_made[i].strip()) + updated_rate_limits.append(rate_limit) + + if len(updated_rate_limits) > 0: + self.set_rate_limit(updated_rate_limits) + + else: + logger.debug("Could not set rate limits: headers length should be the same") + else: + logger.debug("Could not set rate limits: missing headers") def _absolute_url(self, url, encoded_params): pattern = '%s%s%s' diff --git a/mangopay/ratelimit.py b/mangopay/ratelimit.py index 00afc1c..099118e 100644 --- a/mangopay/ratelimit.py +++ b/mangopay/ratelimit.py @@ -1,10 +1,5 @@ class RateLimit: - interval_minutes = 0 calls_made = 0 calls_remaining = 0 reset_time_millis = 0 - - def __init__(self, interval_minutes): - self.interval_minutes = interval_minutes - diff --git a/tests/test_rate_limit.py b/tests/test_rate_limit.py index 3362bd8..073b1f7 100644 --- a/tests/test_rate_limit.py +++ b/tests/test_rate_limit.py @@ -1,5 +1,5 @@ -from tests.test_base import BaseTest, BaseTestLive from mangopay.api import APIRequest as api +from tests.test_base import BaseTest, BaseTestLive class RateLimit(BaseTest): @@ -11,4 +11,4 @@ def test_rate_limits_update(self): rate_limits = apis.get_rate_limits() self.assertIsNotNone(rate_limits) - self.assertTrue(len(rate_limits) == 4) \ No newline at end of file + self.assertTrue(len(rate_limits) > 0)