API¶
Rate Limits¶
Rate Limit Granularities¶
- class freiner.limits.RateLimitItem(amount: int, multiples: int = 1, namespace: str = 'LIMITER')[source]¶
Bases:
objectdefines a Rate limited resource which contains the characteristic namespace, amount and granularity multiples of the rate limiting window.
- Parameters
- Return type
None
- class freiner.limits.RateLimitItemPerYear(amount: int, multiples: int = 1, namespace: str = 'LIMITER')[source]¶
Bases:
freiner.limits.RateLimitItemPer year rate limited resource.
- class freiner.limits.RateLimitItemPerMonth(amount: int, multiples: int = 1, namespace: str = 'LIMITER')[source]¶
Bases:
freiner.limits.RateLimitItemPer month rate limited resource.
- class freiner.limits.RateLimitItemPerDay(amount: int, multiples: int = 1, namespace: str = 'LIMITER')[source]¶
Bases:
freiner.limits.RateLimitItemPer day rate limited resource.
- class freiner.limits.RateLimitItemPerHour(amount: int, multiples: int = 1, namespace: str = 'LIMITER')[source]¶
Bases:
freiner.limits.RateLimitItemPer hour rate limited resource.
Utility Methods¶
- freiner.parse(limit_string: str) freiner.limits.RateLimitItem[source]¶
Parses a single rate limit in string notation (e.g. ‘1/second’ or ‘1 per second’).
# noqa: DAR402
- Parameters
limit_string (str) – The rate limit string. using Rate Limit String Notation.
- Raises
TypeError – If something other than a string was supplied.
ValueError – If the string notation is invalid.
- Returns
An instance of
freiner.limits.RateLimitItem.- Return type
- freiner.parse_many(limit_string: str) Sequence[freiner.limits.RateLimitItem][source]¶
Parses rate limits in string notation containing multiple rate limits (e.g. ‘1/second; 5/minute’).
- Parameters
limit_string (str) – The rate limit string. using Rate Limit String Notation.
- Raises
TypeError – If something other than a string was supplied.
ValueError – If the string notation is invalid.
- Returns
A sequence of
freiner.limits.RateLimitIteminstances.- Return type
Strategies¶
- class freiner.strategies.RateLimiter(*args, **kwargs)[source]¶
Bases:
Protocol- hit(item: freiner.limits.RateLimitItem, *identifiers: Any) bool[source]¶
Creates a hit on the rate limit and returns
Trueif successful.# noqa: DAR202
- Parameters
item (freiner.limits.RateLimitItem) – A
freiner.limits.RateLimitIteminstance.identifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Returns
Trueif the request was successful, orFalseif the rate limit had been exceeded.- Return type
- test(item: freiner.limits.RateLimitItem, *identifiers: Any) bool[source]¶
Checks the rate limit and returns
Trueif it is not currently exceeded.# noqa: DAR202
- Parameters
item (freiner.limits.RateLimitItem) – A
freiner.limits.RateLimitIteminstance.identifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Returns
Trueif the rate limit has not yet been exceeded, orFalseif it has.- Return type
- get_window_stats(item: freiner.limits.RateLimitItem, *identifiers: Any) freiner.strategies.WindowStats[source]¶
Retrieve statistics about the number of requests remaining within the given limit.
# noqa: DAR202
- Parameters
item (freiner.limits.RateLimitItem) – A
freiner.limits.RateLimitIteminstance.identifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Returns
tuple (reset time (float), remaining (int))
- Return type
- clear(item: freiner.limits.RateLimitItem, *identifiers: Any) None[source]¶
Resets the request counter for a given limit to zero.
- Parameters
item (freiner.limits.RateLimitItem) – a
freiner.limits.RateLimitIteminstanceidentifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Return type
None
- class freiner.strategies.WindowStats(reset_time, remaining_count)[source]¶
Bases:
tupleCreate new instance of WindowStats(reset_time, remaining_count)
- class freiner.strategies.fixed_window.FixedWindowRateLimiter(storage: freiner.storage.FixedWindowStorage)[source]¶
Bases:
objectReference: Fixed Window
- Parameters
storage (freiner.storage.FixedWindowStorage) –
- Return type
None
- hit(item: freiner.limits.RateLimitItem, *identifiers: Any) bool[source]¶
Creates a hit on the rate limit and returns
Trueif successful.- Parameters
item (freiner.limits.RateLimitItem) – A
freiner.limits.RateLimitIteminstance.identifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Returns
Trueif the request was successful, orFalseif the rate limit had been exceeded.- Return type
- test(item: freiner.limits.RateLimitItem, *identifiers: Any) bool[source]¶
Checks the rate limit and returns
Trueif it is not currently exceeded.- Parameters
item (freiner.limits.RateLimitItem) – A
freiner.limits.RateLimitIteminstance.identifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Returns
Trueif the rate limit has not yet been exceeded, orFalseif it has.- Return type
- get_window_stats(item: freiner.limits.RateLimitItem, *identifiers: Any) freiner.strategies.WindowStats[source]¶
Returns the number of requests remaining within this limit.
- Parameters
item (freiner.limits.RateLimitItem) – a
freiner.limits.RateLimitIteminstanceidentifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Returns
tuple (reset time (float), remaining (int))
- Return type
- clear(item: freiner.limits.RateLimitItem, *identifiers: Any) None[source]¶
Resets the request counter for a given limit to zero.
- Parameters
item (freiner.limits.RateLimitItem) – a
freiner.limits.RateLimitIteminstanceidentifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Return type
None
- class freiner.strategies.fixed_window_elastic.FixedWindowElasticExpiryRateLimiter(storage: freiner.storage.FixedWindowStorage)[source]¶
Bases:
freiner.strategies.fixed_window.FixedWindowRateLimiterReference: Fixed Window with Elastic Expiry
- Parameters
storage (freiner.storage.FixedWindowStorage) –
- Return type
None
- hit(item: freiner.limits.RateLimitItem, *identifiers: Any) bool[source]¶
Creates a hit on the rate limit and returns
Trueif successful.- Parameters
item (freiner.limits.RateLimitItem) – A
freiner.limits.RateLimitIteminstance.identifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Returns
Trueif the request was successful, orFalseif the rate limit had been exceeded.- Return type
- class freiner.strategies.moving_window.MovingWindowRateLimiter(storage: freiner.storage.MovingWindowStorage)[source]¶
Bases:
objectReference: Moving Window
- Parameters
storage (freiner.storage.MovingWindowStorage) –
- Return type
None
- hit(item: freiner.limits.RateLimitItem, *identifiers: Any) bool[source]¶
Creates a hit on the rate limit and returns
Trueif successful.- Parameters
item (freiner.limits.RateLimitItem) – A
freiner.limits.RateLimitIteminstance.identifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Returns
Trueif the request was successful, orFalseif the rate limit had been exceeded.- Return type
- test(item: freiner.limits.RateLimitItem, *identifiers: Any) bool[source]¶
Checks the rate limit and returns
Trueif it is not currently exceeded.- Parameters
item (freiner.limits.RateLimitItem) – A
freiner.limits.RateLimitIteminstance.identifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Returns
Trueif the rate limit has not yet been exceeded, orFalseif it has.- Return type
- get_window_stats(item: freiner.limits.RateLimitItem, *identifiers: Any) freiner.strategies.WindowStats[source]¶
Returns the number of requests remaining within this limit.
- Parameters
item (freiner.limits.RateLimitItem) – a
freiner.limits.RateLimitIteminstanceidentifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Returns
tuple (reset time (float), remaining (int))
- Return type
- clear(item: freiner.limits.RateLimitItem, *identifiers: Any) None[source]¶
Resets the request counter for a given limit to zero.
- Parameters
item (freiner.limits.RateLimitItem) – a
freiner.limits.RateLimitIteminstanceidentifiers (Any) – A variable list of stringable objects to uniquely identify the limit.
- Return type
None
Storage¶
Storage Protocol Classes¶
- class freiner.storage.FixedWindowStorage(*args, **kwargs)[source]¶
Bases:
Protocol- incr(key: str, expiry: int, elastic_expiry: bool = False) int[source]¶
Increments the counter for the given rate limit key.
# noqa: DAR202
- class freiner.storage.MovingWindow(start_time, acquired_count)[source]¶
Bases:
tupleCreate new instance of MovingWindow(start_time, acquired_count)
- class freiner.storage.MovingWindowStorage(*args, **kwargs)[source]¶
Bases:
Protocol- acquire_entry(key: str, limit: int, expiry: int, no_add: bool = False) bool[source]¶
- Parameters
- Return type
Backend Implementations¶
In-Memory¶
- class freiner.storage.memory.MemoryStorage[source]¶
Bases:
objectrate limit storage using
collections.Counteras an in memory storage for fixed and elastic window strategies, and a simple list to implement moving window strategy.- Return type
None
- incr(key: str, expiry: int, elastic_expiry: bool = False) int[source]¶
Increments the counter for the given rate limit key.
- clear(key: str) None[source]¶
Resets the rate limit for the given key.
- Parameters
key (str) – The key to clear rate limits for.
- Return type
None
- acquire_entry(key: str, limit: int, expiry: int, no_add: bool = False) bool[source]¶
- Parameters
- Return type
Redis¶
- class freiner.storage.redis.RedisStorage(client: redis.client.Redis)[source]¶
Bases:
freiner.storage.redis.RedisInteractorRate limit storage with redis as backend.
Depends on the redis library.
- Parameters
client (redis.client.Redis) –
- Return type
None
- classmethod from_uri(uri: str, **options: Any) freiner.storage.redis.RedisStorage[source]¶
- Parameters
uri (str) – URI of the form redis://[:password]@host:port, redis://[:password]@host:port/db, rediss://[:password]@host:port, unix:///path/to/sock etc. This uri is passed directly to
redis.from_url().options (Any) – All remaining keyword arguments are passed directly to the constructor of
redis.Redis.
- Return type
- incr(key: str, expiry: int, elastic_expiry: bool = False) int[source]¶
Increments the counter for the given rate limit key.
- clear(key: str) None[source]¶
Resets the rate limit for the given key.
- Parameters
key (str) – The key to clear rate limits for.
- Return type
None
- acquire_entry(key: str, limit: int, expiry: int, no_add: bool = False) bool[source]¶
- Parameters
- Return type
- reset() None[source]¶
This function calls a Lua Script to delete keys prefixed with ‘LIMITER’ in blocks of 5000.
Warning
This operation was designed to be fast, but was not tested on a large production based system. Be careful with its usage as it could be slow on very large data sets.
- Return type
None
Redis Sentinel¶
- class freiner.storage.redis_sentinel.RedisSentinelStorage(sentinel: redis.sentinel.Sentinel, service_name: str)[source]¶
Bases:
freiner.storage.redis.RedisStorageRate limit storage with redis sentinel as backend.
Depends on redis library.
- Parameters
sentinel (redis.sentinel.Sentinel) –
service_name (str) –
- Return type
None
- classmethod from_uri(uri: str, service_name: Optional[str] = None, **options: Any) freiner.storage.redis_sentinel.RedisSentinelStorage[source]¶
- Parameters
uri (str) – URI of the form redis+sentinel://host:port,host:port/service_name
service_name (Optional[str]) – Sentinel service name (if not provided in uri).
options (Any) – All remaining keyword arguments are passed directly to the constructor of
redis.sentinel.Sentinel.
- Raises
FreinerConfigurationError – When no service name is provided.
- Return type
Redis Cluster¶
- class freiner.storage.redis_cluster.RedisClusterStorage(client: redis.client.Redis)[source]¶
Bases:
freiner.storage.redis.RedisStorageRate limit storage with redis cluster as backend.
Depends on redis-py-cluster library.
- Parameters
client (redis.client.Redis) –
- Return type
None
- classmethod from_uri(uri: str, **options: Any) freiner.storage.redis_cluster.RedisClusterStorage[source]¶
- Parameters
- Return type
- reset() None[source]¶
Redis Clusters are sharded and deleting across shards can’t be done atomically. Because of this, this reset loops over all keys that are prefixed with ‘LIMITER’ and calls delete on them, one at a time.
Warning
This operation was not tested with extremely large data sets. On a large production based system, care should be taken with its usage as it could be slow on very large data sets.
- Return type
None
Memcached¶
- class freiner.storage.memcached.MemcachedStorage(client: Union[pymemcache.client.base.Client, pymemcache.client.base.PooledClient, pymemcache.client.hash.HashClient])[source]¶
Bases:
objectRate limit storage with memcached as backend.
Depends on the pymemcache library.
- Parameters
client (Union[pymemcache.client.base.Client, pymemcache.client.base.PooledClient, pymemcache.client.hash.HashClient]) –
- Return type
None
- classmethod from_uri(uri: str, **options: Any) freiner.storage.memcached.MemcachedStorage[source]¶
- Parameters
uri (str) – URI of the form memcached://host:port,host:port`or `memcached:///run/path/to/sock.
options (Any) – All remaining keyword arguments are passed directly to the constructor of
pymemcache.client.base.Client.
- Raises
FreinerConfigurationError – When no hosts could be parsed from the supplied URI.
- Return type
- clear(key: str) None[source]¶
Resets the rate limit for the given key.
- Parameters
key (str) – The key to clear rate limits for.
- Return type
None
- incr(key: str, expiry: int, elastic_expiry: bool = False) int[source]¶
Increments the counter for the given rate limit key.