Rush’s Storage Backends

By default, rush includes the following storage backend:

It also has a base class so you can create your own.

class rush.stores.dictionary.DictionaryStore

This class implements a very simple, in-memory, non-permanent storage backend. It naively uses Python’s in-built dictionaries to store rate limit data.

Warning

This is not suggested for use outside of testing and initial proofs of concept.

class rush.stores.redis.RedisStore

This class requires a Redis URL in order to store rate limit data in Redis.

Note

This store requires installing rush with the “redis” extra, e.g.,

pip install -U rush[redis]

Example usage looks like:

from rush.stores import redis as redis_store

s = redis_store.RedisStore(
   url="redis://user:password@host:port",
)

Upon initialization, the store will create a Redis client and use that to store everything.

Further, advanced users can specify configuration parameters for the Redis client that correspond to the parameters in the redis-py documentation

Writing Your Own Storage Backend

Rush specifies a small set of methods that a backend needs to implement.

class rush.stores.base.BaseStore

Users must inherit from this class to implement their own Storage Backend. Users must define compare_and_swap, set, and get methods with the following signatures:

def get(self, key: str) -> typing.Optional[limit_data.LimitData]:
    pass

def set(
    self, *, key: str, data: limit_data.LimitData
) -> limit_data.LimitData:
    pass

def compare_and_swap(
    self,
    *,
    key: str,
    old: typing.Optional[limit_data.LimitData],
    new: limit_data.LimitData,
) -> limit_data.LimitData:
  pass

compare_and_swap must be atomic.

The way these methods communicate data back and forth between the backend and limiters is via the LimitData class.

class rush.limit_data.LimitData(used, remaining, created_at: Union[str, datetime.datetime] = NOTHING, *, time: Union[str, datetime.datetime, None] = None)

Data class that organizes our limit data for storage.

This is a data class that represents the data stored about the user’s current rate usage. It also has convenience methods for default storage backends.

created_at

A timezone-aware datetime object representing the first time we saw this user.

remaining

How much of the rate quota is left remaining.

time

An optional value that can be used for tracking the last time a request was checked by the limiter.

used

The amount of the rate quota that has already been consumed.

asdict() → Dict[str, str]

Return the data as a dictionary.

Returns:A dictionary mapping the attributes to string representations of the values.
copy_with(*, used: Optional[int] = None, remaining: Optional[int] = None, created_at: Optional[datetime.datetime] = None, time: Optional[datetime.datetime] = None) → rush.limit_data.LimitData

Create a copy of this with updated values.

Parameters:
Returns:

A new copy of this instance with the overridden values.

Return type:

LimitData