limits 3.4.0__tar.gz → 3.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {limits-3.4.0 → limits-3.5.0}/HISTORY.rst +10 -0
- {limits-3.4.0 → limits-3.5.0}/PKG-INFO +1 -1
- {limits-3.4.0 → limits-3.5.0}/limits/_version.py +3 -3
- {limits-3.4.0 → limits-3.5.0}/limits/aio/storage/redis.py +0 -7
- {limits-3.4.0 → limits-3.5.0}/limits/resources/redis/lua_scripts/acquire_moving_window.lua +4 -5
- {limits-3.4.0 → limits-3.5.0}/limits/storage/redis_sentinel.py +1 -6
- {limits-3.4.0 → limits-3.5.0}/limits.egg-info/PKG-INFO +1 -1
- {limits-3.4.0 → limits-3.5.0}/requirements/docs.txt +1 -1
- {limits-3.4.0 → limits-3.5.0}/tests/test_strategy.py +10 -0
- {limits-3.4.0 → limits-3.5.0}/CLASSIFIERS +0 -0
- {limits-3.4.0 → limits-3.5.0}/CONTRIBUTIONS.rst +0 -0
- {limits-3.4.0 → limits-3.5.0}/LICENSE.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/MANIFEST.in +0 -0
- {limits-3.4.0 → limits-3.5.0}/README.rst +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/Makefile +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/_static/custom.css +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/api.rst +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/async.rst +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/changelog.rst +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/conf.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/custom-storage.rst +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/index.rst +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/installation.rst +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/quickstart.rst +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/storage.rst +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/strategies.rst +0 -0
- {limits-3.4.0 → limits-3.5.0}/doc/source/theme_config.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/__init__.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/aio/__init__.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/aio/storage/__init__.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/aio/storage/base.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/aio/storage/etcd.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/aio/storage/memcached.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/aio/storage/memory.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/aio/storage/mongodb.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/aio/strategies.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/errors.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/limits.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/py.typed +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/resources/redis/lua_scripts/clear_keys.lua +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/resources/redis/lua_scripts/incr_expire.lua +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/resources/redis/lua_scripts/moving_window.lua +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/storage/__init__.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/storage/base.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/storage/etcd.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/storage/memcached.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/storage/memory.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/storage/mongodb.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/storage/redis.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/storage/redis_cluster.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/storage/registry.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/strategies.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/typing.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/util.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits/version.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits.egg-info/SOURCES.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits.egg-info/dependency_links.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits.egg-info/not-zip-safe +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits.egg-info/requires.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/limits.egg-info/top_level.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/pyproject.toml +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/ci.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/dev.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/main.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/storage/async-etcd.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/storage/async-memcached.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/storage/async-mongodb.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/storage/async-redis.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/storage/etcd.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/storage/memcached.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/storage/mongodb.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/storage/redis.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/storage/rediscluster.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/requirements/test.txt +0 -0
- {limits-3.4.0 → limits-3.5.0}/setup.cfg +0 -0
- {limits-3.4.0 → limits-3.5.0}/setup.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/tests/test_limit_granularities.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/tests/test_limits.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/tests/test_ratelimit_parser.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/tests/test_storage.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/tests/test_utils.py +0 -0
- {limits-3.4.0 → limits-3.5.0}/versioneer.py +0 -0
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
Changelog
|
|
4
4
|
=========
|
|
5
5
|
|
|
6
|
+
v3.5.0
|
|
7
|
+
------
|
|
8
|
+
Release Date: 2023-05-16
|
|
9
|
+
|
|
10
|
+
* Bug Fix
|
|
11
|
+
|
|
12
|
+
* Handle ``cost`` > 8000 when using redis
|
|
13
|
+
* Remove arbitrary default timeout for redis+sentinel
|
|
14
|
+
|
|
6
15
|
v3.4.0
|
|
7
16
|
------
|
|
8
17
|
Release Date: 2023-04-17
|
|
@@ -599,5 +608,6 @@ Release Date: 2015-01-08
|
|
|
599
608
|
|
|
600
609
|
|
|
601
610
|
|
|
611
|
+
|
|
602
612
|
|
|
603
613
|
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2023-
|
|
11
|
+
"date": "2023-05-16T15:04:57-0700",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "3.
|
|
14
|
+
"full-revisionid": "d61ade38645d742e4614dd1c1c0283d6ace40bf0",
|
|
15
|
+
"version": "3.5.0"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -349,11 +349,6 @@ class RedisSentinelStorage(RedisStorage):
|
|
|
349
349
|
STORAGE_SCHEME = ["async+redis+sentinel"]
|
|
350
350
|
"""The storage scheme for redis accessed via a redis sentinel installation"""
|
|
351
351
|
|
|
352
|
-
DEFAULT_OPTIONS: Dict[str, Union[float, str, bool]] = {
|
|
353
|
-
"stream_timeout": 0.2,
|
|
354
|
-
}
|
|
355
|
-
"Default options passed to :class:`~coredis.sentinel.Sentinel`"
|
|
356
|
-
|
|
357
352
|
DEPENDENCIES = {"coredis.sentinel": Version("3.4.0")}
|
|
358
353
|
|
|
359
354
|
def __init__(
|
|
@@ -402,8 +397,6 @@ class RedisSentinelStorage(RedisStorage):
|
|
|
402
397
|
if self.service_name is None:
|
|
403
398
|
raise ConfigurationError("'service_name' not provided")
|
|
404
399
|
|
|
405
|
-
connection_options.setdefault("stream_timeout", 0.2)
|
|
406
|
-
|
|
407
400
|
super(RedisStorage, self).__init__()
|
|
408
401
|
|
|
409
402
|
self.dependency = self.dependencies["coredis.sentinel"].module
|
|
@@ -9,15 +9,14 @@ end
|
|
|
9
9
|
|
|
10
10
|
local entry = redis.call('lindex', KEYS[1], limit - amount)
|
|
11
11
|
|
|
12
|
-
|
|
13
12
|
if entry and tonumber(entry) >= timestamp - expiry then
|
|
14
13
|
return false
|
|
15
14
|
end
|
|
16
|
-
|
|
17
|
-
for i=1, amount do
|
|
18
|
-
|
|
15
|
+
|
|
16
|
+
for i = 1, amount do
|
|
17
|
+
redis.call('lpush', KEYS[1], timestamp)
|
|
19
18
|
end
|
|
20
|
-
|
|
19
|
+
|
|
21
20
|
redis.call('ltrim', KEYS[1], 0, limit - 1)
|
|
22
21
|
redis.call('expire', KEYS[1], expiry)
|
|
23
22
|
|
|
@@ -21,11 +21,6 @@ class RedisSentinelStorage(RedisStorage):
|
|
|
21
21
|
STORAGE_SCHEME = ["redis+sentinel"]
|
|
22
22
|
"""The storage scheme for redis accessed via a redis sentinel installation"""
|
|
23
23
|
|
|
24
|
-
DEFAULT_OPTIONS: Dict[str, Union[float, str, bool]] = {
|
|
25
|
-
"socket_timeout": 0.2,
|
|
26
|
-
}
|
|
27
|
-
"Default options passed to :class:`~redis.sentinel.Sentinel`"
|
|
28
|
-
|
|
29
24
|
DEPENDENCIES = {"redis.sentinel": Version("3.0")}
|
|
30
25
|
|
|
31
26
|
def __init__(
|
|
@@ -79,7 +74,7 @@ class RedisSentinelStorage(RedisStorage):
|
|
|
79
74
|
self.sentinel: "redis.sentinel.Sentinel" = sentinel_dep.Sentinel(
|
|
80
75
|
sentinel_configuration,
|
|
81
76
|
sentinel_kwargs={**parsed_auth, **sentinel_options},
|
|
82
|
-
**{**
|
|
77
|
+
**{**parsed_auth, **options}
|
|
83
78
|
)
|
|
84
79
|
self.storage = self.sentinel.master_for(self.service_name)
|
|
85
80
|
self.storage_slave = self.sentinel.slave_for(self.service_name)
|
|
@@ -134,6 +134,16 @@ class TestWindow:
|
|
|
134
134
|
limiter.clear(five_per_min)
|
|
135
135
|
assert limiter.hit(five_per_min)
|
|
136
136
|
|
|
137
|
+
@moving_window_storage
|
|
138
|
+
def test_moving_window_huge_cost_sync(self, uri, args, fixture):
|
|
139
|
+
storage = storage_from_string(uri, **args)
|
|
140
|
+
limiter = MovingWindowRateLimiter(storage)
|
|
141
|
+
many_per_min = RateLimitItemPerMinute(1_000_000)
|
|
142
|
+
limiter.hit(many_per_min, cost=1_000_000)
|
|
143
|
+
assert not limiter.hit(many_per_min, cost=2)
|
|
144
|
+
limiter.clear(many_per_min)
|
|
145
|
+
assert limiter.hit(many_per_min)
|
|
146
|
+
|
|
137
147
|
@pytest.mark.memcached
|
|
138
148
|
def test_moving_window_memcached(self, memcached):
|
|
139
149
|
storage = MemcachedStorage("memcached://localhost:22122")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|