limits 5.3.0__py3-none-any.whl → 5.4.0__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.
limits/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-06-13T16:23:24-0700",
11
+ "date": "2025-06-16T08:51:06-0700",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "311fe101b2d63c03e8c6a8f0ab363dd49f3e733b",
15
- "version": "5.3.0"
14
+ "full-revisionid": "8a5a8254708e2799a762b28482d2a4da7b71b04e",
15
+ "version": "5.4.0"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
limits/aio/strategies.py CHANGED
@@ -32,6 +32,8 @@ class RateLimiter(ABC):
32
32
  :param identifiers: variable list of strings to uniquely identify the
33
33
  limit
34
34
  :param cost: The cost of this hit, default 1
35
+
36
+ :return: True if ``cost`` could be deducted from the rate limit without exceeding it
35
37
  """
36
38
  raise NotImplementedError
37
39
 
@@ -44,6 +46,8 @@ class RateLimiter(ABC):
44
46
  :param identifiers: variable list of strings to uniquely identify the
45
47
  limit
46
48
  :param cost: The expected cost to be consumed, default 1
49
+
50
+ :return: True if the rate limit is not depleted
47
51
  """
48
52
  raise NotImplementedError
49
53
 
@@ -88,6 +92,8 @@ class MovingWindowRateLimiter(RateLimiter):
88
92
  :param identifiers: variable list of strings to uniquely identify the
89
93
  limit
90
94
  :param cost: The cost of this hit, default 1
95
+
96
+ :return: True if ``cost`` could be deducted from the rate limit without exceeding it
91
97
  """
92
98
 
93
99
  return await cast(MovingWindowSupport, self.storage).acquire_entry(
@@ -102,6 +108,8 @@ class MovingWindowRateLimiter(RateLimiter):
102
108
  :param identifiers: variable list of strings to uniquely identify the
103
109
  limit
104
110
  :param cost: The expected cost to be consumed, default 1
111
+
112
+ :return: True if the rate limit is not depleted
105
113
  """
