import os
import asyncio
import logging
from redis.asyncio import Redis as AsyncRedis
from pyrate_limiter import Duration, Rate, Limiter, RedisBucket
async_redis = AsyncRedis(
host=os.environ["REDIS_HOST"],
port=int(os.environ["REDIS_PORT"]),
password=os.environ["REDIS_PASSWORD"],
decode_responses=True,
socket_keepalive=True,
protocol=3,
)
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)
rate = Rate(1, Duration.SECOND)
class Example:
def __init__(self, limiter):
self.limiter = limiter
async def func(self) -> None:
await self.limiter.try_acquire("test") # After reading the docs, I am not sure what I need to put here.
# No errors with the bucket, so we can run our rate-limited code:
logger.info("Start")
await asyncio.sleep(2) # Imitate a long running function, e.g. a network request.
logger.info("End.")
async def main():
redis_bucket = await RedisBucket.init([rate], async_redis, "my-bucket-name")
limiter = Limiter(
redis_bucket,
max_delay=5000,
raise_when_fail=True
)
e = Example(limiter)
await asyncio.gather(
*[e.func() for _ in range(10)]
)
asyncio.run(main())
Error
Traceback (most recent call last):
File "/opt/pysetup/try_rate_limit.py", line 44, in <module>
asyncio.run(main())
File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/opt/pysetup/try_rate_limit.py", line 40, in main
await asyncio.gather(
File "/opt/pysetup/try_rate_limit.py", line 23, in request
await self.limiter.try_acquire("test")
File "/opt/pysetup/.venv/lib/python3.11/site-packages/pyrate_limiter/limiter.py", line 307, in _handle_async_result
result = await result
^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.11/site-packages/pyrate_limiter/limiter.py", line 259, in _put_async
result = await result
^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.11/site-packages/pyrate_limiter/limiter.py", line 183, in _handle_async
assert isinstance(delay, int), "Delay not integer"
AssertionError: Delay not integer
Expected behavior
I debugged the current delay value and in the code example I have:
assert isinstance(delay, int), f"Delay not integer: {delay=}"
AssertionError: Delay not integer: delay=998.0
Without further debugging it is not clear right away from where I got 998.0 and what is a problem with a float.
Make a descriptive useful message. An example:
assert isinstance(delay, int), f'Expected an integer for "Delay", but got: {delay} of type {type(delay)}'
The error is confusing. Is this not documented or I overlooked something in the documentation?
Reproducible example
Error
Expected behavior
I debugged the current
delay
value and in the code example I have:Without further debugging it is not clear right away from where I got
998.0
and what is a problem with afloat
.UPDATE 1
Allowing a
float
at least allows to do not fail the code. I see a warning mentioned in https://github.com/vutran1710/PyrateLimiter/issues/128 but that is OK for now.