Search code examples
pythonpython-3.xpython-decoratorsthrottlingrate-limiting

How to apply rate limit based on method parameter


I'm using the python module ratelimit to throttle a function, which calls a rest api, I need to apply throttle based on the method of the requests, e.g. for PUT/POST/DELETE 1 per 10s, for GET 5 per 1s, how can I achieve this without breaking the function into two?

from ratelimit import limits, sleep_and_retry

@sleep_and_retry
@limits(calls=1 if method != 'GET' else 5, period=10 if method != 'GET' else 1)
def callrest(method, url, data):
    ...

Is it possible to do this?


Solution

  • You don't have to re-invent the wheel by creating your own rate limiter when ratelimit already works well.

    To apply different rate limits based on the method argument passed in, make a decorator that creates two ratelimit.limits-decorated functions from the given function--one decorated with arguments needed by the GET method, and the other decorated with those needed by non-GET methods. Then make the decorator return a wrapper function that calls one of the two decorated functions above according to the value of the method argument:

    from ratelimit import limits, sleep_and_retry
    
    def limits_by_method(func):
        def wrapper(method, *args, **kwargs):
            return (get if method == 'GET' else non_get)(method, *args, **kwargs)
        get = limits(calls=5, period=1)(func)
        non_get = limits(calls=1, period=10)(func)
        return wrapper
    
    @sleep_and_retry
    @limits_by_method
    def callrest(method, url, data):
        ...
    

    Demo: https://replit.com/@blhsing/ExoticWretchedAdvance