w3resource

Implementing a Python decorator for function rate limits

Python Decorator: Exercise-7 with Solution

Write a Python program that implements a decorator to enforce rate limits on a function.

Sample Solution:

Python Code:

import time

def rate_limits(max_calls, period):
    def decorator(func):
        calls = 0
        last_reset = time.time()

        def wrapper(*args, **kwargs):
            nonlocal calls, last_reset

            # Calculate time elapsed since last reset
            elapsed = time.time() - last_reset

            # If elapsed time is greater than the period, reset the call count
            if elapsed > period:
                calls = 0
                last_reset = time.time()

            # Check if the call count has reached the maximum limit
            if calls >= max_calls:
                raise Exception("Rate limit exceeded. Please try again later.")

            # Increment the call count
            calls += 1

            # Call the original function
            return func(*args, **kwargs)

        return wrapper
    return decorator

# Maximum 6 API calls are permitted.
@rate_limits(max_calls=6, period=10)
def api_call():
    print("API call executed successfully...")

# Make API calls
for _ in range(8):
    try:
        api_call()
    except Exception as e:
        print(f"Error occurred: {e}")

Sample Output:

API call executed successfully...
API call executed successfully...
API call executed successfully...
API call executed successfully...
API call executed successfully...
API call executed successfully...
Error occurred: Rate limit exceeded. Please try again later.
Error occurred: Rate limit exceeded. Please try again later.

Explanation:

In the above exercise -

  • The rate_limits decorator is defined with two parameters: max_calls and period. It limits the number of function calls within a specified time period.
  • Inside the decorator, a "calls" counter and a last_reset timestamp are initialized to keep track of the number of calls made and the last time the counter was reset.
  • The wrapper function is defined inside the decorator and is responsible for enforcing the rate limit and calling the original function.
  • Inside the wrapper function, the elapsed time since the last reset is calculated.
  • If the elapsed time is longer than the specified period, the "calls" counter is reset to 0, and the last_reset timestamp is updated to the current time.
  • The current call count is checked against the maximum limit specified by max_calls. If the limit is exceeded, an exception is raised.
  • If the call count is within the limit, the counter is incremented, and the original function is called.
  • Finally, the wrapper function returns the decorator result.
  • The api_call function is decorated using @rate_limits(max_calls=6, period=10) syntax, indicating that a maximum of 6 API calls are allowed within a 10-second period.
  • In the example code, a loop makes 8 API calls. The first 6 calls execute successfully, but the 7th and 8th calls raise an exception indicating that the rate limit has been exceeded.

Flowchart:

Flowchart: Python - Implementing a Python decorator for function rate limits.
Flowchart: Python - Implementing a Python decorator for function rate limits.

Have another way to solve this solution? Contribute your code (and comments) through Disqus.

Previous: Implementing a Python decorator for function retry.
Next: Implementing a Python decorator for function logging.

What is the difficulty level of this exercise?

Test your Programming skills with w3resource's quiz.



Follow us on Facebook and Twitter for latest update.