async_request_client.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import asyncio
  2. from typing import Optional, Dict
  3. import aiohttp
  4. class AsyncRequestClient:
  5. """
  6. 可独立复用的异步请求客户端,支持重试、日志结构化和限流预留
  7. """
  8. def __init__(self, logger=None, aliyun_log=None,max_retries=3, timeout=30):
  9. self.logger = logger
  10. self.aliyun_log = aliyun_log
  11. self.max_retries = max_retries
  12. self.timeout = timeout
  13. async def request(self, session: aiohttp.ClientSession, method: str, url: str, **kwargs) -> Optional[Dict]:
  14. retries = 0
  15. while retries < self.max_retries:
  16. try:
  17. if self.logger:
  18. self.logger.info(f"请求 {method} {url}, 尝试 {retries+1}/{self.max_retries}")
  19. async with session.request(method, url, **kwargs) as response:
  20. response.raise_for_status()
  21. resp = await response.json()
  22. if resp.get('code') != 0:
  23. retries += 1
  24. if self.logger:
  25. self.logger.warning(f"请求失败 {resp}, 重试 {retries}/{self.max_retries}")
  26. return resp
  27. except Exception as e:
  28. retries += 1
  29. if retries >= self.max_retries:
  30. if self.logger:
  31. self.logger.error(f"请求失败达到最大重试次数: {e}")
  32. if self.aliyun_log:
  33. self.aliyun_log.logging(
  34. code="9006",
  35. message=f"请求异常达到最大重试次数",
  36. data=f"{url}"
  37. )
  38. return
  39. if self.logger:
  40. self.logger.warning(f"请求失败 {e}, 重试 {retries}/{self.max_retries}")
  41. await asyncio.sleep(1)