handle rate limits
This commit is contained in:
parent
b906abe2b1
commit
788f8550c7
2 changed files with 35 additions and 2 deletions
32
utils.py
32
utils.py
|
|
@ -34,3 +34,35 @@ def removeprefix(s, prefix):
|
|||
except AttributeError:
|
||||
# compatibility for pre-3.9
|
||||
return s[len(prefix):] if s.startswith(prefix) else s
|
||||
|
||||
async def sleep_until(dt):
|
||||
await anyio.sleep((dt - datetime.now(timezone.utc)).total_seconds())
|
||||
|
||||
class HandleRateLimits:
|
||||
def __init__(self, http):
|
||||
self.http = http
|
||||
|
||||
def request(self, *args, **kwargs):
|
||||
return _RateLimitContextManager(self.http, args, kwargs)
|
||||
|
||||
class _RateLimitContextManager(contextlib.AbstractAsyncContextManager):
|
||||
def __init__(self, http, args, kwargs):
|
||||
self.http = http
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
|
||||
async def __aenter__(self):
|
||||
self._request_cm = self.http.request(*self.args, **self.kwargs)
|
||||
return await self._do_enter()
|
||||
|
||||
async def _do_enter(self):
|
||||
resp = await self._request_cm.__aenter__()
|
||||
if resp.headers.get('X-RateLimit-Remaining') not in {'0', '1'}:
|
||||
return resp
|
||||
|
||||
await sleep_until(datetime.fromisoformat(resp.headers['X-RateLimit-Reset']))
|
||||
await self._request_cm.__aexit__(*(None,)*3)
|
||||
return await self.__aenter__()
|
||||
|
||||
async def __aexit__(self, *excinfo):
|
||||
return await self._request_cm.__aexit__(*excinfo)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue