Store

A store is the lowest level implementation of rate limits, it manages all the resources and resetting of the buckets/keys when they expire. It can be said that uprate’s complete performance is majorly dependent on stores, hence using a fast store will lower the ratelimit overhead introduced by uprate.

Uprate already provides some in-memory stores. More stores targetting different technologies like redis, SQL etc. are planned be added in future as of now. You are encouraged to write your own store and publish it or to contribute it to uprate, we will gladly accept store implementations.

class uprate.store.BaseStore(*args, **kwargs)[source]

Bases: Protocol[uprate.store.T]

A protocol defining the design of async stores. This is generic in TypeVar uprate.store.T which is unbound and unconstrained.

Subclasses implementing this protocol should inherit from this class.

limit

The RateLimit to which this store is bound to.

Type

uprate.ratelimit.RateLimit

setup(ratelimit: RateLimit)[source]

Adds the ratelimit that this store is bound to as an attribute under BaseStore.limit. This method exists only to create a circular reference between the store and ratelimit. uprate.ratelimit.RateLimit.rates attribute allows the store to access all implemented rates.

Parameters

ratelimit (uprate.ratelimit.RateLimit) – The ratelimit which this store is bound to.

abstract async acquire(key: T) tuple[bool, float, Optional[Rate]][source]

Try to acquire a usage token for given key.

Note

To get all the rates that this key follows use

self.limit.rates

Note

If a HashMap like data-structure is being nested, then it’s best that it is nested by the rates instead of the keys, since the number of keys may not exceed 1 in most cases, while the number of keys could grow upto 100k or more fairly quickly.

Parameters

key (uprate.store.T) – The key to acquire a ratelimit for.

Returns

A three element tuple, the first element of type bool depicting success.

Second element float which is the amount of time to retry in, If a usage token was acquired this should return 0 other-wise the time in which a usage token will be available. If the store does not support retry time then it should return a negative value like -1 (negative values shall be returned only on failure if the retry time cannot be determined).

The last element is the uprate.rate.Rate object which was violated, this must be the rate which will take the longest to reset. The last element is expected to be None if acquiring was successfull.

Return type

tuple[bool, float, Rate | None]

abstract async reset(key: uprate.store.T) None[source]

Reset the usage tokens for given key. Implementation wise, deleting all the records for the given key should be enough.

Parameters

key (uprate.store.T) – The key to acquire a ratelimit for.

abstract async clear() None[source]

Reset all the keys in the store.

class uprate.store.MemoryStore[source]

Bases: uprate.store.BaseStore[uprate.store.H]

An implementation of BaseStore protocol. This implementation uses dict and ejects stale buckets/keys periodically only when MemoryStore.acquire() is called.

This is a generic in TypeVar H

limit

The RateLimit to which this store is bound to.

Type

uprate.ratelimit.RateLimit

Sync Store

class uprate._sync.SyncStore(*args, **kwargs)[source]

Bases: Protocol[uprate.store.T]

setup(ratelimit: uprate._sync.SyncRateLimit)[source]

Same as uprate.store.BaseStore.setup()

abstract acquire(key: T) tuple[bool, float, Rate | None][source]

Sync version of uprate.store.BaseStore.acquire()

abstract reset(key: uprate.store.T) None[source]

Sync version of uprate.store.BaseStore.reset()

abstract clear() None[source]

Sync version of uprate.store.BaseStore.clear()

class uprate._sync.SyncMemoryStore[source]

Bases: uprate._sync.SyncStore[uprate.store.H]

An implementation of SyncStore protocol, hence is also the sync version of MemoryStore

This implementation uses dict and ejects stale buckets/keys periodically only when SyncMemoryStore.acquire() is called.

This is a generic in TypeVar H

limit

The RateLimit to which this store is bound to.

Type

uprate.ratelimit.RateLimit