generate_async_version.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #!/usr/bin/env python3
  2. """Generate async version of client.py and request.py."""
  3. import subprocess
  4. DISCLAIMER = "# THIS IS AUTO GENERATED COPY OF client.py. DON'T EDIT IN BY HANDS #"
  5. DISCLAIMER = f'{"#" * len(DISCLAIMER)}\n{DISCLAIMER}\n{"#" * len(DISCLAIMER)}\n\n'
  6. REQUEST_METHODS = ('_request_wrapper', 'get', 'post', 'retrieve', 'download')
  7. def gen_request(output_request_filename: str) -> None:
  8. """Generate async version of request.py."""
  9. with open('yandex_music/utils/request.py', 'r', encoding='UTF-8') as f:
  10. code = f.read()
  11. code = code.replace('import requests', 'import asyncio\nimport aiohttp\nimport aiofiles')
  12. # order make sense
  13. code = code.replace('resp.content', 'content')
  14. code = code.replace(
  15. 'resp = requests.request(*args, **kwargs)',
  16. f'async with aiohttp.request(*args, **kwargs) as _resp:\n{" " * 16}resp = _resp\n{" " * 16}content = await resp.content.read()', # noqa: E501
  17. )
  18. code = code.replace('except requests.Timeout', 'except asyncio.TimeoutError')
  19. code = code.replace('except requests.RequestException', 'except aiohttp.ClientError')
  20. code = code.replace('resp.status_code', 'resp.status')
  21. for method in REQUEST_METHODS:
  22. code = code.replace(f'def {method}', f'async def {method}')
  23. code = code.replace(f'self.{method}(', f'await self.{method}(')
  24. code = code.replace('proxies=self.proxies', 'proxy=self.proxy_url')
  25. code = code.replace(
  26. "kwargs['timeout'] = self._timeout",
  27. f"kwargs['timeout'] = aiohttp.ClientTimeout(total=self._timeout)\n{' ' * 8}else:\n{' ' * 12}kwargs['timeout'] = aiohttp.ClientTimeout(total=kwargs['timeout'])", # noqa: E501
  28. )
  29. # download method
  30. code = code.replace('with open', 'async with aiofiles.open')
  31. code = code.replace('f.write', 'await f.write')
  32. # docs
  33. code = code.replace('`requests`', '`aiohttp`')
  34. code = code.replace('requests.request', 'aiohttp.request')
  35. code = DISCLAIMER + code
  36. with open(output_request_filename, 'w', encoding='UTF-8') as f:
  37. f.write(code)
  38. def gen_client(output_client_filename: str) -> None:
  39. """Generate async version of client.py."""
  40. with open('yandex_music/client.py', 'r', encoding='UTF-8') as f:
  41. code = f.read()
  42. code = code.replace('Client', 'ClientAsync')
  43. code = code.replace(
  44. 'from yandex_music.utils.request import Request', 'from yandex_music.utils.request_async import Request'
  45. )
  46. code = code.replace('def wrapper', 'async def wrapper')
  47. code = code.replace('result = method(', 'result = await method(')
  48. code = code.replace('@log\n def', '@log\n async def')
  49. code = code.replace('self.account_status', 'await self.account_status')
  50. for method in REQUEST_METHODS:
  51. code = code.replace(f'self._request.{method}', f'await self._request.{method}')
  52. for method in ('_like_action', '_dislike_action', '_get_list', '_get_likes'):
  53. code = code.replace(f'def {method}', f'async def {method}')
  54. code = code.replace(f'self.{method}(', f'await self.{method}(')
  55. # specific cases
  56. code = code.replace('self.users_playlists_change(', 'await self.users_playlists_change(')
  57. code = code.replace('self.rotor_station_feedback(', 'await self.rotor_station_feedback(')
  58. code = code.replace('return DownloadInfo.de_list', 'return await DownloadInfo.de_list_async')
  59. code = DISCLAIMER + code
  60. with open(output_client_filename, 'w', encoding='UTF-8') as f:
  61. f.write(code)
  62. if __name__ == '__main__':
  63. request_filename = 'yandex_music/utils/request_async.py'
  64. client_filename = 'yandex_music/client_async.py'
  65. gen_request(request_filename)
  66. gen_client(client_filename)
  67. for file in (request_filename, client_filename):
  68. subprocess.run(['ruff', 'format', '--quiet', file]) # noqa: S603, S607
  69. subprocess.run(['ruff', '--quiet', '--fix', file]) # noqa: S603, S607
  70. subprocess.run(['ruff', 'format', '--quiet', file]) # noqa: S603, S607