TokenBucket rate limiter with bursts
Python
"""Token-bucket limiter: short bursts allowed, steady average rate enforced."""
import threading
import time
class TokenBucket:
"""Allow bursts up to capacity while refilling at rate tokens/second."""
def __init__(self, rate: float, capacity: float = 1.0) -> None:
if rate <= 0 or capacity <= 0:
raise ValueError("rate and capacity must be positive")
self.rate = rate
self.capacity = float(capacity)
self._tokens = self.capacity # start full so the first burst is free
self._updated = time.monotonic()
self._lock = threading.Lock()
def _refill(self) -> None:
now = time.monotonic()
elapsed = now - self._updated
self._tokens = min(self.capacity, self._tokens + elapsed * self.rate)
self._updated = now
def try_acquire(self, tokens: int = 1) -> bool:
"""Consume tokens if available; never blocks, returns success."""
with self._lock:
self._refill()
if self._tokens < tokens:
return False
self._tokens -= tokens
return True
def wait_time(self, tokens: int = 1) -> float:
"""Seconds until tokens fit, or 0.0 when they fit right now."""
with self._lock:
self._refill()
return max(0.0, (tokens - self._tokens) / self.rate)