Real limiters don't throttle everyone together. They throttle each client, API key, or IP independently. Wrap any limiter strategy in a keyed limiter that lazily creates one limiter per key.
Implement KeyedRateLimiter:
__init__(factory): factory is a zero-arg callable that returns a fresh limiter (e.g. lambda: TokenBucket(5, 1, clock))allow(key): get or create the limiter for key, then delegate to its allow()Each key gets its own independent budget. FixedWindowLimiter is provided so your tests can build a factory.
import time
class FixedWindowLimiter:
def __init__(self, limit, window, clock=time.time):
self.limit = limit
self.window = window
self.clock = clock
self._window_index = None
self._count = 0
def allow(self):
index = int(self.clock() // self.window)
if index != self._window_index:
self._window_index = index
self._count = 0
if self._count < self.limit:
self._count += 1
return True
return False
class KeyedRateLimiter:
def __init__(self, factory):
self.factory = factory # zero-arg callable -> a new limiter
self._limiters = {}
def allow(self, key):
"""Get or create the limiter for the key, then delegate to its allow()."""
# TODO: find this key's limiter in self._limiters, minting one from
# self.factory() the first time a key shows up, then let that limiter
# answer allow() and pass its verdict straight through. The factory
# should run once per distinct key and never on a repeat call.
pass
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
Real limiters don't throttle everyone together. They throttle each client, API key, or IP independently. Wrap any limiter strategy in a keyed limiter that lazily creates one limiter per key.
Implement KeyedRateLimiter:
__init__(factory): factory is a zero-arg callable that returns a fresh limiter (e.g. lambda: TokenBucket(5, 1, clock))allow(key): get or create the limiter for key, then delegate to its allow()Each key gets its own independent budget. FixedWindowLimiter is provided so your tests can build a factory.
Press Run Tests or ββ© to check your solution.