Merge pull request #335747 from dotlambda/python3Packages.flask-limiter

python312Packages.flask-limiter: 3.7.0 -> 3.8.0
This commit is contained in:
Robert Schütz
2024-08-19 16:16:36 -07:00
committed by GitHub
4 changed files with 608 additions and 22 deletions
@@ -9,6 +9,7 @@
ordered-set,
pymemcache,
pymongo,
pytest-cov-stub,
pytest-mock,
pytestCheckHook,
pythonOlder,
@@ -20,28 +21,27 @@
buildPythonPackage rec {
pname = "flask-limiter";
version = "3.7.0";
version = "3.8.0";
pyproject = true;
disabled = pythonOlder "3.7";
disabled = pythonOlder "3.8";
src = fetchFromGitHub {
owner = "alisaifee";
repo = "flask-limiter";
rev = "refs/tags/${version}";
hash = "sha256-W40zuQ/xkoV35DXehwMUJwbX0grJMfRXawiPfpRKL/g=";
hash = "sha256-RkeG5XdanSp2syKrQgYUZ4r8D28Zt33/MsW0UxWxaU0=";
};
postPatch = ''
sed -i "/--cov/d" pytest.ini
# flask-restful is unmaintained and breaks regularly, don't depend on it
sed -i "/import flask_restful/d" tests/test_views.py
substituteInPlace tests/test_views.py \
--replace-fail "import flask_restful" ""
'';
nativeBuildInputs = [ setuptools ];
build-system = [ setuptools ];
propagatedBuildInputs = [
dependencies = [
flask
limits
ordered-set
@@ -57,6 +57,7 @@ buildPythonPackage rec {
nativeCheckInputs = [
asgiref
pytest-cov-stub
pytest-mock
pytestCheckHook
hiro
@@ -6,6 +6,8 @@
deprecated,
etcd3,
fetchFromGitHub,
fetchpatch2,
flaky,
hiro,
importlib-resources,
motor,
@@ -13,6 +15,7 @@
pymemcache,
pymongo,
pytest-asyncio,
pytest-benchmark,
pytest-lazy-fixture,
pytestCheckHook,
pythonOlder,
@@ -23,10 +26,10 @@
buildPythonPackage rec {
pname = "limits";
version = "3.12.0";
version = "3.13.0";
pyproject = true;
disabled = pythonOlder "3.7";
disabled = pythonOlder "3.8";
src = fetchFromGitHub {
owner = "alisaifee";
@@ -38,9 +41,20 @@ buildPythonPackage rec {
postFetch = ''
rm "$out/limits/_version.py"
'';
hash = "sha256-EH2/75tcKuS11XKuo4lCQrFe4/XJZpcWhuGlSuhIk18=";
hash = "sha256-y5iMx+AC52ZgGvAvThRaeKFqCGkwmukyZsJ+nzR2AFM=";
};
patches = [
(fetchpatch2 {
name = "fix-incompatibility-with-latest-pytest-asyncio.patch";
url = "https://github.com/alisaifee/limits/commit/f6dcdb253cd44ca8dc7380c481da1afd8b57af6b.patch";
excludes = [ "requirements/test.txt" ];
hash = "sha256-NwtN8WHNrwsRcIq18pRjzzGmm7XCzn6O5y+jo9Qr6iQ=";
})
./remove-fixed-start-from-async-tests.patch
./only-test-in-memory.patch
];
postPatch = ''
substituteInPlace pytest.ini \
--replace-fail "--cov=limits" "" \
@@ -53,16 +67,16 @@ buildPythonPackage rec {
echo 'def get_versions(): return {"version": "${version}"}' > limits/_version.py
'';
nativeBuildInputs = [ setuptools ];
build-system = [ setuptools ];
propagatedBuildInputs = [
dependencies = [
deprecated
importlib-resources
packaging
typing-extensions
];
passthru.optional-dependencies = {
optional-dependencies = {
redis = [ redis ];
rediscluster = [ redis ];
memcached = [ pymemcache ];
@@ -79,21 +93,18 @@ buildPythonPackage rec {
doCheck = pythonOlder "3.12"; # SystemError in protobuf
nativeCheckInputs = [
flaky
hiro
pytest-asyncio
pytest-benchmark
pytest-lazy-fixture
pytestCheckHook
] ++ lib.flatten (lib.attrValues passthru.optional-dependencies);
] ++ lib.flatten (lib.attrValues optional-dependencies);
disabledTests = [ "test_moving_window_memcached" ];
pythonImportsCheck = [ "limits" ];
pytestFlagsArray = [
# All other tests require a running Docker instance
"tests/test_limits.py"
"tests/test_ratelimit_parser.py"
"tests/test_limit_granularities.py"
];
meta = with lib; {
description = "Rate limiting using various strategies and storage backends such as redis & memcached";
homepage = "https://github.com/alisaifee/limits";
@@ -0,0 +1,487 @@
diff --git a/tests/aio/test_storage.py b/tests/aio/test_storage.py
index 1040d18..deecd9b 100644
--- a/tests/aio/test_storage.py
+++ b/tests/aio/test_storage.py
@@ -95,102 +95,6 @@ class TestBaseStorage:
"uri, args, expected_instance, fixture",
[
pytest.param("async+memory://", {}, MemoryStorage, None, id="in-memory"),
- pytest.param(
- "async+redis://localhost:7379",
- {},
- RedisStorage,
- pytest.lazy_fixture("redis_basic"),
- marks=pytest.mark.redis,
- id="redis",
- ),
- pytest.param(
- "async+redis+unix:///tmp/limits.redis.sock",
- {},
- RedisStorage,
- pytest.lazy_fixture("redis_uds"),
- marks=pytest.mark.redis,
- id="redis-uds",
- ),
- pytest.param(
- "async+redis+unix://:password/tmp/limits.redis.sock",
- {},
- RedisStorage,
- pytest.lazy_fixture("redis_uds"),
- marks=pytest.mark.redis,
- id="redis-uds-auth",
- ),
- pytest.param(
- "async+memcached://localhost:22122",
- {},
- MemcachedStorage,
- pytest.lazy_fixture("memcached"),
- marks=pytest.mark.memcached,
- id="memcached",
- ),
- pytest.param(
- "async+memcached://localhost:22122,localhost:22123",
- {},
- MemcachedStorage,
- pytest.lazy_fixture("memcached_cluster"),
- marks=pytest.mark.memcached,
- id="memcached-cluster",
- ),
- pytest.param(
- "async+redis+sentinel://localhost:26379",
- {"service_name": "mymaster"},
- RedisSentinelStorage,
- pytest.lazy_fixture("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel",
- ),
- pytest.param(
- "async+redis+sentinel://localhost:26379/mymaster",
- {},
- RedisSentinelStorage,
- pytest.lazy_fixture("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel-service-name-url",
- ),
- pytest.param(
- "async+redis+sentinel://:sekret@localhost:36379/mymaster",
- {"password": "sekret"},
- RedisSentinelStorage,
- pytest.lazy_fixture("redis_sentinel_auth"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel-auth",
- ),
- pytest.param(
- "async+redis+cluster://localhost:7001/",
- {},
- RedisClusterStorage,
- pytest.lazy_fixture("redis_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster",
- ),
- pytest.param(
- "async+redis+cluster://:sekret@localhost:8400/",
- {},
- RedisClusterStorage,
- pytest.lazy_fixture("redis_auth_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster-auth",
- ),
- pytest.param(
- "async+mongodb://localhost:37017/",
- {},
- MongoDBStorage,
- pytest.lazy_fixture("mongodb"),
- marks=pytest.mark.mongodb,
- id="mongodb",
- ),
- pytest.param(
- "async+etcd://localhost:2379",
- {},
- EtcdStorage,
- pytest.lazy_fixture("etcd"),
- marks=pytest.mark.etcd,
- id="etcd",
- ),
],
)
class TestConcreteStorages:
diff --git a/tests/test_storage.py b/tests/test_storage.py
index 1b8c7b0..97dcee5 100644
--- a/tests/test_storage.py
+++ b/tests/test_storage.py
@@ -100,110 +100,6 @@ class TestBaseStorage:
"uri, args, expected_instance, fixture",
[
pytest.param("memory://", {}, MemoryStorage, None, id="in-memory"),
- pytest.param(
- "redis://localhost:7379",
- {},
- RedisStorage,
- pytest.lazy_fixture("redis_basic"),
- marks=pytest.mark.redis,
- id="redis",
- ),
- pytest.param(
- "redis+unix:///tmp/limits.redis.sock",
- {},
- RedisStorage,
- pytest.lazy_fixture("redis_uds"),
- marks=pytest.mark.redis,
- id="redis-uds",
- ),
- pytest.param(
- "redis+unix://:password/tmp/limits.redis.sock",
- {},
- RedisStorage,
- pytest.lazy_fixture("redis_uds"),
- marks=pytest.mark.redis,
- id="redis-uds-auth",
- ),
- pytest.param(
- "memcached://localhost:22122",
- {},
- MemcachedStorage,
- pytest.lazy_fixture("memcached"),
- marks=pytest.mark.memcached,
- id="memcached",
- ),
- pytest.param(
- "memcached://localhost:22122,localhost:22123",
- {},
- MemcachedStorage,
- pytest.lazy_fixture("memcached_cluster"),
- marks=pytest.mark.memcached,
- id="memcached-cluster",
- ),
- pytest.param(
- "memcached:///tmp/limits.memcached.sock",
- {},
- MemcachedStorage,
- pytest.lazy_fixture("memcached_uds"),
- marks=pytest.mark.memcached,
- id="memcached-uds",
- ),
- pytest.param(
- "redis+sentinel://localhost:26379",
- {"service_name": "mymaster"},
- RedisSentinelStorage,
- pytest.lazy_fixture("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel",
- ),
- pytest.param(
- "redis+sentinel://localhost:26379/mymaster",
- {},
- RedisSentinelStorage,
- pytest.lazy_fixture("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel-service-name-url",
- ),
- pytest.param(
- "redis+sentinel://:sekret@localhost:36379/mymaster",
- {"password": "sekret"},
- RedisSentinelStorage,
- pytest.lazy_fixture("redis_sentinel_auth"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel-auth",
- ),
- pytest.param(
- "redis+cluster://localhost:7001/",
- {},
- RedisClusterStorage,
- pytest.lazy_fixture("redis_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster",
- ),
- pytest.param(
- "redis+cluster://:sekret@localhost:8400/",
- {},
- RedisClusterStorage,
- pytest.lazy_fixture("redis_auth_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster-auth",
- ),
- pytest.param(
- "mongodb://localhost:37017/",
- {},
- MongoDBStorage,
- pytest.lazy_fixture("mongodb"),
- marks=pytest.mark.mongodb,
- id="mongodb",
- ),
- pytest.param(
- "etcd://localhost:2379",
- {},
- EtcdStorage,
- pytest.lazy_fixture("etcd"),
- marks=pytest.mark.etcd,
- id="etcd",
- ),
],
)
class TestConcreteStorages:
diff --git a/tests/utils.py b/tests/utils.py
index 558d766..9dcb911 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -52,75 +52,6 @@ all_storage = pytest.mark.parametrize(
"uri, args, fixture",
[
pytest.param("memory://", {}, None, id="in-memory"),
- pytest.param(
- "redis://localhost:7379",
- {},
- pytest.lazy_fixture("redis_basic"),
- marks=pytest.mark.redis,
- id="redis_basic",
- ),
- pytest.param(
- "memcached://localhost:22122",
- {},
- pytest.lazy_fixture("memcached"),
- marks=[pytest.mark.memcached, pytest.mark.flaky],
- id="memcached",
- ),
- pytest.param(
- "memcached://localhost:22122,localhost:22123",
- {},
- pytest.lazy_fixture("memcached_cluster"),
- marks=[pytest.mark.memcached, pytest.mark.flaky],
- id="memcached-cluster",
- ),
- pytest.param(
- "redis+cluster://localhost:7001/",
- {},
- pytest.lazy_fixture("redis_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster",
- ),
- pytest.param(
- "redis+cluster://:sekret@localhost:8400/",
- {},
- pytest.lazy_fixture("redis_auth_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster-auth",
- ),
- pytest.param(
- "redis+cluster://localhost:8301",
- {
- "ssl": True,
- "ssl_cert_reqs": "required",
- "ssl_keyfile": "./tests/tls/client.key",
- "ssl_certfile": "./tests/tls/client.crt",
- "ssl_ca_certs": "./tests/tls/ca.crt",
- },
- pytest.lazy_fixture("redis_ssl_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-ssl-cluster",
- ),
- pytest.param(
- "redis+sentinel://localhost:26379/mymaster",
- {"use_replicas": False},
- pytest.lazy_fixture("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel",
- ),
- pytest.param(
- "mongodb://localhost:37017/",
- {},
- pytest.lazy_fixture("mongodb"),
- marks=pytest.mark.mongodb,
- id="mongodb",
- ),
- pytest.param(
- "etcd://localhost:2379",
- {},
- pytest.lazy_fixture("etcd"),
- marks=[pytest.mark.etcd, pytest.mark.flaky],
- id="etcd",
- ),
],
)
@@ -128,54 +59,6 @@ moving_window_storage = pytest.mark.parametrize(
"uri, args, fixture",
[
pytest.param("memory://", {}, None, id="in-memory"),
- pytest.param(
- "redis://localhost:7379",
- {},
- pytest.lazy_fixture("redis_basic"),
- marks=pytest.mark.redis,
- id="redis",
- ),
- pytest.param(
- "redis+cluster://localhost:7001/",
- {},
- pytest.lazy_fixture("redis_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster",
- ),
- pytest.param(
- "redis+cluster://:sekret@localhost:8400/",
- {},
- pytest.lazy_fixture("redis_auth_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster-auth",
- ),
- pytest.param(
- "redis+cluster://localhost:8301",
- {
- "ssl": True,
- "ssl_cert_reqs": "required",
- "ssl_keyfile": "./tests/tls/client.key",
- "ssl_certfile": "./tests/tls/client.crt",
- "ssl_ca_certs": "./tests/tls/ca.crt",
- },
- pytest.lazy_fixture("redis_ssl_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-ssl-cluster",
- ),
- pytest.param(
- "redis+sentinel://localhost:26379/mymaster",
- {"use_replicas": False},
- pytest.lazy_fixture("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel",
- ),
- pytest.param(
- "mongodb://localhost:37017/",
- {},
- pytest.lazy_fixture("mongodb"),
- marks=pytest.mark.mongodb,
- id="mongodb",
- ),
],
)
@@ -183,75 +66,6 @@ async_all_storage = pytest.mark.parametrize(
"uri, args, fixture",
[
pytest.param("async+memory://", {}, None, id="in-memory"),
- pytest.param(
- "async+redis://localhost:7379",
- {},
- pytest.lazy_fixture("redis_basic"),
- marks=pytest.mark.redis,
- id="redis",
- ),
- pytest.param(
- "async+memcached://localhost:22122",
- {},
- pytest.lazy_fixture("memcached"),
- marks=[pytest.mark.memcached, pytest.mark.flaky],
- id="memcached",
- ),
- pytest.param(
- "async+memcached://localhost:22122,localhost:22123",
- {},
- pytest.lazy_fixture("memcached_cluster"),
- marks=[pytest.mark.memcached, pytest.mark.flaky],
- id="memcached-cluster",
- ),
- pytest.param(
- "async+redis+cluster://localhost:7001/",
- {},
- pytest.lazy_fixture("redis_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster",
- ),
- pytest.param(
- "async+redis+cluster://:sekret@localhost:8400/",
- {},
- pytest.lazy_fixture("redis_auth_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster-auth",
- ),
- pytest.param(
- "async+redis+cluster://localhost:8301",
- {
- "ssl": True,
- "ssl_cert_reqs": "required",
- "ssl_keyfile": "./tests/tls/client.key",
- "ssl_certfile": "./tests/tls/client.crt",
- "ssl_ca_certs": "./tests/tls/ca.crt",
- },
- pytest.lazy_fixture("redis_ssl_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-ssl-cluster",
- ),
- pytest.param(
- "async+redis+sentinel://localhost:26379/mymaster",
- {"use_replicas": False},
- pytest.lazy_fixture("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel",
- ),
- pytest.param(
- "async+mongodb://localhost:37017/",
- {},
- pytest.lazy_fixture("mongodb"),
- marks=pytest.mark.mongodb,
- id="mongodb",
- ),
- pytest.param(
- "async+etcd://localhost:2379",
- {},
- pytest.lazy_fixture("etcd"),
- marks=[pytest.mark.etcd, pytest.mark.flaky],
- id="etcd",
- ),
],
)
@@ -259,53 +73,5 @@ async_moving_window_storage = pytest.mark.parametrize(
"uri, args, fixture",
[
pytest.param("async+memory://", {}, None, id="in-memory"),
- pytest.param(
- "async+redis://localhost:7379",
- {},
- pytest.lazy_fixture("redis_basic"),
- marks=pytest.mark.redis,
- id="redis",
- ),
- pytest.param(
- "async+redis+cluster://localhost:7001/",
- {},
- pytest.lazy_fixture("redis_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster",
- ),
- pytest.param(
- "async+redis+cluster://:sekret@localhost:8400/",
- {},
- pytest.lazy_fixture("redis_auth_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster-auth",
- ),
- pytest.param(
- "async+redis+cluster://localhost:8301",
- {
- "ssl": True,
- "ssl_cert_reqs": "required",
- "ssl_keyfile": "./tests/tls/client.key",
- "ssl_certfile": "./tests/tls/client.crt",
- "ssl_ca_certs": "./tests/tls/ca.crt",
- },
- pytest.lazy_fixture("redis_ssl_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-ssl-cluster",
- ),
- pytest.param(
- "async+redis+sentinel://localhost:26379/mymaster",
- {"use_replicas": False},
- pytest.lazy_fixture("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel",
- ),
- pytest.param(
- "async+mongodb://localhost:37017/",
- {},
- pytest.lazy_fixture("mongodb"),
- marks=pytest.mark.mongodb,
- id="mongodb",
- ),
],
)
@@ -0,0 +1,87 @@
diff --git a/tests/aio/test_storage.py b/tests/aio/test_storage.py
index 1040d18..7015278 100644
--- a/tests/aio/test_storage.py
+++ b/tests/aio/test_storage.py
@@ -17,7 +17,6 @@ from limits.aio.storage import (
from limits.aio.strategies import MovingWindowRateLimiter
from limits.errors import StorageError
from limits.storage import storage_from_string
-from tests.utils import fixed_start
@pytest.mark.asyncio
@@ -197,7 +196,6 @@ class TestConcreteStorages:
async def test_storage_string(self, uri, args, expected_instance, fixture):
assert isinstance(storage_from_string(uri, **args), expected_instance)
- @fixed_start
async def test_expiry_incr(self, uri, args, expected_instance, fixture):
storage = storage_from_string(uri, **args)
limit = RateLimitItemPerSecond(1)
@@ -205,7 +203,6 @@ class TestConcreteStorages:
time.sleep(1.1)
assert await storage.get(limit.key_for()) == 0
- @fixed_start
async def test_expiry_acquire_entry(self, uri, args, expected_instance, fixture):
if not issubclass(expected_instance, MovingWindowSupport):
pytest.skip("%s does not support acquire entry" % expected_instance)
diff --git a/tests/aio/test_strategy.py b/tests/aio/test_strategy.py
index b21f808..efa3b95 100644
--- a/tests/aio/test_strategy.py
+++ b/tests/aio/test_strategy.py
@@ -18,14 +18,12 @@ from tests.utils import (
async_all_storage,
async_moving_window_storage,
async_window,
- fixed_start,
)
@pytest.mark.asyncio
class TestAsyncWindow:
@async_all_storage
- @fixed_start
async def test_fixed_window(self, uri, args, fixture):
storage = storage_from_string(uri, **args)
limiter = FixedWindowRateLimiter(storage)
@@ -37,7 +35,6 @@ class TestAsyncWindow:
assert (await limiter.get_window_stats(limit)).reset_time == start + 2
@async_all_storage
- @fixed_start
async def test_fixed_window_empty_stats(self, uri, args, fixture):
storage = storage_from_string(uri, **args)
limiter = FixedWindowRateLimiter(storage)
@@ -61,7 +58,6 @@ class TestAsyncWindow:
) == 58
@async_all_storage
- @fixed_start
async def test_fixed_window_multiple_cost(self, uri, args, fixture):
storage = storage_from_string(uri, **args)
limiter = FixedWindowRateLimiter(storage)
@@ -73,7 +69,6 @@ class TestAsyncWindow:
assert not await limiter.hit(limit, "k2", cost=6)
@async_all_storage
- @fixed_start
async def test_fixed_window_with_elastic_expiry(self, uri, args, fixture):
storage = storage_from_string(uri, **args)
limiter = FixedWindowElasticExpiryRateLimiter(storage)
@@ -90,7 +85,6 @@ class TestAsyncWindow:
assert (await limiter.get_window_stats(limit)).reset_time == end + 2
@async_all_storage
- @fixed_start
async def test_fixed_window_with_elastic_expiry_multiple_cost(
self, uri, args, fixture
):
@@ -179,7 +173,6 @@ class TestAsyncWindow:
MovingWindowRateLimiter(storage)
@async_all_storage
- @fixed_start
@pytest.mark.flaky
async def test_test_fixed_window(self, uri, args, fixture):
storage = storage_from_string(uri, **args)