async_request_client.py 2.0 KB

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