跳转至

快速开始

Note

在异步上下文中,只需将 limits 的导入替换为 limits.aio,并在存储和限制器方法中使用 await

初始化策略和存储

初始化存储后端

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")

初始化速率限制器

from limits import strategies
limiter = strategies.FixedWindowRateLimiter(limits_storage)

Warning

如果使用的存储不支持移动窗口策略,将会抛出 NotImplementedError 异常

from limits import strategies
limiter = strategies.MovingWindowRateLimiter(limits_storage)

Warning

如果使用的存储不支持滑动窗口计数器策略,将会抛出 :exc:NotImplementedError 异常

from limits import strategies
limiter = strategies.SlidingWindowCounterRateLimiter(limits_storage)

描述速率限制

使用字符串表示法初始化速率限制

from limits import parse
one_per_minute = parse("1/minute")

使用 RateLimitItem 子类显式初始化速率限制

from limits import RateLimitItemPerSecond
one_per_second = RateLimitItemPerSecond(1, 1)

测试限制

消耗限制

>>> 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

检查而不消耗

>>> 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

查询可用容量和重置时间

>>> 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

清除限制

>>> 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