Метод de_list в TrackId.

Поля coauthors и recent_tracks в Playlist.
Поле regions в User.
Поля users, podcasts, podcast_episodes, type_, page, per_page в Search.
Поддержка новых типов поиска: подкасты, выпуски, пользователи.
Поля short_description, description, is_premiere, is_banner в Like.
Документация и тесты к новым поля. #339
このコミットが含まれているのは:
Il`ya Semyonov 2020-06-07 12:55:30 +03:00
コミット 09905eb7af
13個のファイルの変更211行の追加49行の削除

ファイルの表示

@ -3,21 +3,22 @@ import pytest
from yandex_music import Account, AdParams, Album, AlbumEvent, Artist, ArtistEvent, AutoRenewable, Best, Block, \
BlockEntity, CaseForms, Chart, ChartInfo, ChartInfoMenu, ChartInfoMenuItem, ChartItem, Client, Counts, Cover, Day, \
Description, DiscreteScale, Enum, Event, GeneratedPlaylist, Icon, Id, Images, InvocationInfo, Label, \
LicenceTextPart, Link, Lyrics, MadeFor, Major, MetaData, MixLink, Normalization, Pager, PassportPhone, Permissions, \
PersonalPlaylistsData, PlayContext, PlayContextsData, PlayCounter, Playlist, PlaylistAbsence, PlaylistId, Plus, \
Price, Product, Promotion, Ratings, RenewableRemainder, Restrictions, RotorSettings, SearchResult, Sequence, \
Settings, Shot, ShotData, ShotType, Station, StationResult, Status, Subscription, Tag, Title, Track, TrackId, \
TrackPosition, TrackShort, TrackShortOld, TrackWithAds, User, Value, Video, VideoSupplement, Vinyl
from . import TestAccount, TestAdParams, TestAlbum, TestArtist, TestAutoRenewable, TestBest, TestBlock, TestBlockEntity, \
TestCaseForms, TestChart, TestChartInfo, TestChartInfoMenuItem, TestCounts, TestCover, TestDay, TestDescription, \
TestDiscreteScale, TestEnum, TestEvent, TestGeneratedPlaylist, TestIcon, TestId, TestImages, TestInvocationInfo, \
TestLabel, TestLicenceTextPart, TestLink, TestLyrics, TestMajor, TestMetaData, TestMixLink, TestNormalization, \
TestPager, TestPassportPhone, TestPermissions, TestPersonalPlaylistsData, TestPlayContext, TestPlayCounter, \
TestPlaylist, TestPlaylistAbsence, TestPlaylistId, TestPlus, TestPrice, TestProduct, TestPromotion, TestRatings, \
TestRenewableRemainder, TestRotorSettings, TestSearchResult, TestSequence, TestSettings, TestShot, TestShotData, \
TestShotType, TestStation, TestStationResult, TestStatus, TestSubscription, TestTag, TestTitle, TestTrack, \
TestTrackId, TestTrackPosition, TestTrackShort, TestTrackShortOld, TestTrackWithAds, TestUser, TestValue,\
TestVideo, TestVideoSupplement, TestVinyl, TestArtistEvent
LicenceTextPart, Link, Lyrics, MadeFor, Major, MetaData, MixLink, Normalization, Pager, PassportPhone, \
Permissions, PersonalPlaylistsData, PlayContext, PlayContextsData, PlayCounter, Playlist, PlaylistAbsence, \
PlaylistId, Plus, Price, Product, Promotion, Ratings, RenewableRemainder, Restrictions, RotorSettings, \
SearchResult, Sequence, Settings, Shot, ShotData, ShotType, Station, StationResult, Status, Subscription, Tag, \
Title, Track, TrackId, TrackPosition, TrackShort, TrackShortOld, TrackWithAds, User, Value, Video, \
VideoSupplement, Vinyl
from . import TestAccount, TestAdParams, TestAlbum, TestArtist, TestAutoRenewable, TestBest, TestBlock, \
TestBlockEntity, TestCaseForms, TestChart, TestChartInfo, TestChartInfoMenuItem, TestCounts, TestCover, TestDay, \
TestDescription, TestDiscreteScale, TestEnum, TestEvent, TestGeneratedPlaylist, TestIcon, TestId, TestImages, \
TestInvocationInfo, TestLabel, TestLicenceTextPart, TestLink, TestLyrics, TestMajor, TestMetaData, TestMixLink, \
TestNormalization, TestPager, TestPassportPhone, TestPermissions, TestPersonalPlaylistsData, TestPlayContext, \
TestPlayCounter, TestPlaylist, TestPlaylistAbsence, TestPlaylistId, TestPlus, TestPrice, TestProduct,\
TestPromotion, TestRatings, TestRenewableRemainder, TestRotorSettings, TestSearchResult, TestSequence, \
TestSettings, TestShot, TestShotData, TestShotType, TestStation, TestStationResult, TestStatus, TestSubscription, \
TestTag, TestTitle, TestTrack, TestTrackId, TestTrackPosition, TestTrackShort, TestTrackShortOld, \
TestTrackWithAds, TestUser, TestValue, TestVideo, TestVideoSupplement, TestVinyl, TestArtistEvent
@pytest.fixture(scope='session')
@ -118,7 +119,7 @@ def album_without_nested_albums(album_factory, artist_without_tracks, track_with
@pytest.fixture(scope='session')
def playlist_factory(user, cover, made_for, track_short, play_counter, playlist_absence, artist):
def playlist_factory(user, cover, made_for, track_short, play_counter, playlist_absence, artist, track_id):
class PlaylistFactory:
def get(self, similar_playlists, last_owner_playlists):
return Playlist(user, cover, made_for, play_counter, playlist_absence, TestPlaylist.uid, TestPlaylist.kind,
@ -128,11 +129,11 @@ def playlist_factory(user, cover, made_for, track_short, play_counter, playlist_
TestPlaylist.available, TestPlaylist.is_banner, TestPlaylist.is_premiere,
TestPlaylist.duration_ms, TestPlaylist.og_image, TestPlaylist.og_title,
TestPlaylist.og_description, TestPlaylist.image, cover, TestPlaylist.background_color,
TestPlaylist.text_color, TestPlaylist.id_for_from, [artist], [track_short],
TestPlaylist.prerolls, TestPlaylist.likes_count, similar_playlists, last_owner_playlists,
TestPlaylist.generated_playlist_type, TestPlaylist.animated_cover_uri,
TestPlaylist.ever_played, TestPlaylist.description, TestPlaylist.description_formatted,
TestPlaylist.is_for_from, TestPlaylist.regions)
TestPlaylist.text_color, TestPlaylist.id_for_from, TestPlaylist.coauthors, [artist],
[track_id], [track_short], TestPlaylist.prerolls, TestPlaylist.likes_count,
similar_playlists, last_owner_playlists, TestPlaylist.generated_playlist_type,
TestPlaylist.animated_cover_uri, TestPlaylist.ever_played, TestPlaylist.description,
TestPlaylist.description_formatted, TestPlaylist.is_for_from, TestPlaylist.regions)
return PlaylistFactory()
@ -387,7 +388,7 @@ def renewable_remainder():
@pytest.fixture(scope='session')
def user():
return User(TestUser.uid, TestUser.login, TestUser.name, TestUser.display_name,
TestUser.full_name, TestUser.sex, TestUser.verified)
TestUser.full_name, TestUser.sex, TestUser.verified, TestUser.regions)
@pytest.fixture(scope='session')
@ -547,7 +548,7 @@ def restrictions(enum, discrete_scale):
@pytest.fixture(scope='session')
def results(track, artist, album, playlist, video, generated_playlist, promotion, chart_item, play_context, mix_link,
personal_playlists_data, play_contexts_data):
personal_playlists_data, play_contexts_data, user):
return {
1: track,
2: artist,
@ -560,7 +561,10 @@ def results(track, artist, album, playlist, video, generated_playlist, promotion
9: play_context,
10: mix_link,
11: personal_playlists_data,
12: play_contexts_data
12: play_contexts_data,
13: user,
14: album,
15: track
}
@ -578,11 +582,14 @@ def types():
9: 'play-context',
10: 'mix-link',
11: 'personal-playlists',
12: 'play-contexts'
12: 'play-contexts',
13: 'user',
14: 'podcast',
15: 'podcast_episode'
}
@pytest.fixture(scope='session', params=[1, 2, 3, 4, 5])
@pytest.fixture(scope='session', params=[1, 2, 3, 4, 5, 13, 14, 15])
def result_with_type(request, results, types):
return results[request.param], types[request.param]

ファイルの表示

@ -5,13 +5,21 @@ from yandex_music import Like
@pytest.fixture(scope='class', params=[2, 3, 4])
def like_with_param(request, results, types):
return Like(types[request.param], TestLike.id, TestLike.timestamp,
return Like(types[request.param], TestLike.id, TestLike.timestamp, short_description=TestLike.short_description,
description=TestLike.description, is_premiere=TestLike.is_premiere, is_banner=TestLike.is_banner,
**{types[request.param]: results[request.param]}), request.param
class TestLike:
id = 5246018
timestamp = '2019-09-03T19:59:56+00:00'
short_description = 'Учим английский нескучно'
description = 'Английский по песням это аудио- и видеоподкаст радио Unistar о том, как учить английский язык ' \
'по песням хитам 90-х и 2000-х, которые звучат на Unistar. Никакого занудства, грамматических ' \
'правил и зубрежки. Только нескучный английский! Вы узнаете, о чем поют в любимых песнях, и как ' \
'это может помочь вам в общении во время путешествий.'
is_premiere = False
is_banner = True
def test_expected_values(self, results, types, like_with_param):
like, param = like_with_param
@ -19,6 +27,10 @@ class TestLike:
assert like.type == types[param]
assert like.id == self.id
assert like.timestamp == self.timestamp
assert like.short_description == self.short_description
assert like.description == self.description
assert like.is_premiere == self.is_premiere
assert like.is_banner == self.is_banner
assert getattr(like, like.type) == results[param]
def test_de_json_none(self, client):
@ -31,12 +43,18 @@ class TestLike:
def test_de_json_all(self, results, types, client, param):
result, type_ = results[param], types[param]
json_dict = {'timestamp': self.timestamp, 'id_': self.id, type_: result.to_dict()}
json_dict = {'timestamp': self.timestamp, 'id_': self.id, type_: result.to_dict(),
'short_description': self.short_description, 'description': self.description,
'is_premiere': self.is_premiere, 'is_banner': self.is_banner}
like = Like.de_json(json_dict, client, type_)
assert like.type == type_
assert like.id == self.id
assert like.timestamp == self.timestamp
assert like.short_description == self.short_description
assert like.description == self.description
assert like.is_premiere == self.is_premiere
assert like.is_banner == self.is_banner
assert getattr(like, type_) == result
@pytest.mark.parametrize('param', [2, 3, 4])

ファイルの表示

@ -25,6 +25,7 @@ class TestPlaylist:
background_color = ''
text_color = ''
id_for_from = 'playlist_of_the_day'
coauthors = [1130000003905541]
prerolls = []
likes_count = 1
generated_playlist_type = 'playlistOfTheDay'
@ -36,7 +37,7 @@ class TestPlaylist:
regions = None
def test_expected_values(self, playlist, user, cover, made_for, track_short, play_counter, playlist_absence,
playlist_without_nested_playlists, artist):
playlist_without_nested_playlists, artist, track_id):
assert playlist.owner == user
assert playlist.uid == self.uid
assert playlist.kind == self.kind
@ -66,7 +67,9 @@ class TestPlaylist:
assert playlist.background_color == self.background_color
assert playlist.text_color == self.text_color
assert playlist.id_for_from == self.id_for_from
assert playlist.coauthors == self.coauthors
assert playlist.top_artist == [artist]
assert playlist.recent_tracks == [track_id]
assert playlist.tracks == [track_short]
assert playlist.prerolls == self.prerolls
assert playlist.likes_count == self.likes_count
@ -98,7 +101,7 @@ class TestPlaylist:
assert playlist.playlist_absence == playlist_absence
def test_de_json_all(self, client, user, cover, made_for, track_short, play_counter, playlist_absence,
playlist_without_nested_playlists, artist):
playlist_without_nested_playlists, artist, track_id):
json_dict = {'owner': user.to_dict(), 'uid': self.uid, 'kind': self.kind, 'title': self.title,
'track_count': self.track_count, 'cover': cover.to_dict(), 'made_for': made_for.to_dict(),
'play_counter': play_counter.to_dict(), 'playlist_absence': playlist_absence.to_dict(),
@ -112,10 +115,11 @@ class TestPlaylist:
'description': self.description, 'description_formatted': self.description_formatted,
'is_for_from': self.is_for_from, 'regions': self.regions, 'og_title': self.og_title,
'image': self.image, 'id_for_from': self.id_for_from, 'background_color': self.background_color,
'text_color': self.text_color, 'cover_without_text': cover.to_dict(),
'text_color': self.text_color, 'cover_without_text': cover.to_dict(), 'coauthors': self.coauthors,
'similar_playlists': [playlist_without_nested_playlists.to_dict()],
'last_owner_playlists': [playlist_without_nested_playlists.to_dict()],
'og_description': self.og_description, 'top_artist': [artist.to_dict()]}
'og_description': self.og_description, 'top_artist': [artist.to_dict()],
'recent_tracks': [track_id.to_dict()]}
playlist = Playlist.de_json(json_dict, client)
assert playlist.owner == user
@ -147,7 +151,9 @@ class TestPlaylist:
assert playlist.background_color == self.background_color
assert playlist.text_color == self.text_color
assert playlist.id_for_from == self.id_for_from
assert playlist.coauthors == self.coauthors
assert playlist.top_artist == [artist]
assert playlist.recent_tracks == [track_id]
assert playlist.tracks == [track_short]
assert playlist.prerolls == self.prerolls
assert playlist.likes_count == self.likes_count

ファイルの表示

@ -16,14 +16,18 @@ def search_result(results, types):
@pytest.fixture(scope='class')
def search(best, search_result):
return Search(TestSearch.search_request_id, TestSearch.text, best,
search_result(3), search_result(2), search_result(4),
search_result(1), search_result(5), TestSearch.misspell_corrected, TestSearch.nocorrect)
search_result(3), search_result(2), search_result(4), search_result(1), search_result(5),
search_result(13), search_result(14), search_result(15), TestSearch.type_, TestSearch.page,
TestSearch.per_page, TestSearch.misspell_corrected, TestSearch.nocorrect)
class TestSearch:
search_request_id = 'myt1-0261-c2e-msk-myt-music-st-e72-18274.gencfg-c.yandex.net-1573323135801461' \
'-3742331365077765411-1573323135819 '
text = 'NCS'
type_ = 'artist'
page = 0
per_page = 10
misspell_corrected = False
nocorrect = False
@ -36,6 +40,12 @@ class TestSearch:
assert search.playlists == search_result(4)
assert search.tracks == search_result(1)
assert search.videos == search_result(5)
assert search.users == search_result(13)
assert search.podcasts == search_result(14)
assert search.podcast_episodes == search_result(15)
assert search.type_ == self.type_
assert search.page == self.page
assert search.per_page == self.per_page
assert search.misspell_corrected == self.misspell_corrected
assert search.nocorrect == self.nocorrect
@ -46,7 +56,8 @@ class TestSearch:
json_dict = {'search_request_id': self.search_request_id, 'text': self.text, 'best': best.to_dict(),
'albums': search_result(3).to_dict(), 'artists': search_result(2).to_dict(),
'playlists': search_result(4).to_dict(), 'tracks': search_result(1).to_dict(),
'videos': search_result(5).to_dict()}
'videos': search_result(5).to_dict(), 'users': search_result(13).to_dict(),
'podcasts': search_result(14).to_dict(), 'podcast_episodes': search_result(15).to_dict()}
search = Search.de_json(json_dict, client)
assert search.search_request_id == self.search_request_id
@ -57,13 +68,18 @@ class TestSearch:
assert search.playlists == search_result(4)
assert search.tracks == search_result(1)
assert search.videos == search_result(5)
assert search.users == search_result(13)
assert search.podcasts == search_result(14)
assert search.podcast_episodes == search_result(15)
def test_de_json_all(self, client, best, search_result):
json_dict = {'search_request_id': self.search_request_id, 'text': self.text, 'best': best.to_dict(),
'albums': search_result(3).to_dict(), 'artists': search_result(2).to_dict(),
'playlists': search_result(4).to_dict(), 'tracks': search_result(1).to_dict(),
'videos': search_result(5).to_dict(), 'misspell_corrected': self.misspell_corrected,
'nocorrect': self.nocorrect}
'videos': search_result(5).to_dict(), 'users': search_result(13).to_dict(),
'podcasts': search_result(14).to_dict(), 'podcast_episodes': search_result(15).to_dict(),
'misspell_corrected': self.misspell_corrected, 'nocorrect': self.nocorrect,
'type_': self.type_, 'page': self.page, 'per_page': self.per_page}
search = Search.de_json(json_dict, client)
assert search.search_request_id == self.search_request_id
@ -74,16 +90,22 @@ class TestSearch:
assert search.playlists == search_result(4)
assert search.tracks == search_result(1)
assert search.videos == search_result(5)
assert search.users == search_result(13)
assert search.podcasts == search_result(14)
assert search.podcast_episodes == search_result(15)
assert search.type_ == self.type_
assert search.page == self.page
assert search.per_page == self.per_page
assert search.misspell_corrected == self.misspell_corrected
assert search.nocorrect == self.nocorrect
def test_equality(self, best, search_result):
a = Search(self.search_request_id, self.text, best, search_result(3), search_result(2), search_result(4),
search_result(1), search_result(5))
search_result(1), search_result(5), search_result(13), search_result(14), search_result(15))
b = Search(self.search_request_id, '', best, search_result(3), None, search_result(4), search_result(1),
search_result(5))
search_result(5), search_result(13), None, search_result(15))
c = Search(self.search_request_id, self.text, best, search_result(3), search_result(2), search_result(4),
search_result(1), search_result(5))
search_result(1), search_result(5), search_result(13), search_result(14), search_result(15))
assert a != b
assert hash(a) != hash(b)

ファイルの表示

@ -12,6 +12,9 @@ class TestTrackId:
def test_de_json_none(self, client):
assert TrackId.de_json({}, client) is None
def test_de_list_none(self, client):
assert TrackId.de_list({}, client) == []
def test_de_json_required(self, client):
json_dict = {'id_': self.id}
track_id = TrackId.de_json(json_dict, client)

ファイルの表示

@ -9,6 +9,7 @@ class TestUser:
full_name = 'Илья'
sex = 'unknown'
verified = False
regions = ['RUSSIA_PREMIUM', 'RUSSIA']
def test_expected_values(self, user):
assert user.uid == self.uid
@ -18,10 +19,14 @@ class TestUser:
assert user.full_name == self.full_name
assert user.sex == self.sex
assert user.verified == self.verified
assert user.regions == self.regions
def test_de_json_none(self, client):
assert User.de_json({}, client) is None
def test_de_list_none(self, client):
assert User.de_list({}, client) == []
def test_de_json_required(self, client):
json_dict = {'uid': self.uid, 'login': self.login}
user = User.de_json(json_dict, client)
@ -31,7 +36,8 @@ class TestUser:
def test_de_json_all(self, client):
json_dict = {'uid': self.uid, 'login': self.login, 'name': self.name, 'sex': self.sex,
'verified': self.verified, 'display_name': self.display_name, 'full_name': self.full_name}
'verified': self.verified, 'display_name': self.display_name, 'full_name': self.full_name,
'regions': self.regions}
user = User.de_json(json_dict, client)
assert user.uid == self.uid
@ -41,6 +47,7 @@ class TestUser:
assert user.full_name == self.full_name
assert user.sex == self.sex
assert user.verified == self.verified
assert user.regions == self.regions
def test_equality(self):
a = User(self.uid, self.login)

ファイルの表示

@ -763,11 +763,17 @@ class Client(YandexMusicObject):
*args, **kwargs) -> Optional[Search]:
"""Осуществление поиска по запросу и типу, получение результатов.
Note:
Известные значения для поля `type_`: `all`, `artist`, `user`, `album`, `playlist`, `track`, `podcast`,
`podcast_episode`.
При поиске `type=all` не возвращаются подкасты и эпизоды. Указывайте конкретный тип для поиска.
Args:
text (:obj:`str`): Текст запроса.
nocorrect (:obj:`bool`): Если :obj:`False`, то ошибочный запрос будет исправлен. Например, запрос
"Гражданская абарона" будет исправлен на "Гражданская оборона".
type_ (:obj:`str`): Среди какого типа искать (трек, плейлист, альбом, исполнитель).
type_ (:obj:`str`): Среди какого типа искать (трек, плейлист, альбом, исполнитель, пользователь, подкаст).
page (:obj:`int`): Номер страницы.
playlist_in_best (:obj:`bool`): Выдавать ли плейлисты лучшим вариантом поиска.
timeout (:obj:`int` | :obj:`float`, optional): Если это значение указано, используется как время ожидания

ファイルの表示

@ -1,4 +1,4 @@
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, Optional, List
from yandex_music import YandexMusicObject
@ -51,3 +51,19 @@ class TrackId(YandexMusicObject):
data = super(TrackId, cls).de_json(data, client)
return cls(client=client, **data)
@classmethod
def de_list(cls, data: dict, client: 'Client') -> List['TrackId']:
"""Десериализация списка объектов.
Args:
data (:obj:`list`): Список словарей с полями и значениями десериализуемого объекта.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
Returns:
:obj:`list` из :obj:`yandex_music.TrackId`: Уникальные идентификаторы треков.
"""
if not data:
return []
return [cls.de_json(track_id, client) for track_id in data]

ファイルの表示

@ -25,6 +25,10 @@ class Like(YandexMusicObject):
album (:obj:`yandex_music.Album`): Понравившейся альбом.
artist (:obj:`yandex_music.Artist`): Понравившейся артист.
playlist (:obj:`yandex_music.Playlist`): Понравившейся плейлист.
short_description (:obj:`str`): Короткое описание.
description (:obj:`str`): Описание.
is_premiere (:obj:`bool`): Премьера ли.
is_banner (:obj:`bool`): Является ли баннером.
client (:obj:`yandex_music.Client`): Клиент Yandex Music.
Args:
@ -34,6 +38,10 @@ class Like(YandexMusicObject):
album (:obj:`yandex_music.Album`, optional): Понравившейся альбом.
artist (:obj:`yandex_music.Artist`, optional): Понравившейся артист.
playlist (:obj:`yandex_music.Playlist`, optional): Понравившейся плейлист.
short_description (:obj:`str`, optional): Короткое описание.
description (:obj:`str`, optional): Описание.
is_premiere (:obj:`bool`, optional): Премьера ли.
is_banner (:obj:`bool`, optional): Является ли баннером.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
**kwargs: Произвольные ключевые аргументы полученные от API.
"""
@ -45,6 +53,10 @@ class Like(YandexMusicObject):
album: Optional['Album'] = None,
artist: Optional['Artist'] = None,
playlist: Optional['Playlist'] = None,
short_description: Optional[str] = None,
description: Optional[str] = None,
is_premiere: Optional[bool] = None,
is_banner: Optional[bool] = None,
client: Optional['Client'] = None,
**kwargs) -> None:
self.id = id_
@ -54,6 +66,10 @@ class Like(YandexMusicObject):
self.artist = artist
self.playlist = playlist
self.timestamp = timestamp
self.short_description = short_description
self.description = description
self.is_premiere = is_premiere
self.is_banner = is_banner
self.client = client
self._id_attrs = (self.id, self.type, self.timestamp, self.album, self.artist, self.playlist)

ファイルの表示

@ -4,7 +4,7 @@ from yandex_music import YandexMusicObject
if TYPE_CHECKING:
from yandex_music import Client, User, Cover, MadeFor, TrackShort, PlaylistAbsence, PlayCounter,\
PlaylistRecommendations, Artist
PlaylistRecommendations, Artist, TrackId
class Playlist(YandexMusicObject):
@ -47,7 +47,9 @@ class Playlist(YandexMusicObject):
background_color (:obj:`str`): Цвет заднего фона TODO.
text_color (:obj:`str`): Цвет текста TODO.
id_for_from (:obj:`str`): Откуда пришло событие (уникальный идентификатор объекта) TODO.
coauthors (:obj:`list` из :obj:`int`): Перечень ID аккаунтов соавторов плейлиста.
top_artist (:obj:`list` из :obj:`yandex_music.Artist`): Топ артистов TODO.
recent_tracks (:obj:`list` из :obj:`yandex_music.TrackId`): Список ID недавних треков.
tracks (:obj:`list` из :obj:`yandex_music.TrackShort`): Список треков.
prerolls (:obj:`list`): Прерол, проигрываемый перед плейлистом. Присутствует только у персональных плейлистов.
likes_count (:obj:`int`): Количество лайков.
@ -93,7 +95,9 @@ class Playlist(YandexMusicObject):
background_color (:obj:`str`, optional): Цвет заднего фона TODO.
text_color (:obj:`str`, optional): Цвет текста TODO.
id_for_from (:obj:`str`, optional): Откуда пришло событие (уникальный идентификатор объекта) TODO.
coauthors (:obj:`list` из :obj:`int`, optional): Перечень ID аккаунтов соавторов плейлиста.
top_artist (:obj:`list` из :obj:`yandex_music.Artist`, optional): Топ артистов TODO.
recent_tracks (:obj:`list` из :obj:`yandex_music.TrackId`, optional): Список ID недавних треков.
tracks (:obj:`list` из :obj:`yandex_music.TrackShort`, optional): Список треков.
prerolls (:obj:`list`, optional): Прерол, проигрываемый перед плейлистом. Присутствует только у персональных
плейлистов.
@ -141,7 +145,9 @@ class Playlist(YandexMusicObject):
background_color: Optional[str] = None,
text_color: Optional[str] = None,
id_for_from: Optional[str] = None,
coauthors: List[int] = None,
top_artist: List['Artist'] = None,
recent_tracks: List['TrackId'] = None,
tracks: List['TrackShort'] = None,
prerolls: Optional[list] = None,
likes_count: Optional[int] = None,
@ -185,7 +191,9 @@ class Playlist(YandexMusicObject):
self.background_color = background_color
self.text_color = text_color
self.id_for_from = id_for_from
self.coauthors = coauthors
self.top_artist = top_artist
self.recent_tracks = recent_tracks
self.tracks = tracks
self.prerolls = prerolls
self.likes_count = likes_count
@ -282,12 +290,13 @@ class Playlist(YandexMusicObject):
return None
data = super(Playlist, cls).de_json(data, client)
from yandex_music import User, MadeFor, Cover, PlayCounter, TrackShort, PlaylistAbsence, Artist
from yandex_music import User, MadeFor, Cover, PlayCounter, TrackShort, PlaylistAbsence, Artist, TrackId
data['owner'] = User.de_json(data.get('owner'), client)
data['cover'] = Cover.de_json(data.get('cover'), client)
data['cover_without_text'] = Cover.de_json(data.get('cover_without_text'), client)
data['made_for'] = MadeFor.de_json(data.get('made_for'), client)
data['tracks'] = TrackShort.de_list(data.get('tracks'), client)
data['recent_tracks'] = TrackId.de_list(data.get('recent_tracks'), client)
data['play_counter'] = PlayCounter.de_json(data.get('play_counter'), client)
data['top_artist'] = Artist.de_list(data.get('top_artist'), client)

ファイルの表示

@ -1,4 +1,4 @@
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, Optional, List
from yandex_music import YandexMusicObject
@ -16,6 +16,8 @@ class User(YandexMusicObject):
При наличии экземпляра класса в `user_info` у `Track` (у самозагруженных треков) доступны только `uid`,
'`login`, 'display_name` и `full_name`.
Поле `regions` есть только при возвращении пользователей в результатах поисках.
Attributes:
uid (:obj:`int`): Идентификатор пользователя.
login (:obj:`str`): Логин пользователя.
@ -24,6 +26,7 @@ class User(YandexMusicObject):
full_name (:obj:`str`, optional): Полное имя пользователя.
sex (:obj:`str`): Пол пользователя.
verified (:obj:`bool`): Участвует ли пользователь в генерации плейлистов дня и т.д., и т.п.
regions (:obj:`list` из :obj:`int`): Список регионов TODO.
client (:obj:`yandex_music.Client`): Клиент Yandex Music.
Args:
@ -34,6 +37,7 @@ class User(YandexMusicObject):
full_name (:obj:`str`, optional): Полное имя пользователя.
sex (:obj:`str`, optional): Пол пользователя.
verified (:obj:`bool`, optional): Участвует ли пользователь в генерации плейлистов дня и т.д., и т.п.
regions (:obj:`list` из :obj:`int`, optional): Список регионов TODO.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
**kwargs: Произвольные ключевые аргументы полученные от API.
"""
@ -46,6 +50,7 @@ class User(YandexMusicObject):
full_name: Optional[str] = None,
sex: Optional[str] = None,
verified: Optional[bool] = None,
regions: List[int] = None,
client: Optional['Client'] = None,
**kwargs) -> None:
self.uid = uid
@ -56,6 +61,7 @@ class User(YandexMusicObject):
self.full_name = full_name
self.sex = sex
self.verified = verified
self.regions = regions
self.client = client
self._id_attrs = (self.uid, self.login)
@ -89,6 +95,22 @@ class User(YandexMusicObject):
return cls(client=client, **data)
@classmethod
def de_list(cls, data: dict, client: 'Client') -> List['User']:
"""Десериализация списка объектов.
Args:
data (:obj:`list`): Список словарей с полями и значениями десериализуемого объекта.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
Returns:
:obj:`list` из :obj:`yandex_music.User`: Пользователи.
"""
if not data:
return []
return [cls.de_json(user, client) for user in data]
# camelCase псевдонимы
#: Псевдоним для :attr:`download_avatar`

ファイルの表示

@ -18,6 +18,12 @@ class Search(YandexMusicObject):
playlists (:obj:`yandex_music.SearchResult`): Найденные плейлисты.
tracks (:obj:`yandex_music.SearchResult`): Найденные треки.
videos (:obj:`yandex_music.SearchResult`): Найденные видео.
users (:obj:`yandex_music.SearchResult`): Найденные пользователи.
podcasts (:obj:`yandex_music.SearchResult`): Найденные подскасты.
podcast_episodes (:obj:`yandex_music.SearchResult`): Найденные выпуски подкастов.
type_ (:obj:`str`): Тип результата по которому искали (аргумент в Client.search).
page (:obj:`int`): Текущая страница.
per_page (:obj:`int`): Результатов на странице.
misspell_corrected (:obj:`bool`): Был ли исправлен запрос.
nocorrect (:obj:`bool`): Было ли отключено исправление результата.
client (:obj:`yandex_music.Client`): Клиент Yandex Music.
@ -31,6 +37,12 @@ class Search(YandexMusicObject):
playlists (:obj:`yandex_music.SearchResult`): Найденные плейлисты.
tracks (:obj:`yandex_music.SearchResult`): Найденные треки.
videos (:obj:`yandex_music.SearchResult`): Найденные видео.
users (:obj:`yandex_music.SearchResult`): Найденные пользователи.
podcasts (:obj:`yandex_music.SearchResult`): Найденные подскасты.
podcast_episodes (:obj:`yandex_music.SearchResult`): Найденные выпуски подкастов.
type_ (:obj:`str`), optional: Тип результата по которому искали (аргумент в Client.search).
page (:obj:`int`, optional): Текущая страница.
per_page (:obj:`int`, optional): Результатов на странице.
misspell_corrected (:obj:`bool`, optional): Был ли исправлен запрос.
nocorrect (:obj:`bool`, optional): Было ли отключено исправление результата.
client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
@ -46,6 +58,12 @@ class Search(YandexMusicObject):
playlists: Optional['SearchResult'],
tracks: Optional['SearchResult'],
videos: Optional['SearchResult'],
users: Optional['SearchResult'],
podcasts: Optional['SearchResult'],
podcast_episodes: Optional['SearchResult'],
type_: Optional[str] = None,
page: Optional[int] = None,
per_page: Optional[int] = None,
misspell_corrected: Optional[bool] = None,
nocorrect: Optional[bool] = None,
client: Optional['Client'] = None,
@ -58,13 +76,19 @@ class Search(YandexMusicObject):
self.playlists = playlists
self.tracks = tracks
self.videos = videos
self.users = users
self.podcasts = podcasts
self.podcast_episodes = podcast_episodes
self.type_ = type_
self.page = page
self.per_page = per_page
self.misspell_corrected = misspell_corrected
self.nocorrect = nocorrect
self.client = client
self._id_attrs = (self.search_request_id, self.text, self.best, self.albums,
self.artists, self.playlists, self.tracks, self.videos)
self._id_attrs = (self.search_request_id, self.text, self.best, self.albums, self.artists, self.playlists,
self.tracks, self.videos, self.users, self.podcasts, self.podcast_episodes)
super().handle_unknown_kwargs(self, **kwargs)
@ -90,5 +114,8 @@ class Search(YandexMusicObject):
data['playlists'] = SearchResult.de_json(data.get('playlists'), client, 'playlist')
data['tracks'] = SearchResult.de_json(data.get('tracks'), client, 'track')
data['videos'] = SearchResult.de_json(data.get('videos'), client, 'video')
data['users'] = SearchResult.de_json(data.get('users'), client, 'user')
data['podcasts'] = SearchResult.de_json(data.get('podcasts'), client, 'podcast')
data['podcast_episodes'] = SearchResult.de_json(data.get('podcast_episodes'), client, 'podcast_episode')
return cls(client=client, **data)

ファイルの表示

@ -1,6 +1,6 @@
from typing import TYPE_CHECKING, Optional, List, Union
from yandex_music import YandexMusicObject, Artist, Album, Track, Playlist, Video
from yandex_music import YandexMusicObject, Artist, Album, Track, Playlist, Video, User
if TYPE_CHECKING:
from yandex_music import Client
@ -12,6 +12,9 @@ de_json_result = {
'album': Album.de_list,
'playlist': Playlist.de_list,
'video': Video.de_list,
'user': User.de_list,
'podcast': Album.de_list,
'podcast_episode': Track.de_list,
}