Skip to content

Upgrading limits 2 to 3

Breaking2.8.0 → 3.14.1Breaking2Platform3Deprecated1New4Changed12Fixed10Other18

BreakingUpgrade verdict

2 breaking changes and 3 platform requirement changes.

  • The package no longer falls back to the redis-py-cluster library for Redis cluster support.
  • The old Google App Engine Memcached storage option is gone, so anyone using it must switch to another storage backend.
  • The package can now be installed and used on Python 3.13.
  • Python 3.8 is no longer supported, so users on 3.8 must upgrade their Python version.
Top 5 of 6 that need code or config changes

Python requirement changed in 3.14.0: >=3.7 → >=3.9.

Drops setuptools.

Installs 4 packages in all (was 5).

Breaking2
Removes fallback support for redis-py-cluster.
redis-py-cluster
Removes the deprecated GAE Memcached storage.
Platform3
Adds support for Python 3.13.
Drops support for Python 3.8.
Adds support for Python 3.12.
Deprecated1
Removes deprecated use of pkg_resources and switches to importlib_resource.
pkg_resourcesimportlib_resource

Generated by DepDelta from published Python source. Not mixed with prose notes.

  • added: export WindowStats
  • added: export EtcdStorage
  • changed: constructor Storage(uri: Optional[str]=…, **options: Union[float, str, bool]) -> None → constructor Storage(uri: Optional[str]=…, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None
  • added: property Storage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • added: async method EtcdStorage.check() -> bool
  • added: async method EtcdStorage.clear(key: str) -> None
  • added: async method EtcdStorage.get(key: str) -> int
  • added: async method EtcdStorage.get_expiry(key: str) -> int
  • added: async method EtcdStorage.incr(key: str, expiry: int, elastic_expiry: bool=…, amount: int=…) -> int
  • added: async method EtcdStorage.reset() -> Optional[int]
  • added: class EtcdStorage(Storage)
  • added: constructor EtcdStorage(uri: str, max_retries: int=…, **options: str) -> None
  • added: field EtcdStorage.DEPENDENCIES
  • added: field EtcdStorage.MAX_RETRIES
  • added: field EtcdStorage.PREFIX
  • added: field EtcdStorage.STORAGE_SCHEME
  • added: method EtcdStorage.prefixed_key(key: str) -> bytes
  • added: property EtcdStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • changed: constructor MemcachedStorage(uri: str, **options: Union[float, str, bool]) -> None → constructor MemcachedStorage(uri: str, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None
  • added: property MemcachedStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • changed: constructor MemoryStorage(uri: Optional[str]=…, **_: str) -> None → constructor MemoryStorage(uri: Optional[str]=…, wrap_exceptions: bool=…, **_: str) -> None
  • added: property MemoryStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • removed: field MongoDBStorage.DEFAULT_OPTIONS: Dict[str, Union[float, str, bool]]
  • changed: constructor MongoDBStorage(uri: str, database_name: str=…, **options: Union[float, str, bool]) -> None → constructor MongoDBStorage(uri: str, database_name: str=…, counter_collection_name: str=…, window_collection_name: str=…, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None
  • added: property MongoDBStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • removed: field RedisSentinelStorage.DEFAULT_OPTIONS: Dict[str, Union[float, str, bool]]
  • changed: constructor RedisClusterStorage(uri: str, **options: Union[float, str, bool]) -> None → constructor RedisClusterStorage(uri: str, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None
  • changed: constructor RedisStorage(uri: str, connection_pool: Optional[coredis.ConnectionPool]=…, **options: Union[float, str, bool]) -> None → constructor RedisStorage(uri: str, connection_pool: Optional[coredis.ConnectionPool]=…, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None
  • added: field RedisInteractor.PREFIX
  • added: method RedisInteractor.prefixed_key(key: str) -> str
  • added: property RedisStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • changed: async method FixedWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → async method FixedWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats
  • changed: async method FixedWindowRateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → async method FixedWindowRateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool
  • changed: async method MovingWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → async method MovingWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats
  • changed: async method MovingWindowRateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → async method MovingWindowRateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool
  • changed: async method RateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → async method RateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats
  • changed: async method RateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → async method RateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool
  • added: class ConcurrentUpdateError(Exception)
  • added: class StorageError(Exception)
  • added: constructor ConcurrentUpdateError(key: str, attempts: int) -> None
  • added: constructor StorageError(storage_error: Exception) -> None
  • removed: export GAEMemcachedStorage
  • added: export EtcdStorage
  • added: export MongoDBStorageBase
  • changed: constructor Storage(uri: Optional[str]=…, **options: Union[float, str, bool]) → constructor Storage(uri: Optional[str]=…, wrap_exceptions: bool=…, **options: Union[float, str, bool])
  • added: property Storage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • added: class EtcdStorage(Storage)
  • added: constructor EtcdStorage(uri: str, max_retries: int=…, **options: str) -> None
  • added: field EtcdStorage.DEPENDENCIES
  • added: field EtcdStorage.MAX_RETRIES
  • added: field EtcdStorage.PREFIX
  • added: field EtcdStorage.STORAGE_SCHEME
  • added: method EtcdStorage.check() -> bool
  • added: method EtcdStorage.clear(key: str) -> None
  • added: method EtcdStorage.get(key: str) -> int
  • added: method EtcdStorage.get_expiry(key: str) -> int
  • added: method EtcdStorage.incr(key: str, expiry: int, elastic_expiry: bool=…, amount: int=…) -> int
  • added: method EtcdStorage.prefixed_key(key: str) -> bytes
  • added: method EtcdStorage.reset() -> Optional[int]
  • added: property EtcdStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • removed: class GAEMemcachedStorage(MemcachedStorage)
  • removed: constructor GAEMemcachedStorage(uri: str, **options)
  • removed: field GAEMemcachedStorage.MAX_CAS_RETRIES
  • removed: field GAEMemcachedStorage.STORAGE_SCHEME
  • removed: method GAEMemcachedStorage.check() -> bool
  • removed: method GAEMemcachedStorage.incr(key: str, expiry: int, elastic_expiry: bool=…, amount: int=…)
  • changed: constructor MemcachedStorage(uri: str, **options: Union[str, Callable[[], MemcachedClientP]]) -> None → constructor MemcachedStorage(uri: str, wrap_exceptions: bool=…, **options: Union[str, Callable[[], MemcachedClientP]]) -> None
  • added: field MemcachedStorage.DEPENDENCIES
  • added: property MemcachedStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • changed: constructor MemoryStorage(uri: Optional[str]=…, **_: str) → constructor MemoryStorage(uri: Optional[str]=…, wrap_exceptions: bool=…, **_: str)
  • added: property MemoryStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • removed: constructor MongoDBStorage(uri: str, database_name: str=…, **options: Union[int, str, bool]) -> None
  • removed: field MongoDBStorage.DEFAULT_OPTIONS: Dict[str, Union[int, str, bool]]
  • removed: field MongoDBStorage.DEPENDENCIES
  • removed: method MongoDBStorage.acquire_entry(key: str, limit: int, expiry: int, amount: int=…) -> bool
  • removed: method MongoDBStorage.check() -> bool
  • removed: method MongoDBStorage.clear(key: str) -> None
  • removed: method MongoDBStorage.get(key: str) -> int
  • removed: method MongoDBStorage.get_expiry(key: str) -> int
  • removed: method MongoDBStorage.get_moving_window(key: str, limit: int, expiry: int) -> Tuple[int, int]
  • removed: method MongoDBStorage.incr(key: str, expiry: int, elastic_expiry: bool=…, amount: int=…) -> int
  • removed: method MongoDBStorage.reset() -> Optional[int]
  • changed: class MongoDBStorage(Storage, MovingWindowSupport) → class MongoDBStorage(MongoDBStorageBase)
  • added: class MongoDBStorageBase(Storage, MovingWindowSupport, ABC)
  • added: constructor MongoDBStorageBase(uri: str, database_name: str=…, counter_collection_name: str=…, window_collection_name: str=…, wrap_exceptions: bool=…, **options: Union[int, str, bool]) -> None
  • added: field MongoDBStorageBase.DEPENDENCIES
  • added: method MongoDBStorageBase.acquire_entry(key: str, limit: int, expiry: int, amount: int=…) -> bool
  • added: method MongoDBStorageBase.check() -> bool
  • added: method MongoDBStorageBase.clear(key: str) -> None
  • added: method MongoDBStorageBase.get(key: str) -> int
  • added: method MongoDBStorageBase.get_expiry(key: str) -> int
  • added: method MongoDBStorageBase.get_moving_window(key: str, limit: int, expiry: int) -> Tuple[int, int]
  • added: method MongoDBStorageBase.incr(key: str, expiry: int, elastic_expiry: bool=…, amount: int=…) -> int
  • added: method MongoDBStorageBase.reset() -> Optional[int]
  • added: property MongoDBStorageBase.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • added: property MongoDBStorageBase.counters -> MongoCollection
  • added: property MongoDBStorageBase.storage -> MongoClient
  • added: property MongoDBStorageBase.windows -> MongoCollection
  • changed: constructor RedisStorage(uri: str, connection_pool: Optional[redis.connection.ConnectionPool]=…, **options: Union[float, str, bool]) -> None → constructor RedisStorage(uri: str, connection_pool: Optional[redis.connection.ConnectionPool]=…, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None
  • added: field RedisInteractor.PREFIX
  • added: method RedisInteractor.prefixed_key(key: str) -> str
  • added: property RedisStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • changed: constructor RedisClusterStorage(uri: str, **options: Union[float, str, bool]) -> None → constructor RedisClusterStorage(uri: str, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None
  • removed: field RedisSentinelStorage.DEFAULT_OPTIONS: Dict[str, Union[float, str, bool]]
  • changed: constructor RedisSentinelStorage(uri: str, service_name: Optional[str]=…, use_replicas: bool=…, sentinel_kwargs: Optional[Dict[str, Union[float, str, bool]]]=…, **options: Union[float, str, bool]) -> None → constructor RedisSentinelStorage(uri: str, service_name: Optional[str]=…, use_replicas: bool=…, sentinel_kwargs: Optional[Dict[str, Union[float, str, bool]]]=…, wrap_exceptions: bool=…, **options: Union[float, str, bool]) -> None
  • added: property RedisSentinelStorage.base_exceptions -> Union[Type[Exception], Tuple[Type[Exception], ...]]
  • changed: method FixedWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → method FixedWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats
  • changed: method FixedWindowRateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → method FixedWindowRateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool
  • changed: method MovingWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → method MovingWindowRateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats
  • changed: method MovingWindowRateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → method MovingWindowRateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool
  • changed: method RateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> Tuple[int, int] → method RateLimiter.get_window_stats(item: RateLimitItem, *identifiers: str) -> WindowStats
  • changed: method RateLimiter.test(item: RateLimitItem, *identifiers: str) -> bool → method RateLimiter.test(item: RateLimitItem, *identifiers: str, cost: int=…) -> bool
  • added: export Awaitable
  • added: export NamedTuple
  • added: variable MongoClient: TypeAlias
  • added: variable MongoCollection: TypeAlias
  • added: variable MongoDatabase: TypeAlias
  • added: class WindowStats(NamedTuple)
  • added: field WindowStats.remaining: int
  • added: field WindowStats.reset_time: int