limits 4.7.2__py3-none-any.whl → 5.0.0rc1__py3-none-any.whl

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.
@@ -0,0 +1,41 @@
1
+ limits/__init__.py,sha256=gPUFrt02kHF_syLjiVRSs-S4UVGpRMcM2VMFNhF6G24,748
2
+ limits/_version.py,sha256=kltwWj42pO4gRxnH3YVXMAqHthKTyYt67Uzylwnaayo,500
3
+ limits/errors.py,sha256=s1el9Vg0ly-z92guvnvYNgKi3_aVqpiw_sufemiLLTI,662
4
+ limits/limits.py,sha256=YzzZP8_ay_zlMMnnY2xhAcFTTFvFe5HEk8NQlvUTru4,4907
5
+ limits/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ limits/strategies.py,sha256=LeZ6lnE73EIQqQ8TfKaTzlxNvBMrZOOSXFB0l8D17fI,9946
7
+ limits/typing.py,sha256=vmutp9AD8XXQ5U48fM7rVaBSoK9fWalkhnK_TGg8xxY,3267
8
+ limits/util.py,sha256=nk5QYvezFuXPq1OTEj04RrZFSWIH-khT0e_Dim6zGCw,6002
9
+ limits/version.py,sha256=YwkF3dtq1KGzvmL3iVGctA8NNtGlK_0arrzZkZGVjUs,47
10
+ limits/aio/__init__.py,sha256=yxvWb_ZmV245Hg2LqD365WC5IDllcGDMw6udJ1jNp1g,118
11
+ limits/aio/strategies.py,sha256=RzZExH2r6jnHra4SpDHqtZCC0Bo3085zUJYo2boAj6Y,9897
12
+ limits/aio/storage/__init__.py,sha256=vKeArUnN1ld_0mQOBBZPCjaQgM5xI1GBPM7_F2Ydz5c,646
13
+ limits/aio/storage/base.py,sha256=VfHpL9Z3RL76eKhoaSQKLKQsqcF5B2bnF6gfa-8ltWA,6296
14
+ limits/aio/storage/memcached.py,sha256=q1t9wowCg04-pHavg0i5xEly4KMgVkW5ptyGNA4RiqU,9195
15
+ limits/aio/storage/memory.py,sha256=HdkQPcjjHv1MhGoeYWOkBwwMj5e0tQbaO0OlECzh64A,9178
16
+ limits/aio/storage/mongodb.py,sha256=tIMfQrseONRMR2nuRmPO7ocp8dTCABfqBICS_kgp550,19141
17
+ limits/aio/storage/redis/__init__.py,sha256=lwoKk91YLEBlZ3W6hCnQ1e7Gc6LxpvSzZZW16saCyR4,14143
18
+ limits/aio/storage/redis/bridge.py,sha256=eoRi9h2bSy194cVwoKgRYQV1HQ7SvwarL-4LeazrxeA,3145
19
+ limits/aio/storage/redis/coredis.py,sha256=IzfEyXBvQbr4QUWML9xAd87a2aHCvglOBEjAg-Vq4z0,7420
20
+ limits/aio/storage/redis/redispy.py,sha256=HS1H6E9g0dP3G-8tSUILIFoc8JWpeRQOiBxcpL3I0gM,8310
21
+ limits/aio/storage/redis/valkey.py,sha256=f_-HPZhzNspywGybMNIL0F5uDZk76v8_K9wuC5ZeKhc,248
22
+ limits/resources/redis/lua_scripts/acquire_moving_window.lua,sha256=Vz0HkI_bSFLW668lEVw8paKlTLEuU4jZk1fpdSuz3zg,594
23
+ limits/resources/redis/lua_scripts/acquire_sliding_window.lua,sha256=OhVI1MAN_gT92P6r-2CEmvy1yvQVjYCCZxWIxfXYceY,1329
24
+ limits/resources/redis/lua_scripts/clear_keys.lua,sha256=zU0cVfLGmapRQF9x9u0GclapM_IB2pJLszNzVQ1QRK4,184
25
+ limits/resources/redis/lua_scripts/incr_expire.lua,sha256=Uq9NcrrcDI-F87TDAJexoSJn2SDgeXIUEYozCp9S3oA,195
26
+ limits/resources/redis/lua_scripts/moving_window.lua,sha256=zlieQwfET0BC7sxpfiOuzPa1wwmrwWLy7IF8LxNa_Lw,717
27
+ limits/resources/redis/lua_scripts/sliding_window.lua,sha256=qG3Yg30Dq54QpRUcR9AOrKQ5bdJiaYpCacTm6Kxblvc,713
28
+ limits/storage/__init__.py,sha256=9iNxIlwzLQw2d54EcMa2LBJ47wiWCPOnHgn6ddqKkDI,2652
29
+ limits/storage/base.py,sha256=IdOL_iqR9KhaJO73M_h9c6OYe8Ox632pxx5uXaL9Dbo,6860
30
+ limits/storage/memcached.py,sha256=7ZdT80OgQa0f16Tr2L2zGu8PZGzLryOvlb4D1Qk7z9I,10193
31
+ limits/storage/memory.py,sha256=Qc13tGIOFPJ5maehxZdT0074qMvkW-RrzoyZIbFuRyE,8698
32
+ limits/storage/mongodb.py,sha256=V4Ib_AwPFX6JpNI7oUUGJx_3MxD8EmYAi4Q6QcWnQ5U,18071
33
+ limits/storage/redis.py,sha256=i_6qh4S6JQd-lG6eRJdTPxNnZIAkm4G0cA0mfow9OOk,10389
34
+ limits/storage/redis_cluster.py,sha256=z6aONMl4p1AY78G3J0BbtK--uztz88krwnpiOsU61BM,4447
35
+ limits/storage/redis_sentinel.py,sha256=AN0WtwHN88TvXk0C2uUE8l5Jhsd1ZxU8XSqrEyQSR20,4327
36
+ limits/storage/registry.py,sha256=CxSaDBGR5aBJPFAIsfX9axCnbcThN3Bu-EH4wHrXtu8,650
37
+ limits-5.0.0rc1.dist-info/licenses/LICENSE.txt,sha256=T6i7kq7F5gIPfcno9FCxU5Hcwm22Bjq0uHZV3ElcjsQ,1061
38
+ limits-5.0.0rc1.dist-info/METADATA,sha256=iXK14MS_wl5xFrRblJE9Niv54qsuaGhW-_49-vIrSrY,10828
39
+ limits-5.0.0rc1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
40
+ limits-5.0.0rc1.dist-info/top_level.txt,sha256=C7g5ahldPoU2s6iWTaJayUrbGmPK1d6e9t5Nn0vQ2jM,7
41
+ limits-5.0.0rc1.dist-info/RECORD,,
@@ -1,146 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import asyncio
4
- import time
5
- import urllib.parse
6
- from typing import TYPE_CHECKING
7
-
8
- from deprecated.sphinx import deprecated
9
-
10
- from limits.aio.storage.base import Storage
11
- from limits.errors import ConcurrentUpdateError
12
-
13
- if TYPE_CHECKING:
14
- import aetcd
15
-
16
-
17
- @deprecated(version="4.4")
18
- class EtcdStorage(Storage):
19
- """
20
- Rate limit storage with etcd as backend.
21
-
22
- Depends on :pypi:`aetcd`.
23
- """
24
-
25
- STORAGE_SCHEME = ["async+etcd"]
26
- """The async storage scheme for etcd"""
27
- DEPENDENCIES = ["aetcd"]
28
-
29
- PREFIX = "limits"
30
- MAX_RETRIES = 5
31
-
32
- def __init__(
33
- self,
34
- uri: str,
35
- max_retries: int = MAX_RETRIES,
36
- wrap_exceptions: bool = False,
37
- **options: str,
38
- ) -> None:
39
- """
40
- :param uri: etcd location of the form
41
- ``async+etcd://host:port``,
42
- :param max_retries: Maximum number of attempts to retry
43
- in the case of concurrent updates to a rate limit key
44
- :param wrap_exceptions: Whether to wrap storage exceptions in
45
- :exc:`limits.errors.StorageError` before raising it.
46
- :param options: all remaining keyword arguments are passed
47
- directly to the constructor of :class:`aetcd.client.Client`
48
- :raise ConfigurationError: when :pypi:`aetcd` is not available
49
- """
50
- parsed = urllib.parse.urlparse(uri)
51
- self.lib = self.dependencies["aetcd"].module
52
- self.storage: aetcd.Client = self.lib.Client(
53
- host=parsed.hostname, port=parsed.port, **options
54
- )
55
- self.max_retries = max_retries
56
- super().__init__(uri, wrap_exceptions=wrap_exceptions)
57
-
58
- @property
59
- def base_exceptions(
60
- self,
61
- ) -> type[Exception] | tuple[type[Exception], ...]: # pragma: no cover
62
- return self.lib.ClientError # type: ignore[no-any-return]
63
-
64
- def prefixed_key(self, key: str) -> bytes:
65
- return f"{self.PREFIX}/{key}".encode()
66
-
67
- async def incr(
68
- self, key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1
69
- ) -> int:
70
- retries = 0
71
- etcd_key = self.prefixed_key(key)
72
- while retries < self.max_retries:
73
- now = time.time()
74
- lease = await self.storage.lease(expiry)
75
- window_end = now + expiry
76
- create_attempt = await self.storage.transaction(
77
- compare=[self.storage.transactions.create(etcd_key) == b"0"],
78
- success=[
79
- self.storage.transactions.put(
80
- etcd_key, f"{amount}:{window_end}".encode(), lease=lease.id
81
- )
82
- ],
83
- failure=[self.storage.transactions.get(etcd_key)],
84
- )
85
- if create_attempt[0]:
86
- return amount
87
- else:
88
- cur = create_attempt[1][0][0][1]
89
- cur_value, window_end = cur.value.split(b":")
90
- window_end = float(window_end)
91
- if window_end <= now:
92
- await asyncio.gather(
93
- self.storage.revoke_lease(cur.lease),
94
- self.storage.delete(etcd_key),
95
- )
96
- else:
97
- if elastic_expiry:
98
- await self.storage.refresh_lease(cur.lease)
99
- window_end = now + expiry
100
- new = int(cur_value) + amount
101
- if (
102
- await self.storage.transaction(
103
- compare=[
104
- self.storage.transactions.value(etcd_key) == cur.value
105
- ],
106
- success=[
107
- self.storage.transactions.put(
108
- etcd_key,
109
- f"{new}:{window_end}".encode(),
110
- lease=cur.lease,
111
- )
112
- ],
113
- failure=[],
114
- )
115
- )[0]:
116
- return new
117
- retries += 1
118
- raise ConcurrentUpdateError(key, retries)
119
-
120
- async def get(self, key: str) -> int:
121
- cur = await self.storage.get(self.prefixed_key(key))
122
- if cur:
123
- amount, expiry = cur.value.split(b":")
124
- if float(expiry) > time.time():
125
- return int(amount)
126
- return 0
127
-
128
- async def get_expiry(self, key: str) -> float:
129
- cur = await self.storage.get(self.prefixed_key(key))
130
- if cur:
131
- window_end = float(cur.value.split(b":")[1])
132
- return window_end
133
- return time.time()
134
-
135
- async def check(self) -> bool:
136
- try:
137
- await self.storage.status()
138
- return True
139
- except: # noqa
140
- return False
141
-
142
- async def reset(self) -> int | None:
143
- return (await self.storage.delete_prefix(f"{self.PREFIX}/".encode())).deleted
144
-
145
- async def clear(self, key: str) -> None:
146
- await self.storage.delete(self.prefixed_key(key))
limits/storage/etcd.py DELETED
@@ -1,139 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import time
4
- import urllib.parse
5
-
6
- from deprecated.sphinx import deprecated
7
-
8
- from limits.errors import ConcurrentUpdateError
9
- from limits.storage.base import Storage
10
- from limits.typing import TYPE_CHECKING
11
-
12
- if TYPE_CHECKING:
13
- import etcd3
14
-
15
-
16
- @deprecated(version="4.4")
17
- class EtcdStorage(Storage):
18
- """
19
- Rate limit storage with etcd as backend.
20
-
21
- Depends on :pypi:`etcd3`.
22
- """
23
-
24
- STORAGE_SCHEME = ["etcd"]
25
- """The storage scheme for etcd"""
26
- DEPENDENCIES = ["etcd3"]
27
- PREFIX = "limits"
28
- MAX_RETRIES = 5
29
-
30
- def __init__(
31
- self,
32
- uri: str,
33
- max_retries: int = MAX_RETRIES,
34
- wrap_exceptions: bool = False,
35
- **options: str,
36
- ) -> None:
37
- """
38
- :param uri: etcd location of the form
39
- ``etcd://host:port``,
40
- :param max_retries: Maximum number of attempts to retry
41
- in the case of concurrent updates to a rate limit key
42
- :param wrap_exceptions: Whether to wrap storage exceptions in
43
- :exc:`limits.errors.StorageError` before raising it.
44
- :param options: all remaining keyword arguments are passed
45
- directly to the constructor of :class:`etcd3.Etcd3Client`
46
- :raise ConfigurationError: when :pypi:`etcd3` is not available
47
- """
48
- parsed = urllib.parse.urlparse(uri)
49
- self.lib = self.dependencies["etcd3"].module
50
- self.storage: etcd3.Etcd3Client = self.lib.client(
51
- parsed.hostname, parsed.port, **options
52
- )
53
- self.max_retries = max_retries
54
- super().__init__(uri, wrap_exceptions=wrap_exceptions)
55
-
56
- @property
57
- def base_exceptions(
58
- self,
59
- ) -> type[Exception] | tuple[type[Exception], ...]: # pragma: no cover
60
- return self.lib.Etcd3Exception # type: ignore[no-any-return]
61
-
62
- def prefixed_key(self, key: str) -> bytes:
63
- return f"{self.PREFIX}/{key}".encode()
64
-
65
- def incr(
66
- self, key: str, expiry: int, elastic_expiry: bool = False, amount: int = 1
67
- ) -> int:
68
- retries = 0
69
- etcd_key = self.prefixed_key(key)
70
- while retries < self.max_retries:
71
- now = time.time()
72
- lease = self.storage.lease(expiry)
73
- window_end = now + expiry
74
- create_attempt = self.storage.transaction(
75
- compare=[self.storage.transactions.create(etcd_key) == "0"],
76
- success=[
77
- self.storage.transactions.put(
78
- etcd_key,
79
- f"{amount}:{window_end}".encode(),
80
- lease=lease.id,
81
- )
82
- ],
83
- failure=[self.storage.transactions.get(etcd_key)],
84
- )
85
- if create_attempt[0]:
86
- return amount
87
- else:
88
- cur, meta = create_attempt[1][0][0]
89
- cur_value, window_end = cur.split(b":")
90
- window_end = float(window_end)
91
- if window_end <= now:
92
- self.storage.revoke_lease(meta.lease_id)
93
- self.storage.delete(etcd_key)
94
- else:
95
- if elastic_expiry:
96
- self.storage.refresh_lease(meta.lease_id)
97
- window_end = now + expiry
98
- new = int(cur_value) + amount
99
- if self.storage.transaction(
100
- compare=[self.storage.transactions.value(etcd_key) == cur],
101
- success=[
102
- self.storage.transactions.put(
103
- etcd_key,
104
- f"{new}:{window_end}".encode(),
105
- lease=meta.lease_id,
106
- )
107
- ],
108
- failure=[],
109
- )[0]:
110
- return new
111
- retries += 1
112
- raise ConcurrentUpdateError(key, retries)
113
-
114
- def get(self, key: str) -> int:
115
- value, meta = self.storage.get(self.prefixed_key(key))
116
- if value:
117
- amount, expiry = value.split(b":")
118
- if float(expiry) > time.time():
119
- return int(amount)
120
- return 0
121
-
122
- def get_expiry(self, key: str) -> float:
123
- value, _ = self.storage.get(self.prefixed_key(key))
124
- if value:
125
- return float(value.split(b":")[1])
126
- return time.time()
127
-
128
- def check(self) -> bool:
129
- try:
130
- self.storage.status()
131
- return True
132
- except: # noqa
133
- return False
134
-
135
- def reset(self) -> int | None:
136
- return self.storage.delete_prefix(f"{self.PREFIX}/").deleted
137
-
138
- def clear(self, key: str) -> None:
139
- self.storage.delete(self.prefixed_key(key))
@@ -1,43 +0,0 @@
1
- limits/__init__.py,sha256=gPUFrt02kHF_syLjiVRSs-S4UVGpRMcM2VMFNhF6G24,748
2
- limits/_version.py,sha256=WS_qWia_2D12fx8eH9Ix80GnKTrf5Yaps8T8rEk3YVE,497
3
- limits/errors.py,sha256=s1el9Vg0ly-z92guvnvYNgKi3_aVqpiw_sufemiLLTI,662
4
- limits/limits.py,sha256=YzzZP8_ay_zlMMnnY2xhAcFTTFvFe5HEk8NQlvUTru4,4907
5
- limits/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- limits/strategies.py,sha256=14k8CFu9mfoVokEVxD48MjF61gBl-hr895brpL4XZUc,10899
7
- limits/typing.py,sha256=7G4-1MIh0pLOjBMG-gjNhpAqmX-hgQRzhD5_8ROVkls,4459
8
- limits/util.py,sha256=nk5QYvezFuXPq1OTEj04RrZFSWIH-khT0e_Dim6zGCw,6002
9
- limits/version.py,sha256=YwkF3dtq1KGzvmL3iVGctA8NNtGlK_0arrzZkZGVjUs,47
10
- limits/aio/__init__.py,sha256=yxvWb_ZmV245Hg2LqD365WC5IDllcGDMw6udJ1jNp1g,118
11
- limits/aio/strategies.py,sha256=9jnVU_nynm0zL1EjQLE3fus1vFbLqA-19ZRQhhexAGo,10776
12
- limits/aio/storage/__init__.py,sha256=gL4DGTV-XDksZxofaP__sGvwehN8MuuJQuRZeuGwiOQ,695
13
- limits/aio/storage/base.py,sha256=376Bs7l285vRTRa3-DqcVRnqOPdf3BpoCqbJr3XA9u8,6439
14
- limits/aio/storage/etcd.py,sha256=QJY8B9jNCNZLpo_cEMUyQkYsk4UIfoMhz7lJUl-ROmk,5081
15
- limits/aio/storage/memcached.py,sha256=kSX7B0CRS-qDVCQot4AW0rF3YwomXRyWg6W0_RyaHhM,10361
16
- limits/aio/storage/memory.py,sha256=KzpDnr-o3U6Ar2GkhAUTDokQ8tstUFUIe44_rYlMD3k,9765
17
- limits/aio/storage/mongodb.py,sha256=AyF5CxpuL0-O-PLZPBWPSbyL6JCRpKAlbIfczLSzFFY,19388
18
- limits/aio/storage/redis/__init__.py,sha256=p6amEcujcImDUxcYCsfBaLBKp1qH9xDXDjv3FWWfGow,14203
19
- limits/aio/storage/redis/bridge.py,sha256=cKs77RoCxUPfYD6_o1AiHfqpkeq_DFqMtVQKMLhEWdY,3183
20
- limits/aio/storage/redis/coredis.py,sha256=YT8cBx25MeSy9ApSJBfOK8VKduABTRefsnd9GhWscsI,7494
21
- limits/aio/storage/redis/redispy.py,sha256=ZAxHOFGAjRHsPzjfLowq5nMlVkK_YhVGHOOV8K4gMmU,8547
22
- limits/aio/storage/redis/valkey.py,sha256=f_-HPZhzNspywGybMNIL0F5uDZk76v8_K9wuC5ZeKhc,248
23
- limits/resources/redis/lua_scripts/acquire_moving_window.lua,sha256=5CFJX7D6T6RG5SFr6eVZ6zepmI1EkGWmKeVEO4QNrWo,483
24
- limits/resources/redis/lua_scripts/acquire_sliding_window.lua,sha256=OhVI1MAN_gT92P6r-2CEmvy1yvQVjYCCZxWIxfXYceY,1329
25
- limits/resources/redis/lua_scripts/clear_keys.lua,sha256=zU0cVfLGmapRQF9x9u0GclapM_IB2pJLszNzVQ1QRK4,184
26
- limits/resources/redis/lua_scripts/incr_expire.lua,sha256=Uq9NcrrcDI-F87TDAJexoSJn2SDgeXIUEYozCp9S3oA,195
27
- limits/resources/redis/lua_scripts/moving_window.lua,sha256=5hUZghISDh8Cbg8HJediM_OKjjNMF-0CBywWmsc93vA,430
28
- limits/resources/redis/lua_scripts/sliding_window.lua,sha256=qG3Yg30Dq54QpRUcR9AOrKQ5bdJiaYpCacTm6Kxblvc,713
29
- limits/storage/__init__.py,sha256=DArgeRfGilHWsfKz5qT_6OimP3S5u2E9lnzVst0n8Bw,2701
30
- limits/storage/base.py,sha256=6MprvcdNaTIPyN0ei9emcJLajYq07vDGSIKrmiaU6dU,7003
31
- limits/storage/etcd.py,sha256=oaNYOUryK-YmWKfmPtodRLjJGDMV4lGEYW9PU7FI_Ko,4745
32
- limits/storage/memcached.py,sha256=NJqHpbfZjT7YpjlK0dUX1-k_nb7HxPMQvBBapgUaHhY,11217
33
- limits/storage/memory.py,sha256=xLg3NDsnVEI3ds4QGS7MpH-VjjEJqwroOnz3LA8UQQ8,9226
34
- limits/storage/mongodb.py,sha256=UOn1owOnCJ_HxYQS2A82PKqJ_2gg46yWNBV6S73uVeE,18314
35
- limits/storage/redis.py,sha256=b2m5TrPNwS7NBY5btwCN0esGyCVQTwwgCn6f-sTcgFQ,10613
36
- limits/storage/redis_cluster.py,sha256=z6aONMl4p1AY78G3J0BbtK--uztz88krwnpiOsU61BM,4447
37
- limits/storage/redis_sentinel.py,sha256=AN0WtwHN88TvXk0C2uUE8l5Jhsd1ZxU8XSqrEyQSR20,4327
38
- limits/storage/registry.py,sha256=CxSaDBGR5aBJPFAIsfX9axCnbcThN3Bu-EH4wHrXtu8,650
39
- limits-4.7.2.dist-info/licenses/LICENSE.txt,sha256=T6i7kq7F5gIPfcno9FCxU5Hcwm22Bjq0uHZV3ElcjsQ,1061
40
- limits-4.7.2.dist-info/METADATA,sha256=nqjHZ5XRKBzhgdQ2kofnp2xS1w2Q25JBDPgPtOh0QOs,11379
41
- limits-4.7.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
42
- limits-4.7.2.dist-info/top_level.txt,sha256=C7g5ahldPoU2s6iWTaJayUrbGmPK1d6e9t5Nn0vQ2jM,7
43
- limits-4.7.2.dist-info/RECORD,,