New supported objects: Response, PromoCodeStatus
The following method are wrapped: /account/consume-promo-code Added error receiver The following fields are optional: Ratings.day, InvocationInfo.exec_duration_millis, Account.registered_at Request now accepts client object, not token
このコミットが含まれているのは:
コミット
9a717e6196
|
@ -40,10 +40,11 @@ from .event_artist import EventArtist
|
|||
from .event_album import EventAlbum
|
||||
from .feed import Feed
|
||||
from .event import Event
|
||||
from .promo_code_status import PromoCodeStatus
|
||||
|
||||
__all__ = ['YandexMusicObject', 'Account', 'PassportPhone', 'InvocationInfo', 'Permissions', 'Plus', 'Subscription',
|
||||
'Status', 'Price', 'Product', 'AutoRenewable', 'Settings', 'PermissionAlerts', 'Experiments', 'Cover',
|
||||
'Ratings', 'Counts', 'Link', 'Artist', 'User', 'CaseForms', 'MadeFor', 'Label', 'Album', 'PlayCounter',
|
||||
'Playlist', 'TrackShort', 'TracksLikes', 'Major', 'Normalization', 'TrackPosition', 'Track', 'AlbumsLikes',
|
||||
'ArtistsLikes', 'PlaylistsLikes', 'GeneratedPlaylist', 'TrackWithAds', 'Day', 'EventArtist', 'EventAlbum',
|
||||
'Feed', 'Event']
|
||||
'Feed', 'Event', 'PromoCodeStatus']
|
||||
|
|
|
@ -17,7 +17,7 @@ class Account(YandexMusicObject):
|
|||
service_available,
|
||||
hosted_user,
|
||||
passport_phones,
|
||||
registered_at,
|
||||
registered_at=None,
|
||||
has_info_for_app_metrica=False,
|
||||
client=None,
|
||||
**kwargs):
|
||||
|
@ -33,7 +33,8 @@ class Account(YandexMusicObject):
|
|||
self.service_available = service_available
|
||||
self.hosted_user = hosted_user
|
||||
self.passport_phones = passport_phones
|
||||
self.registered_at = datetime.fromisoformat(registered_at)
|
||||
|
||||
self.registered_at = datetime.fromisoformat(registered_at) if registered_at else registered_at
|
||||
self.has_info_for_app_metrica = has_info_for_app_metrica
|
||||
|
||||
self.client = client
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import logging
|
||||
|
||||
from yandex_music import YandexMusicObject, Status, Settings, PermissionAlerts, Experiments, Artist, Album, Playlist, \
|
||||
TracksLikes, Track, AlbumsLikes, ArtistsLikes, PlaylistsLikes, Feed
|
||||
TracksLikes, Track, AlbumsLikes, ArtistsLikes, PlaylistsLikes, Feed, PromoCodeStatus
|
||||
from yandex_music.utils.request import Request
|
||||
from yandex_music.error import InvalidToken
|
||||
|
||||
|
@ -9,7 +9,7 @@ from yandex_music.error import InvalidToken
|
|||
class Client(YandexMusicObject):
|
||||
def __init__(self, token, base_url=None, request=None):
|
||||
self.token = token
|
||||
self._request = request or Request(token)
|
||||
self._request = request or Request(self)
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
if base_url is None:
|
||||
|
@ -78,6 +78,15 @@ class Client(YandexMusicObject):
|
|||
|
||||
return feed
|
||||
|
||||
def consume_promo_code(self, code: str, language='en', timeout=None, *args, **kwargs):
|
||||
url = f'{self.base_url}/account/consume-promo-code'
|
||||
|
||||
result = self._request.post(url, {'code': code, 'language': language}, timeout=timeout, *args, **kwargs)
|
||||
|
||||
promo_code_status = PromoCodeStatus.de_json(result, self)
|
||||
|
||||
return promo_code_status
|
||||
|
||||
def artists(self, artist_ids: list or int or str, timeout=None, *args, **kwargs):
|
||||
url = f'{self.base_url}/artists'
|
||||
|
||||
|
|
|
@ -5,11 +5,12 @@ class InvocationInfo(YandexMusicObject):
|
|||
def __init__(self,
|
||||
hostname,
|
||||
req_id,
|
||||
exec_duration_millis,
|
||||
exec_duration_millis=None,
|
||||
client=None,
|
||||
**kwargs):
|
||||
self.hostname = hostname
|
||||
self.req_id = req_id
|
||||
|
||||
self.exec_duration_millis = exec_duration_millis
|
||||
|
||||
self.client = client
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
from yandex_music import YandexMusicObject
|
||||
|
||||
|
||||
class PromoCodeStatus(YandexMusicObject):
|
||||
def __init__(self,
|
||||
status,
|
||||
status_desc,
|
||||
account_status,
|
||||
client=None,
|
||||
**kwargs):
|
||||
self.status = status
|
||||
self.status_desc = status_desc
|
||||
self.account_status = account_status
|
||||
|
||||
self.client = client
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, client):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(PromoCodeStatus, cls).de_json(data, client)
|
||||
from yandex_music import Status
|
||||
data['account_status'] = Status.de_json(data.get('account_status'), client)
|
||||
|
||||
return cls(client=client, **data)
|
|
@ -5,11 +5,12 @@ class Ratings(YandexMusicObject):
|
|||
def __init__(self,
|
||||
week,
|
||||
month,
|
||||
day,
|
||||
day=None,
|
||||
client=None,
|
||||
**kwargs):
|
||||
self.week = week
|
||||
self.month = month
|
||||
|
||||
self.day = day
|
||||
|
||||
self.client = client
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from yandex_music import YandexMusicObject, Account, Permissions, Plus, Subscription
|
||||
from yandex_music import YandexMusicObject
|
||||
|
||||
|
||||
class Status(YandexMusicObject):
|
||||
|
@ -10,7 +10,7 @@ class Status(YandexMusicObject):
|
|||
subeditor,
|
||||
subeditor_level,
|
||||
plus,
|
||||
default_email,
|
||||
default_email=None,
|
||||
client=None,
|
||||
**kwargs):
|
||||
self.account = account
|
||||
|
@ -20,6 +20,7 @@ class Status(YandexMusicObject):
|
|||
self.subeditor = subeditor
|
||||
self.subeditor_level = subeditor_level
|
||||
self.plus = plus
|
||||
|
||||
self.default_email = default_email
|
||||
|
||||
self.client = client
|
||||
|
@ -31,6 +32,7 @@ class Status(YandexMusicObject):
|
|||
return None
|
||||
|
||||
data = super(Status, cls).de_json(data, client)
|
||||
from yandex_music import Account, Permissions, Plus, Subscription
|
||||
data['account'] = Account.de_json(data.get('account'), client)
|
||||
data['permissions'] = Permissions.de_json(data.get('permissions'), client)
|
||||
data['subscription'] = Subscription.de_json(data.get('subscription'), client)
|
||||
|
|
|
@ -3,6 +3,7 @@ import json
|
|||
import logging
|
||||
import requests
|
||||
|
||||
from yandex_music.utils.response import Response
|
||||
from yandex_music.error import Unauthorized, BadRequest, NetworkError, YandexMusicError
|
||||
|
||||
|
||||
|
@ -18,12 +19,14 @@ HEADERS = {
|
|||
|
||||
class Request(object):
|
||||
def __init__(self,
|
||||
token,
|
||||
client,
|
||||
headers=None,
|
||||
proxies=None):
|
||||
|
||||
self.client = client
|
||||
|
||||
self.headers = headers or HEADERS
|
||||
self.headers.update({'Authorization': f'OAuth {token}'})
|
||||
self.headers.update({'Authorization': f'OAuth {self.client.token}'})
|
||||
|
||||
self.proxies = proxies # TODO
|
||||
|
||||
|
@ -41,8 +44,7 @@ class Request(object):
|
|||
|
||||
return cleaned_object
|
||||
|
||||
@staticmethod
|
||||
def _parse(json_data):
|
||||
def _parse(self, json_data) -> Response:
|
||||
try:
|
||||
decoded_s = json_data.decode('utf-8')
|
||||
data = json.loads(decoded_s, object_hook=Request._object_hook)
|
||||
|
@ -50,10 +52,10 @@ class Request(object):
|
|||
logging.getLogger(__name__).debug(
|
||||
'Logging raw invalid UTF-8 response:\n%r', json_data)
|
||||
raise YandexMusicError('Server response could not be decoded using UTF-8')
|
||||
except ValueError:
|
||||
raise Exception('Invalid server response')
|
||||
except (AttributeError, ValueError):
|
||||
raise YandexMusicError('Invalid server response')
|
||||
|
||||
return data.get('result')
|
||||
return Response.de_json(data, self.client)
|
||||
|
||||
def _request_wrapper(self, *args, **kwargs):
|
||||
if 'headers' not in kwargs:
|
||||
|
@ -65,14 +67,16 @@ class Request(object):
|
|||
resp = requests.request(verify=False, *args, **kwargs)
|
||||
except requests.Timeout:
|
||||
raise TimeoutError()
|
||||
except requests.RequestException:
|
||||
raise Exception('Network error')
|
||||
except requests.RequestException as e:
|
||||
raise NetworkError(e)
|
||||
|
||||
if 200 <= resp.status_code <= 299:
|
||||
return resp.content
|
||||
return self._parse(resp.content).result
|
||||
|
||||
try:
|
||||
message = self._parse(resp.text)
|
||||
message = self._parse(resp.content).error
|
||||
if message is None:
|
||||
raise ValueError()
|
||||
except ValueError:
|
||||
message = 'Unknown HTTPError'
|
||||
|
||||
|
@ -81,7 +85,7 @@ class Request(object):
|
|||
elif resp.status_code == 400:
|
||||
raise BadRequest(message)
|
||||
elif resp.status_code in (404, 409, 413):
|
||||
raise NetworkError()
|
||||
raise NetworkError(message)
|
||||
|
||||
elif resp.status_code == 502:
|
||||
raise NetworkError('Bad Gateway')
|
||||
|
@ -89,10 +93,8 @@ class Request(object):
|
|||
raise NetworkError('{0} ({1})'.format(message, resp.status_code))
|
||||
|
||||
def get(self, url, timeout=5, *args, **kwargs):
|
||||
result = self._request_wrapper('GET', url, headers=self.headers, timeout=timeout, *args, **kwargs)
|
||||
return self._parse(result)
|
||||
return self._request_wrapper('GET', url, headers=self.headers, timeout=timeout, *args, **kwargs)
|
||||
|
||||
def post(self, url, data, timeout=5, *args, **kwargs):
|
||||
result = self._request_wrapper('POST', url, headers=self.headers, data=data, timeout=timeout, *args, **kwargs)
|
||||
return self._parse(result)
|
||||
return self._request_wrapper('POST', url, headers=self.headers, data=data, timeout=timeout, *args, **kwargs)
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
from yandex_music import YandexMusicObject
|
||||
|
||||
|
||||
class Response(YandexMusicObject):
|
||||
def __init__(self,
|
||||
invocation_info,
|
||||
result=None,
|
||||
error=None,
|
||||
client=None,
|
||||
**kwargs):
|
||||
self.invocation_info = invocation_info
|
||||
self.result = result
|
||||
self.error = error
|
||||
|
||||
self.client = client
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data, client):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
data = super(Response, cls).de_json(data, client)
|
||||
from yandex_music import InvocationInfo
|
||||
data['invocation_info'] = InvocationInfo.de_json(data.get('invocation_info'), client)
|
||||
|
||||
return cls(client=client, **data)
|
読み込み中…
新しいイシューから参照