1{
2 lib,
3 aetcd,
4 buildPythonPackage,
5 coredis,
6 deprecated,
7 etcd3,
8 fetchFromGitHub,
9 flaky,
10 hiro,
11 importlib-resources,
12 motor,
13 packaging,
14 pymemcache,
15 pymongo,
16 pytest-asyncio,
17 pytest-benchmark,
18 pytest-cov-stub,
19 pytest-lazy-fixtures,
20 pytestCheckHook,
21 pythonOlder,
22 redis,
23 setuptools,
24 typing-extensions,
25 valkey,
26}:
27
28buildPythonPackage rec {
29 pname = "limits";
30 version = "5.4.0";
31 pyproject = true;
32
33 src = fetchFromGitHub {
34 owner = "alisaifee";
35 repo = "limits";
36 tag = version;
37 # Upstream uses versioneer, which relies on git attributes substitution.
38 # This leads to non-reproducible archives on github. Remove the substituted
39 # file here, and recreate it later based on our version info.
40 hash = "sha256-EHLqkd5Muazr52/oYaLklFVvF+AzJWGbFaaIG+T0ulE=";
41 postFetch = ''
42 rm "$out/limits/_version.py"
43 '';
44 };
45
46 patches = [
47 ./only-test-in-memory.patch
48 ];
49
50 postPatch = ''
51 substituteInPlace pytest.ini \
52 --replace-fail "-K" ""
53
54 substituteInPlace setup.py \
55 --replace-fail "versioneer.get_version()" "'${version}'"
56
57 # Recreate _version.py, deleted at fetch time due to non-reproducibility.
58 echo 'def get_versions(): return {"version": "${version}"}' > limits/_version.py
59 '';
60
61 build-system = [ setuptools ];
62
63 dependencies = [
64 deprecated
65 importlib-resources
66 packaging
67 typing-extensions
68 ];
69
70 optional-dependencies = {
71 redis = [ redis ];
72 rediscluster = [ redis ];
73 memcached = [ pymemcache ];
74 mongodb = [ pymongo ];
75 etcd = [ etcd3 ];
76 async-redis = [ coredis ];
77 # async-memcached = [
78 # emcache # Missing module
79 # ];
80 async-mongodb = [ motor ];
81 async-etcd = [ aetcd ];
82 valkey = [ valkey ];
83 };
84
85 env = {
86 # make protobuf compatible with old versions
87 # https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates
88 PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION = "python";
89 };
90
91 nativeCheckInputs = [
92 flaky
93 hiro
94 pytest-asyncio
95 pytest-benchmark
96 pytest-cov-stub
97 pytest-lazy-fixtures
98 pytestCheckHook
99 ]
100 ++ lib.flatten (lib.attrValues optional-dependencies);
101
102 pytestFlags = [ "--benchmark-disable" ];
103
104 disabledTests = [
105 "test_moving_window_memcached"
106 # Flaky: compares time to magic value
107 "test_sliding_window_counter_previous_window"
108 ];
109
110 pythonImportsCheck = [ "limits" ];
111
112 meta = {
113 description = "Rate limiting using various strategies and storage backends such as redis & memcached";
114 homepage = "https://github.com/alisaifee/limits";
115 changelog = "https://github.com/alisaifee/limits/releases/tag/${src.tag}";
116 license = lib.licenses.mit;
117 maintainers = with lib.maintainers; [ sarahec ];
118 };
119}