I am trying to limit my API calls based on the below limit rates. To achieve this am trying to use ratelimit
from python.
I am able to use the per second limit based on rate limit as shown below:
from ratelimit import limits, sleep_and_retry
SEC_CALLS = 10
SEC_RATE_LIMIT = 1
@sleep_and_retry
@limits(calls=SEC_CALLS, period=SEC_RATE_LIMIT)
def check_limit_secs():
print(f'sec time: {time.time()}')
return
##Function Code:
for i in ID:
check_limit_secs()
url = 'https://xxxxxx{}'.format(ID)
headers = {
'Accept': 'application/json'
}
response = requests.get(url, headers=headers)
# Check the response status
if response.status_code == 200:
# Do something with the response data (e.g., print it)
print(i)
# print(response.json())
else:
# Print an error message if the request was not successful
print(f"Error: {response.status_code} - {response.text}")
This code stops me from hitting the API after 1 second, but I also want to limit it based on one minute and 30 minutes as well.
FYI: my code hits 25 requests in a second, that means after 10 seconds, my per limit rate would hit. That means my code should stop for about 50 seconds to full fill the per min limit.
Do I have to make multiple calls using ratelimit
?
Issues:
Single-Level Rate Limit or rate limiting : Your current implementation with @limits(calls=SEC_CALLS, period=SEC_RATE_LIMIT)
only enforces a limit on the number of requests per second. If you make continuous requests, you might exceed the minute and half-hour limits.
Perhaps there is an accumulation of requests: For example in your case you are sending 25 requests per second, you will hit the per/min limit (250 requests) in 10 seconds or less.
The current setup wouldn't stop further requests when this limit is hit, so you risk exceeding the minute or 30-mins rate limits without additional checks.
Possible solution:
Try enforcing multiple rate limits simultaneously, you need to account for either p/second, p/minute, or p/30-minute limits.
A possible solution would be to stack multiple @limits
decorators or using custom logic to track requests across different time windows.
But how would you track it quite tedious...
for example
@sleep_and_retry
@limits(calls=HOUR_CALLS, period=HOUR_RATE_LIMIT)
@sleep_and_retry
@limits(calls=MIN_CALLS, period=MIN_RATE_LIMIT)
@sleep_and_retry
@limits(calls=SEC_CALLS, period=SEC_RATE_LIMIT)
def check_limit():
print(f'Time: {time.time()}'
OR
Alternatively use tenacity
instead, just because it implements those aforementioned issues
I mentioned earlier...
For example:
from tenacity import retry, stop_after_attempt, wait_random_exponential
@retry(
reraise=True,
wait=wait_random_exponential(min=0.1, max=10),
stop=stop_after_attempt(3),
)
def check_limit(...):
.... your code