muffin-rest 13.0.1__py3-none-any.whl → 13.0.3__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.
muffin_rest/limits.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import abc
2
+ from asyncio import Lock
2
3
  from time import time
3
4
  from typing import Any
4
5
 
@@ -13,13 +14,19 @@ class RateLimiter(abc.ABC):
13
14
  limit (int): The limit of requests.
14
15
  period (int): The period of time in seconds.
15
16
  """
17
+ self.lock = Lock()
16
18
  self.limit = limit
17
19
  self.period = period
18
20
 
19
- @abc.abstractmethod
20
21
  async def check(self, key: str) -> bool:
21
22
  """Check the request."""
22
- raise NotImplementedError
23
+ async with self.lock:
24
+ return await self._check(key)
25
+
26
+ @abc.abstractmethod
27
+ async def _check(self, key: str) -> bool:
28
+ """Check the request."""
29
+ raise NotImplementedError("Subclasses must implement this method.")
23
30
 
24
31
 
25
32
  class MemoryRateLimiter(RateLimiter):
@@ -29,7 +36,7 @@ class MemoryRateLimiter(RateLimiter):
29
36
  super().__init__(limit, **opts)
30
37
  self.storage: dict[Any, tuple[float, int]] = {}
31
38
 
32
- async def check(self, key: str) -> bool:
39
+ async def _check(self, key: str) -> bool:
33
40
  """Check the request."""
34
41
  now = time()
35
42
  storage = self.storage
@@ -53,8 +60,6 @@ class MemoryRateLimiter(RateLimiter):
53
60
  class RedisRateLimiter(RateLimiter):
54
61
  """Redis rate limiter."""
55
62
 
56
- # TODO: Asyncio lock
57
-
58
63
  def __init__(self, limit: int, *, redis, **opts):
59
64
  """Initialize the rate limiter.
60
65
 
@@ -66,12 +71,10 @@ class RedisRateLimiter(RateLimiter):
66
71
  super().__init__(limit, **opts)
67
72
  self.redis = redis
68
73
 
69
- async def check(self, key: str) -> bool:
74
+ async def _check(self, key: str) -> bool:
70
75
  """Check the request."""
71
- value = await self.redis.get(key)
72
- if value is None:
73
- await self.redis.setex(key, self.period, 1)
74
- return True
76
+ current = await self.redis.incr(key)
77
+ if current == 1:
78
+ await self.redis.expire(key, self.period)
75
79
 
76
- await self.redis.incr(key)
77
- return int(value) < self.limit
80
+ return current <= self.limit
@@ -1,8 +1,9 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: muffin-rest
3
- Version: 13.0.1
3
+ Version: 13.0.3
4
4
  Summary: The package provides enhanced support for writing REST APIs with Muffin framework
5
5
  License: MIT
6
+ License-File: LICENSE
6
7
  Keywords: rest,api,muffin,asgi,asyncio,trio
7
8
  Author: Kirill Klenov
8
9
  Author-email: horneds@gmail.com
@@ -18,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.10
18
19
  Classifier: Programming Language :: Python :: 3.11
19
20
  Classifier: Programming Language :: Python :: 3.12
20
21
  Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
21
23
  Classifier: Topic :: Internet :: WWW/HTTP
22
24
  Provides-Extra: peewee
23
25
  Provides-Extra: sqlalchemy
@@ -3,7 +3,7 @@ muffin_rest/api.py,sha256=bdbXMPiZi5yXf7_u3XB_gaGDHZKzDPqnnFnrwHoO1Rs,3799
3
3
  muffin_rest/errors.py,sha256=Todg7CrCE1ufOsyyARI2Bv-RqNPH4Rl1p-Tkpq7VYrA,1151
4
4
  muffin_rest/filters.py,sha256=nWlwDLuId-mmP3tgZjp1joYCVx0k9ekV42fPIMMKphM,5920
5
5
  muffin_rest/handler.py,sha256=97nkx5rGB2CE_7oPG4UOLVw7b4UcGbubkSt1m_LrHhk,10762
6
- muffin_rest/limits.py,sha256=Fnlu4Wj3B-BzpahLK-rDbd1GEd7CEQ3zxyOD0vee7GE,2007
6
+ muffin_rest/limits.py,sha256=X6qwuQPUdKJiPRgiKLY2NquXZlrpbx7BYHH3njw9ros,2168
7
7
  muffin_rest/marshmallow.py,sha256=-MyMKiaMTfiWw4y-4adpfoQd05HV1vEKqSXJh8eD3xg,548
8
8
  muffin_rest/mongo/__init__.py,sha256=dck5zDEv0P3v_2CdlPI7Nbg8xay-EIzy9Y0yksEZkxw,4665
9
9
  muffin_rest/mongo/filters.py,sha256=yIxIDVqMn6SoDgVhCqiTxYetw0hoaf_3jIvX2Vnizok,964
@@ -33,7 +33,7 @@ muffin_rest/sqlalchemy/types.py,sha256=Exm-zAQCtPAwXvYcCTtPRqSa-wTEWRcH_v2YSsJkB
33
33
  muffin_rest/swagger.html,sha256=2uGLu_KpkYf925KnDKHBJmV9pm6OHn5C3BWScESsUS8,1736
34
34
  muffin_rest/types.py,sha256=5NY9gPTIptv6U2Qab2xMXlS_jZuTuR0bquFFwWRURcA,510
35
35
  muffin_rest/utils.py,sha256=c08E4HJ4SLYC-91GKPEbsyKTZ4sZbTN4qDqJbNg_HTE,2076
36
- muffin_rest-13.0.1.dist-info/LICENSE,sha256=xHPkOZhjyKBMOwXpWn9IB_BVLjrrMxv2M9slKkHj2hM,1082
37
- muffin_rest-13.0.1.dist-info/METADATA,sha256=314stUC6_wkJlpM9Ms8IJqiodDBH3eojfuQwq6mvH_8,4912
38
- muffin_rest-13.0.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
39
- muffin_rest-13.0.1.dist-info/RECORD,,
36
+ muffin_rest-13.0.3.dist-info/METADATA,sha256=sk-98taZjJD1AJ5dcMGLAlSnlLj5EIJZsYzHuxfv5-o,4985
37
+ muffin_rest-13.0.3.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
38
+ muffin_rest-13.0.3.dist-info/licenses/LICENSE,sha256=xHPkOZhjyKBMOwXpWn9IB_BVLjrrMxv2M9slKkHj2hM,1082
39
+ muffin_rest-13.0.3.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.3
2
+ Generator: poetry-core 2.2.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any