A token bucket smooths traffic. Many APIs instead promise "at most N requests in any 60-second window": a sliding window log.
Implement SlidingWindowLimiter(limit, window, clock=time.monotonic):
allow(user): record and allow the request if the user made fewer than limit allowed requests in the last window seconds (timestamps t with now - t < window). Rejected requests aren't recorded.retry_after(user): seconds until the user can make another request (0 if they can now).deque of timestamps per user, dropping expired ones from the left.