Skip to content

Commit

Permalink
updated the way rate limits are set (#387)
Browse files Browse the repository at this point in the history
Co-authored-by: Iulian Masar <iulian.masar@codegile.com>
  • Loading branch information
iulian03 and Iulian Masar authored Feb 28, 2025
1 parent 49b5008 commit 4882f7f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 54 deletions.
93 changes: 46 additions & 47 deletions mangopay/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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):
Expand Down Expand Up @@ -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'
Expand Down
5 changes: 0 additions & 5 deletions mangopay/ratelimit.py
Original file line number Diff line number Diff line change
@@ -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

4 changes: 2 additions & 2 deletions tests/test_rate_limit.py
Original file line number Diff line number Diff line change
@@ -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):
Expand All @@ -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)
self.assertTrue(len(rate_limits) > 0)

0 comments on commit 4882f7f

Please sign in to comment.