Search code examples
pythondecoratorrate-limiting

How to recall function's decorators from the decorator itself in python


I have a decorator that I use to rate limit api requests, but instead of ignore the requests, I want to retry them after some time wait.

The decorator logic is the following:

def rate_limiter(self, func: Callable):
    @wraps(func)
    def wrapper(*args, **kwargs):
        if is_request_allowed():
            LOGGER.info('Request allowed')
            return func(*args, **kwargs)
        else:
            LOGGER.info('Request not allowed')
            # sleep(reasonable_amount_of_time)
            # retry_function_with_decorator()
    return wrapper

The "allowed" part of the decorator works fine, but the "retry_function_with_decorator()" from the decorator itself is where I'm stuck with.

I have tried to pass the function object to another function and call it from there but it executes the decorated function directly, not the wrapper.

Is this something possible? I'm missing something? or there is a better approach?

Thank you in advance.


Solution

  • Given your current definition, you could just call wrapper recursively.

    def rate_limiter(self, func: Callable):
        @wraps(func)
        def wrapper(*args, **kwargs):
            if is_request_allowed():
                LOGGER.info('Request allowed')
                return func(*args, **kwargs)
            else:
                LOGGER.info('Request not allowed')
                # sleep(reasonable_amount_of_time)
                return wrapper(*args, **wargs)
        return wrapper
    

    However, a simple while loop would be better.

    def rate_limiter(self, func: Callable):
        @wraps(func)
        def wrapper(*args, **kwargs):
            while not is_request_allowed():
                LOGGER.info('Request not allowed')
                # sleep(reasonable_amount_of_time)
            LOGGER.info('Request allowed')
            return func(*args, **kwargs)
        return wrapper