106
114
  res = await cast(MovingWindowSupport, self.storage).get_moving_window(
107
115
  item.key_for(*identifiers),
@@ -144,6 +152,8 @@ class FixedWindowRateLimiter(RateLimiter):
144
152
  :param identifiers: variable list of strings to uniquely identify the
145
153
  limit
146
154
  :param cost: The cost of this hit, default 1
155
+
156
+ :return: True if ``cost`` could be deducted from the rate limit without exceeding it
147
157
  """
148
158
 
149
159
  return (
@@ -163,6 +173,8 @@ class FixedWindowRateLimiter(RateLimiter):
163
173
  :param identifiers: variable list of strings to uniquely identify the
164
174
  limit
165
175
  :param cost: The expected cost to be consumed, default 1
176
+
177
+ :return: True if the rate limit is not depleted
166
178
  """
167
179
 
168
180
  return (
@@ -225,6 +237,8 @@ class SlidingWindowCounterRateLimiter(RateLimiter):
225
237
  :param identifiers: variable list of strings to uniquely identify this
226
238
  instance of the limit
227
239
  :param cost: The cost of this hit, default 1
240
+
241
+ :return: True if ``cost`` could be deducted from the rate limit without exceeding it
228
242
  """
229
243
  return await cast(
230
244
  SlidingWindowCounterSupport, self.storage
@@ -243,6 +257,8 @@ class SlidingWindowCounterRateLimiter(RateLimiter):
243
257
  :param identifiers: variable list of strings to uniquely identify this
244
258
  instance of the limit
245
259
  :param cost: The expected cost to be consumed, default 1
260
+
261
+ :return: True if the rate limit is not depleted
246
262
  """
247
263
 
248
264
  previous_count, previous_expires_in, current_count, _ = await cast(
limits/limits.py CHANGED
@@ -91,7 +91,10 @@ class RateLimitItem(metaclass=RateLimitItemMeta):
91
91
 
92
92
  """
93
93
 
94
- return granularity_string.lower() in cls.GRANULARITY.name
94
+ return granularity_string.lower() in {
95
+ cls.GRANULARITY.name,
96
+ f"{cls.GRANULARITY.name}s", # allow plurals like days, hours etc.
97
+ }
95
98
 
96
99
  def get_expiry(self) -> int:
97
100
  """
limits/strategies.py CHANGED
@@ -32,6 +32,8 @@ class RateLimiter(metaclass=ABCMeta):
32
32
  :param identifiers: variable list of strings to uniquely identify this
33
33
  instance of the limit
34
34
  :param cost: The cost of this hit, default 1
35
+
36
+ :return: True if ``cost`` could be deducted from the rate limit without exceeding it
35
37
  """
36
38
  raise NotImplementedError
37
39
 
@@ -44,6 +46,8 @@ class RateLimiter(metaclass=ABCMeta):
44
46
  :param identifiers: variable list of strings to uniquely identify this
45
47
  instance of the limit
46
48
  :param cost: The expected cost to be consumed, default 1
49
+
50
+ :return: True if the rate limit is not depleted
47
51
  """
48
52
  raise NotImplementedError
49
53
 
@@ -86,7 +90,8 @@ class MovingWindowRateLimiter(RateLimiter):
86
90
  :param identifiers: variable list of strings to uniquely identify this
87
91
  instance of the limit
88
92
  :param cost: The cost of this hit, default 1
89
- :return: (reset time, remaining)
93
+
94
+ :return: True if ``cost`` could be deducted from the rate limit without exceeding it
90
95
  """
91
96
 
92
97
  return cast(MovingWindowSupport, self.storage).acquire_entry(
@@ -101,6 +106,8 @@ class MovingWindowRateLimiter(RateLimiter):
101
106
  :param identifiers: variable list of strings to uniquely identify this
102
107
  instance of the limit
103
108
  :param cost: The expected cost to be consumed, default 1
109
+
110
+ :return: True if the rate limit is not depleted
104
111
  """
105
112
 
106
113
  return (
@@ -142,6 +149,8 @@ class FixedWindowRateLimiter(RateLimiter):
142
149
  :param identifiers: variable list of strings to uniquely identify this
143
150
  instance of the limit
144
151
  :param cost: The cost of this hit, default 1
152
+
153
+ :return: True if ``cost`` could be deducted from the rate limit without exceeding it
145
154
  """
146
155
 
147
156
  return (
@@ -161,6 +170,8 @@ class FixedWindowRateLimiter(RateLimiter):
161
170
  :param identifiers: variable list of strings to uniquely identify this
162
171
  instance of the limit
163
172
  :param cost: The expected cost to be consumed, default 1
173
+
174
+ :return: True if the rate limit is not depleted
164
175
  """
165
176
 
166
177
  return self.storage.get(item.key_for(*identifiers)) < item.amount - cost + 1
@@ -216,6 +227,8 @@ class SlidingWindowCounterRateLimiter(RateLimiter):
216
227
  :param identifiers: variable list of strings to uniquely identify this
217
228
  instance of the limit
218
229
  :param cost: The cost of this hit, default 1
230
+
231
+ :return: True if ``cost`` could be deducted from the rate limit without exceeding it
219
232
  """
220
233
  return cast(
221
234
  SlidingWindowCounterSupport, self.storage
@@ -234,6 +247,8 @@ class SlidingWindowCounterRateLimiter(RateLimiter):
234
247
  :param identifiers: variable list of strings to uniquely identify this
235
248
  instance of the limit
236
249
  :param cost: The expected cost to be consumed, default 1
250
+
251
+ :return: True if the rate limit is not depleted
237
252
  """
238
253
  previous_count, previous_expires_in, current_count, _ = cast(
239
254
  SlidingWindowCounterSupport, self.storage
limits/util.py CHANGED
@@ -22,8 +22,10 @@ SINGLE_EXPR = re.compile(
22
22
  r"""
23
23
  \s*([0-9]+)
24
24
  \s*(/|\s*per\s*)
25
- \s*([0-9]+)
26
- *\s*(hour|minute|second|day|month|year)s?\s*""",
25
+ \s*([0-9]+)?
26
+ \s*([a-z]+)
27
+ \s*
28
+ """,
27
29
  re.IGNORECASE | re.VERBOSE,
28
30
  )
29
31
  EXPR = re.compile(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: limits
3
- Version: 5.3.0
3
+ Version: 5.4.0
4
4
  Summary: Rate limiting utilities
5
5
  Home-page: https://limits.readthedocs.org
6
6
  Author: Ali-Akber Saifee
@@ -1,14 +1,14 @@
1
1
  limits/__init__.py,sha256=gPUFrt02kHF_syLjiVRSs-S4UVGpRMcM2VMFNhF6G24,748
2
- limits/_version.py,sha256=zdxTHiQVSU3wNvKwUyOaoK8MMVvzbTzqFicCzdjC7j4,497
2
+ limits/_version.py,sha256=yzZjmmcS6zK5TYwp241WU_2TWLKQak_9QvmKSaY24EY,497
3
3
  limits/errors.py,sha256=s1el9Vg0ly-z92guvnvYNgKi3_aVqpiw_sufemiLLTI,662
4
- limits/limits.py,sha256=YzzZP8_ay_zlMMnnY2xhAcFTTFvFe5HEk8NQlvUTru4,4907
4
+ limits/limits.py,sha256=EztiGCXBVwIqNtps77HiW6vLlMO93wCh7mu5W7BuhwI,5011
5
5
  limits/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- limits/strategies.py,sha256=blVIWefjRmDZvD78tneZ9aHUgCGWddyHjJaPuKxP07s,10169
6
+ limits/strategies.py,sha256=Q03NTAyADtwMalhRkOSdk6UE1gVfVt5n258xVyA481o,10732
7
7
  limits/typing.py,sha256=pVt5D23MhQSUGqi0MBG5FCSqDwta2ygu18BpKvJFxow,3283
8
- limits/util.py,sha256=nk5QYvezFuXPq1OTEj04RrZFSWIH-khT0e_Dim6zGCw,6002
8
+ limits/util.py,sha256=283O2aXnN7DmaqjTeTiF-KYn5wVbnpXJ8vb-6LvY5lY,5983
9
9
  limits/version.py,sha256=YwkF3dtq1KGzvmL3iVGctA8NNtGlK_0arrzZkZGVjUs,47
10
10
  limits/aio/__init__.py,sha256=yxvWb_ZmV245Hg2LqD365WC5IDllcGDMw6udJ1jNp1g,118
11
- limits/aio/strategies.py,sha256=XSNE0SOSbJDjlodA_8AsL7oBYdfIn3JYh6iuR2z_cyU,10132
11
+ limits/aio/strategies.py,sha256=ip7NJ_6FvEtICr90tesayaXcsqrmpG7VlC3PwxbfiVQ,10736
12
12
  limits/aio/storage/__init__.py,sha256=vKeArUnN1ld_0mQOBBZPCjaQgM5xI1GBPM7_F2Ydz5c,646
13
13
  limits/aio/storage/base.py,sha256=56UyNz3I3J-4pQecjsaCK4pUC4L3R_9GzDnutdTrfKs,6706
14
14
  limits/aio/storage/memory.py,sha256=-U_GWPWmR77Hzi1Oa1_L1WjiAlROTS8PNG8PROAm13c,9842
@@ -37,8 +37,8 @@ limits/storage/redis.py,sha256=zTwxV5qosxGBTrkZmD4UWQdvavDbWpYHXY7H3hXH-Sw,10791
37
37
  limits/storage/redis_cluster.py,sha256=GkL8GCQFfxDriMzsPMkaj6pMEX5FvQXYpUtXLY5q8fQ,4621
38
38
  limits/storage/redis_sentinel.py,sha256=OSb61DxgUxMgXSIjaM_pF5-entD8XntD56xt0rFu89k,4479
39
39
  limits/storage/registry.py,sha256=CxSaDBGR5aBJPFAIsfX9axCnbcThN3Bu-EH4wHrXtu8,650
40
- limits-5.3.0.dist-info/licenses/LICENSE.txt,sha256=T6i7kq7F5gIPfcno9FCxU5Hcwm22Bjq0uHZV3ElcjsQ,1061
41
- limits-5.3.0.dist-info/METADATA,sha256=saaz-nkRG9gi-N5HyQ2eFhNjvPe2TrJnScsaZTkowEM,10900
42
- limits-5.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
43
- limits-5.3.0.dist-info/top_level.txt,sha256=C7g5ahldPoU2s6iWTaJayUrbGmPK1d6e9t5Nn0vQ2jM,7
44
- limits-5.3.0.dist-info/RECORD,,
40
+ limits-5.4.0.dist-info/licenses/LICENSE.txt,sha256=T6i7kq7F5gIPfcno9FCxU5Hcwm22Bjq0uHZV3ElcjsQ,1061
41
+ limits-5.4.0.dist-info/METADATA,sha256=TbligMc6UvZHAIo_DOoYF31XmWZx64Hghgh1RULEQb4,10900
42
+ limits-5.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
43
+ limits-5.4.0.dist-info/top_level.txt,sha256=C7g5ahldPoU2s6iWTaJayUrbGmPK1d6e9t5Nn0vQ2jM,7
44
+ limits-5.4.0.dist-info/RECORD,,
File without changes