我想使用 aiohttp
客户端为我们的服务创建一个异步 SDK。我一直无法弄清楚如何限制 ClientSession()
以每秒仅发出 N 个请求。
class AsyncHTTPClient:
def __init__(self, api_token, per_second_limit=10):
self._client = aiohttp.ClienSession(
headers = {"Authorization": "Bearer f{api_token}"}
)
self._throttler = asyncio.Semaphore(per_second_limit)
async def _make_request(self, method, url, **kwargs):
async with self._throttler:
return await self._client.request(method, url, **kwargs)
async def get(self, url, **params):
return await self._make_request("GET", url, **params)
async def close(self):
await self._client.close()
我有一个带有 get, post, patch, put, delete
方法的类,作为对 _make_request
的调用实现。
#As a user of the SDK I run the following code.
async def main():
try:
urls = [some_url * 100]
client = AsyncHTTPClient(my_token, per_second_limit=20)
await asyncio.gather(*[client.get(url) for url in urls])
finally:
await client.close()
asyncio.run(main())
asyncio.Semaphore
限制并发。也就是说,当调用 main()
函数时,async with self._throttler
中使用的 client._make_request
将并发限制为 20 个请求。但是,如果 20 个请求在 1 秒内完成,则将继续发出请求。我想要做的是确保在一秒钟内只发出 N 个请求(即 20 个)。如果所有 20 个请求在 0.8 秒内完成,则休眠 0.2 秒,然后再次处理请求。
我使用 asyncio.Queue
示例查找了一些 workers
示例,但我不确定如何在我的 SDK 中实现它,因为创建 workers
必须由用户使用这个 SDK,我想避免这种情况,我希望 AsyncHTTPClient
处理每秒请求数限制。
任何建议/建议/样品将不胜感激。