26 lines
804 B
Python
26 lines
804 B
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import time
|
|
from collections import deque
|
|
|
|
|
|
class RateLimiter:
|
|
def __init__(self, requests_per_second: float = 1.0) -> None:
|
|
self._min_interval = 1.0 / requests_per_second
|
|
self._timestamps: deque[float] = deque()
|
|
self._lock = asyncio.Lock()
|
|
|
|
async def acquire(self) -> None:
|
|
async with self._lock:
|
|
now = time.monotonic()
|
|
while self._timestamps and self._timestamps[0] <= now - self._min_interval:
|
|
self._timestamps.popleft()
|
|
|
|
if self._timestamps:
|
|
wait_time = self._timestamps[0] + self._min_interval - now
|
|
if wait_time > 0:
|
|
await asyncio.sleep(wait_time)
|
|
|
|
self._timestamps.append(time.monotonic())
|