Quickstart¶
Note
In an async context, simply substitute the imports
from limits to limits.aio and use await in
the storage and limiter methods.
Initialize the strategy & storage¶
Initialize the storage backend¶
from limits import storage
limits_storage = storage.MemoryStorage()
from limits import storage
limits_storage = storage.MemcachedStorage(
"memcached://localhost:11211"
)
from limits import storage
limits_storage = storage.RedisStorage("redis://localhost:6379/1")
Initialize a rate limiter¶
from limits import strategies
limiter = strategies.FixedWindowRateLimiter(limits_storage)
Caution
If the storage used does not support the moving window
strategy, NotImplementedError will be raised
from limits import strategies
limiter = strategies.MovingWindowRateLimiter(limits_storage)
Caution
If the storage used does not support the sliding window
counter strategy, NotImplementedError will be raised
from limits import strategies
limiter = strategies.SlidingWindowCounterRateLimiter(limits_storage)
Describe the rate limit¶
Initialize a rate limit using the string notation¶
from limits import parse
one_per_minute = parse("1/minute")
Initialize a rate limit explicitly using a subclass of RateLimitItem¶
from limits import RateLimitItemPerSecond
one_per_second = RateLimitItemPerSecond(1, 1)
Test the limits¶
Consume the limits¶
>>> limiter.hit(one_per_minute, "test_namespace", "foo")
True
>>> limiter.hit(one_per_minute, "test_namespace", "foo")
False
>>> limiter.hit(one_per_minute, "test_namespace", "bar")
True
>>> limiter.hit(one_per_second, "test_namespace", "foo")
True
>>> limiter.hit(one_per_second, "test_namespace", "foo")
False
>>> time.sleep(1)
>>> limiter.hit(one_per_second, "test_namespace", "foo")
True
Check without consuming¶
>>> limiter.hit(one_per_second, "test_namespace", "foo")
True
>>> while not limiter.test(one_per_second, "test_namespace", "foo"):
... time.sleep(0.01)
>>> limiter.hit(one_per_second, "test_namespace", "foo")
True
Query available capacity and reset time¶
>>> limiter.hit(one_per_minute, "test_namespace", "foo")
True
>>> window = limiter.get_window_stats(one_per_minute, "test_namespace", "foo")
>>> window.remaining
0
>>> limiter.hit(one_per_minute, "test_namespace", "foo")
False
>>> time.sleep(window.reset_time - time.time())
>>> limiter.hit(one_per_minute, "test_namespace", "foo")
True
Clear a limit¶
>>> limiter.hit(one_per_minute, "test_namespace", "foo")
True
>>> limiter.hit(one_per_minute, "test_namespace", "foo")
False
>>> limiter.clear(one_per_minute, "test_namespace", "foo")
>>> limiter.hit(one_per_minute, "test_namespace", "foo")
True
Rate limit string notation¶
Instead of manually constructing instances of RateLimitItem
you can instead use the following Parsing functions.
These functions accept rate limits specified as strings following the format:
[count] [per|/] [n (optional)] [second|minute|hour|day|month|year]
You can combine rate limits by separating them with a delimiter of your choice.
Examples¶
10 per hour10/hour10/hour;100/day;2000 per year100/day, 500/7days