diff --git a/Pipfile b/Pipfile index a82d718..889c4e4 100644 --- a/Pipfile +++ b/Pipfile @@ -12,7 +12,7 @@ pytest-cov = "*" codecov = "*" [packages] -requests = "*" +requests = { extras = ["socks"] } [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index 7f56072..faee401 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c889ddb9cbefe66436c2a82bf83cac14e9a8f1a85ad8b2e9d0d8aa891f33a5fc" + "sha256": "4af012e674da3f8f42b23516f2f3bdd4571bc89b117efec071530308cf97e478" }, "pipfile-spec": 6, "requires": { @@ -37,7 +37,18 @@ ], "version": "==2.8" }, + "pysocks": { + "hashes": [ + "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299", + "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", + "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0" + ], + "version": "==1.7.1" + }, "requests": { + "extras": [ + "socks" + ], "hashes": [ "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" @@ -47,10 +58,10 @@ }, "urllib3": { "hashes": [ - "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", - "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86" + "sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293", + "sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745" ], - "version": "==1.25.6" + "version": "==1.25.7" } }, "develop": { @@ -104,6 +115,14 @@ "index": "pypi", "version": "==2.0.15" }, + "colorama": { + "hashes": [ + "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", + "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48" + ], + "markers": "sys_platform == 'win32'", + "version": "==0.4.1" + }, "coverage": { "hashes": [ "sha256:08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6", @@ -249,18 +268,18 @@ }, "pyparsing": { "hashes": [ - "sha256:4acadc9a2b96c19fe00932a38ca63e601180c39a189a696abce1eaab641447e1", - "sha256:61b5ed888beab19ddccab3478910e2076a6b5a0295dffc43021890e136edf764" + "sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f", + "sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a" ], - "version": "==2.4.4" + "version": "==2.4.5" }, "pytest": { "hashes": [ - "sha256:27abc3fef618a01bebb1f0d6d303d2816a99aa87a5968ebc32fe971be91eb1e6", - "sha256:58cee9e09242937e136dbb3dab466116ba20d6b7828c7620f23947f37eb4dae4" + "sha256:8e256fe71eb74e14a4d20a5987bb5e1488f0511ee800680aaedc62b9358714e8", + "sha256:ff0090819f669aaa0284d0f4aad1a6d9d67a6efdc6dd4eb4ac56b704f890a0d6" ], "index": "pypi", - "version": "==5.2.2" + "version": "==5.2.4" }, "pytest-cov": { "hashes": [ @@ -278,6 +297,9 @@ "version": "==2019.3" }, "requests": { + "extras": [ + "socks" + ], "hashes": [ "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" @@ -359,10 +381,10 @@ }, "urllib3": { "hashes": [ - "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", - "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86" + "sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293", + "sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745" ], - "version": "==1.25.6" + "version": "==1.25.7" }, "wcwidth": { "hashes": [ diff --git a/README.rst b/README.rst index 633f5ef..67de2dc 100644 --- a/README.rst +++ b/README.rst @@ -176,6 +176,25 @@ Microsoft Store. Так как API является закрытым и испо Первым треком из примера является следующий трек: music.yandex.ru/album/**1193829**/track/**10994777** +Выполнение запросов с использование прокси: + +.. code:: python + + from yandex_music.utils.request import Request + from yandex_music.client import Client + + request = Request(proxy_url='socks5://user:password@host:port') + client = Client(request=request) + +Примеры proxy url: + +- socks5://user:password@host:port +- http://host:port +- https://host:port +- http://user:password@host + +Больше примеров тут: `proxies - advanced usage - requests `_ + -------------------- Изучение по примерам -------------------- diff --git a/yandex_music/client.py b/yandex_music/client.py index 550289d..8d0f9b4 100644 --- a/yandex_music/client.py +++ b/yandex_music/client.py @@ -77,7 +77,11 @@ class Client(YandexMusicObject): self.base_url = base_url self.oauth_url = oauth_url - self._request = request or Request(self) + if request: + self._request = request + self._request.set_and_return_client(self) + else: + self._request = Request(self) self.account = self.account_status().account diff --git a/yandex_music/utils/request.py b/yandex_music/utils/request.py index 3f20d8f..e51d8f3 100644 --- a/yandex_music/utils/request.py +++ b/yandex_music/utils/request.py @@ -24,26 +24,30 @@ class Request: client (:obj:`yandex_music.Client`): Объект класса :class:`yandex_music.Client` представляющий клиент Yandex Music. headers (:obj:`dict`, optional): Заголовки передаваемые с каждым запросом. - proxies (:obj:`dict`, optional): Прокси. + proxy_url (:obj:`str`, optional): Прокси. """ def __init__(self, - client, + client=None, headers=None, - proxies=None): - - self.client = client - + proxy_url=None): self.headers = headers or HEADERS.copy() - if self.client.token: - self.set_authorization(self.client.token) + self.client = self.set_and_return_client(client) - self.proxies = proxies # TODO + self.proxies = {'http': proxy_url, 'https': proxy_url} if proxy_url else None def set_authorization(self, token): self.headers.update({'Authorization': f'OAuth {token}'}) + def set_and_return_client(self, client): + self.client = client + + if self.client and self.client.token: + self.set_authorization(self.client.token) + + return self.client + @staticmethod def _convert_camel_to_snake(text): s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', text) @@ -107,21 +111,21 @@ class Request: raise NetworkError(f'{message} ({resp.status_code})') def get(self, url, params=None, timeout=5, *args, **kwargs): - result = self._request_wrapper('GET', url, params=params, headers=self.headers, timeout=timeout, - *args, **kwargs) + result = self._request_wrapper('GET', url, params=params, headers=self.headers, proxies=self.proxies, + timeout=timeout, *args, **kwargs) return self._parse(result.content).result def post(self, url, data=None, timeout=5, *args, **kwargs): - result = self._request_wrapper('POST', url, headers=self.headers, data=data, timeout=timeout, - *args, **kwargs) + result = self._request_wrapper('POST', url, headers=self.headers, proxies=self.proxies, data=data, + timeout=timeout, *args, **kwargs) return self._parse(result.content).result def retrieve(self, url, timeout=5, *args, **kwargs): - return self._request_wrapper('GET', url, timeout=timeout, *args, **kwargs) + return self._request_wrapper('GET', url, proxies=self.proxies, timeout=timeout, *args, **kwargs) def download(self, url, filename, timeout=5, *args, **kwargs): - result = self.retrieve(url, timeout=timeout, *args, *kwargs) + result = self.retrieve(url, proxies=self.proxies, timeout=timeout, *args, *kwargs) with open(filename, 'wb') as f: f.write(result.content)