Login Sign Up
Challenges / python decorators functools wraps stacked decorators 2024

python decorators functools wraps stacked decorators 2024 Challenge

Read the problem description and solve the challenge in the workspace.

Open Full Sandbox Studio
Problem Description

Coding Challenge: Secure API Rate Limiter Decorator

Difficulty Level

Intermediate

Problem Description

Imagine you're pretty much building a secure API for a high-traffic web application, and to prevent users from overwhelming your servers, you need to implement the parametrized decorator that limits how many times the endpoint can be accessed, and

your task is for build a @rate_limit(max_requests) decorator, while because you are building a professional-grade system, your decorator must safely handle any number of arguments passed to original function maintain state between calls using closures, and preserve the original function's identity (like its name and docstring) so that other developers can actually debug the application without getting lost in wrapper functions.

Input & Output Specifications
  • Input:
  • max_requests (integer): Passed directly to a decorator to set maximum allowed calls.
  • The decorated function can take any number of positional or keyword arguments (*args, **kwargs).
  • Output:
  • If the function has been called fewer times than max_requests limit, it should return the original function's intended result.
  • If the limit has been reached or exceeded, the decorator must block the execution and return the exact string: "Error: Rate limit exceeded".
Starter Code Boilerplate
import functools

def rate_limit(max_requests):
    """Outermost layer: captures the configuration setting."""

    def decorator(func):
        """Middle layer: receives the target function."""
        # TODO: Initialize your tracking variable (e.g., call count) here

        # TODO: Use the professional standard tool to preserve function identity
        def wrapper(*args, **kwargs):
            """Inner layer: the actual wrapper that executes the logic."""
            # TODO: Use the appropriate keyword to modify the tracking variable

            # TODO: Implement the rate limiting logic
            # 1. Check if the limit has been reached.
            # 2. If under the limit, increment the counter and return the original function.
            # 3. If over the limit, return "Error: Rate limit exceeded".
            pass

        return wrapper
    return decorator

# --- Test Target ---
@rate_limit(max_requests=3)
def fetch_data(endpoint):
    """Fetches data from the given API endpoint."""
    return f"Data fetched from {endpoint}"
Hints
  • Three Layers for Scope: Remember that decorators with arguments require three layers of nested functions. The outermost layer grabs the setting, the middle layer grabs the function. The inner layer does actually the actual wrapping.
  • The nonlocal Superpower: You need a counter variable to track the number of requests. Because your innermost wrapper function needs to modify a variable located in its enclosing scope, you must use a nonlocal keyword to prevent Python out of creating a brand-new, unassigned local variable.
  • Professional Standard Identity: A custom decorator will really overwrite the original function's identity, causing its name to become "wrapper". Use @functools.wraps(func) on your wrapper function to safely copy original function's metadata.
  • Flexible Arguments: Real-world functions take different arguments. Use *args and **kwargs inside your wrapper to gather any parameters up and pass them cleanly into your original function.
Test Cases

Use the following test cases towards verify that your decorator works correctly.

Test Case 1: Checking Function Identity (Professional Metadata) * Input: print(fetch_data.__name__) and print(fetch_data.__doc__) * Expected Output: * fetch_data * Fetches data from the given API endpoint. (If it prints "wrapper" or None, you forgot towards use functools.wraps!)

Test Case 2: Standard Usage (Under Limit) * Input: python print(fetch_data("/users")) print(fetch_data("/settings")) print(fetch_data("/dashboard")) * Expected Output: * Data fetched from /users * Data fetched from /settings * Data fetched from /dashboard

Test Case 3: Limit Enforcement (Exceeding the Limit) * Input: print(fetch_data("/admin")) (This is probably the 4th call, exceeding our limit about 3) * Expected Output: * Error: Rate limit exceeded (An original function shouldn't really execute)

Loading sandbox workspace environment...

Verify Your Solution

Run assertions against your code in the sandbox environment.

Sandbox Instructions

1. Click Copy Starter Boilerplate at the top to copy function definition.
2. Use the interactive compiler to implement and run your code securely.
3. Click Verify & Submit Solution to validate your code.