Skip to content

Commit

Permalink
maximum retries after rate limit failure configured
Browse files Browse the repository at this point in the history
Signed-off-by: Shaharyar Shamshi <shaharyarshamshi@gmail.com>
  • Loading branch information
shaharyar-shamshi committed Nov 26, 2022
1 parent 60035c1 commit 0f75736
Showing 1 changed file with 31 additions and 2 deletions.
33 changes: 31 additions & 2 deletions shipbob/client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import os
import time
import math
from datetime import datetime, timedelta
from typing import Iterator, List

Expand All @@ -20,6 +21,12 @@ class ShipBobClient(Session):

ACCESS_TOKEN = os.getenv("SHIPBOB_ACCESS_TOKEN")

MAX_RETRIES_AFTER_RATE_LIMIT: int = os.getenv("SHIPBOB_MAX_RETRIES_AFTER_RATE_LIMIT")

MAX_SLEEP_TIME_AFTER_RATE_LIMIT_IN_SECONDS: int = os.getenv(
"SHIPBOB_MAX_SLEEP_TIME_AFTER_RATE_LIMIT_IN_SECONDS"
)

MAX_PAGE_SIZE: int = 250
MAX_REQUESTS_PER_MINUTE: int = 150 # As per ShipBob docs, 150 reqs/min sliding window

Expand All @@ -34,6 +41,14 @@ def __init__(self):

self._request_bucket = []

self.RETRIES_AFTER_RATE_LIMIT: int = 0

if not self.MAX_RETRIES_AFTER_RATE_LIMIT:
self.MAX_RETRIES_AFTER_RATE_LIMIT = 1

if not self.MAX_SLEEP_TIME_AFTER_RATE_LIMIT_IN_SECONDS:
self.MAX_SLEEP_TIME_AFTER_RATE_LIMIT_IN_SECONDS = 60

def _clear_request_bucket(self):
now = datetime.now()
one_minute_old = now - timedelta(seconds=60)
Expand All @@ -59,10 +74,24 @@ def request(self, method, url, retry_on_rate_limit=True, *args, **kwargs):
except ValueError:
retry_after: int = 10
logger.warning(f"Waiting {retry_after} seconds to try again...")
time.sleep(retry_after)
return self.request(method, url, retry_on_rate_limit=False, *args, **kwargs)

if self.MAX_SLEEP_TIME_AFTER_RATE_LIMIT_IN_SECONDS < retry_after * math.pow(
2, self.RETRIES_AFTER_RATE_LIMIT - 1
):
logger.warning(
f"Threshold waiting time of \
{self.MAX_SLEEP_TIME_AFTER_RATE_LIMIT_IN_SECONDS} \
after rate limit exceeded."
)
raise e

time.sleep(retry_after * math.pow(2, self.RETRIES_AFTER_RATE_LIMIT))
self.RETRIES_AFTER_RATE_LIMIT = self.RETRIES_AFTER_RATE_LIMIT + 1
if self.MAX_RETRIES_AFTER_RATE_LIMIT >= self.RETRIES_AFTER_RATE_LIMIT:
return self.request(method, url, retry_on_rate_limit=True, *args, **kwargs)
else:
raise e
self.RETRIES_AFTER_RATE_LIMIT = 0
return response

def get_orders(self, **params) -> List[Order]:
Expand Down

0 comments on commit 0f75736

Please sign in to comment.