Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rate-limiting python decorator

I found this rate-limiting python decorator based on redis classes. How can I write a similar decorator that uses only what's available in the standard library that can be used as follows?

def ratelimit(limit, every):
    # 🐍 python magic 🐍

@ratelimit(limit=1, every=2)
def printlimited(x):
    print x

# print one number every two seconds
for x in range(10):
    printlimited(x)

There are other answers on stackoverflow but they do not allow to specify the denominator.

like image 617
enrico.bacis Avatar asked Jun 18 '15 14:06

enrico.bacis


People also ask

What is a rate limiter Python?

Rate Limiting is a way to limit the number of requests within a specific period. It is super helpful when you have many requests and want to reduce load.

What is rate limiting in REST API?

Rate-limiting is used to prevent users overwhelming your API with requests, limiting denial of service threats. Encryption ensures that data is kept confidential when sent to or from the API and when stored on disk, preventing information disclosure. Modern encryption also prevents data being tampered with.


1 Answers

You can use a threading.Semaphore to count and block the requests that are exceeding the limit, in combination with threading.Timer to schedule a function that releases the semaphore.

from threading import Semaphore, Timer
from functools import wraps

def ratelimit(limit, every):
    def limitdecorator(fn):
        semaphore = Semaphore(limit)
        @wraps(fn)
        def wrapper(*args, **kwargs):
            semaphore.acquire()
            try:
                return fn(*args, **kwargs)
            finally:                    # don't catch but ensure semaphore release
                timer = Timer(every, semaphore.release)
                timer.setDaemon(True)   # allows the timer to be canceled on exit
                timer.start()
        return wrapper
    return limitdecorator

I extended this idea and published a library on PyPI named limit.

like image 71
enrico.bacis Avatar answered Oct 11 '22 10:10

enrico.bacis