Skip to content

Instantly share code, notes, and snippets.

@zinthose
Last active October 22, 2023 01:09
Show Gist options
  • Save zinthose/d11a9fc5d26eed9bbd5cade10a768f96 to your computer and use it in GitHub Desktop.
Save zinthose/d11a9fc5d26eed9bbd5cade10a768f96 to your computer and use it in GitHub Desktop.
Simple Rate Limiter Decorator for Python
import time
def rate_limit(sec: float = 0):
"""Rate limit a function by number of seconds between calls.
Rate is time passage aware so if the last call was over the limiter, then the next call will be immediate.
Additionally if the time past since the last call was half the time limit, then the next call will be delayed
by half the time limit.
### Examples:
```python
>>> @rate_limit(2)
... def foo():
... print("bar")
...
>>> foo()
bar
>>> foo()
bar
"""
last_call = None
def decorator(func):
def wrapper(*args, **kwargs):
nonlocal last_call
if last_call is not None:
time_since_last_call = time.time() - last_call
if time_since_last_call < sec:
time.sleep(sec - time_since_last_call)
last_call = time.time()
return func(*args, **kwargs)
return wrapper
return decorator
def _test():
import doctest
doctest.testmod()
if __name__ == "__main__":
_test()
@zinthose
Copy link
Author

I did some tests, it appears to be thread-safe... neat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment