Last active
October 22, 2023 01:09
-
-
Save zinthose/d11a9fc5d26eed9bbd5cade10a768f96 to your computer and use it in GitHub Desktop.
Simple Rate Limiter Decorator for Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I did some tests, it appears to be thread-safe... neat.