deezer-python-gql 0.20.0__tar.gz → 0.22.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {deezer_python_gql-0.20.0/deezer_python_gql.egg-info → deezer_python_gql-0.22.1}/PKG-INFO +7 -6
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/README.md +1 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/base_client.py +5 -1
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/__init__.py +32 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/base_client.py +5 -1
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/client.py +71 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/enums.py +14 -0
- deezer_python_gql-0.22.1/deezer_python_gql/generated/input_types.py +62 -0
- deezer_python_gql-0.22.1/deezer_python_gql/generated/move_track_in_playlist.py +21 -0
- deezer_python_gql-0.22.1/deezer_python_gql/generated/push_queue_state.py +39 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1/deezer_python_gql.egg-info}/PKG-INFO +7 -6
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql.egg-info/SOURCES.txt +2 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql.egg-info/requires.txt +5 -5
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/pyproject.toml +7 -7
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/tests/test_client.py +82 -1
- deezer_python_gql-0.20.0/deezer_python_gql/generated/input_types.py +0 -3
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/LICENSE +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/MANIFEST.in +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/__init__.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/add_album_to_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/add_artist_to_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/add_audiobook_to_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/add_playlist_to_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/add_podcast_to_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/add_track_to_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/add_tracks_to_playlist.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/ban_artist_from_recommendation.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/ban_track_from_recommendation.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/base_model.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/bookmark_podcast_episode.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/create_playlist.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/delete_playlist.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/fragments.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_album.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_artist.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_artist_mix.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_audiobook.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_audiobook_chapter.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_banned_artists.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_banned_tracks.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_charts.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_family.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_favorite_albums.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_favorite_artists.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_favorite_audiobooks.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_favorite_playlists.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_favorite_podcasts.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_favorite_tracks.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_flow.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_flow_batch.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_flow_config_tracks.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_flow_configs.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_flow_tuner.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_infinite_track_mix.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_latest_podcast_episodes.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_livestream.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_made_for_me.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_me.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_music_together_affinity.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_music_together_group.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_music_together_groups.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_personal_tracks.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_playlist.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_podcast.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_podcast_episode.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_podcast_episode_bookmarks.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_podcast_episodes_by_ids.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_recently_played.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_recommendations.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_similar_artists.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_similar_tracks.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_smart_tracklist.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_track.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_track_mix.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_tracks_by_ids.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_user_charts.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_user_playlists.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/mark_as_not_played_podcast_episode.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/mark_as_played_podcast_episode.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/music_together_create_group.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/music_together_generate_group_name.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/music_together_join_group.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/music_together_leave_group.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/music_together_refresh_suggested_tracklist.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/music_together_update_group_settings.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/remove_album_from_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/remove_artist_from_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/remove_audiobook_from_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/remove_playlist_from_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/remove_podcast_from_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/remove_track_from_favorite.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/remove_tracks_from_playlist.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/search.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/search_flows.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/set_flow_discovery_tuner.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/unban_artist_from_recommendation.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/unban_track_from_recommendation.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/unbookmark_podcast_episode.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/update_playlist.py +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/py.typed +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql.egg-info/dependency_links.txt +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql.egg-info/not-zip-safe +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql.egg-info/top_level.txt +0 -0
- {deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deezer-python-gql
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.22.1
|
|
4
4
|
Summary: Async typed Python client for Deezer's Pipe GraphQL API.
|
|
5
5
|
Author-email: Julian Daberkow <jdaberkow@users.noreply.github.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -16,13 +16,13 @@ Requires-Dist: pydantic>=2.0.0
|
|
|
16
16
|
Requires-Dist: yarl>=1.22.0
|
|
17
17
|
Provides-Extra: test
|
|
18
18
|
Requires-Dist: codespell==2.4.3; extra == "test"
|
|
19
|
-
Requires-Dist: mypy==2.
|
|
20
|
-
Requires-Dist: pre-commit==4.
|
|
19
|
+
Requires-Dist: mypy==2.4.1; extra == "test"
|
|
20
|
+
Requires-Dist: pre-commit==4.7.0; extra == "test"
|
|
21
21
|
Requires-Dist: pre-commit-hooks==6.0.0; extra == "test"
|
|
22
|
-
Requires-Dist: pytest==9.
|
|
23
|
-
Requires-Dist: pytest-asyncio==1.4.
|
|
22
|
+
Requires-Dist: pytest==9.2.0; extra == "test"
|
|
23
|
+
Requires-Dist: pytest-asyncio==1.4.1.post1; extra == "test"
|
|
24
24
|
Requires-Dist: pytest-cov==7.1.0; extra == "test"
|
|
25
|
-
Requires-Dist: ruff==0.
|
|
25
|
+
Requires-Dist: ruff==0.17.3; extra == "test"
|
|
26
26
|
Provides-Extra: dev
|
|
27
27
|
Requires-Dist: ariadne-codegen[subscriptions]; extra == "dev"
|
|
28
28
|
Dynamic: license-file
|
|
@@ -191,6 +191,7 @@ Keep a track or artist out of the user's recommendations (Flow, mixes).
|
|
|
191
191
|
| `delete_playlist(playlist_id)` | Delete a playlist |
|
|
192
192
|
| `add_tracks_to_playlist(playlist_id, track_ids)` | Add tracks to a playlist |
|
|
193
193
|
| `remove_tracks_from_playlist(playlist_id, ...)` | Remove tracks from a playlist |
|
|
194
|
+
| `move_track_in_playlist(playlist_id, ...)` | Move a track behind another one or to the top |
|
|
194
195
|
|
|
195
196
|
### Podcast Episode Management
|
|
196
197
|
|
|
@@ -162,6 +162,7 @@ Keep a track or artist out of the user's recommendations (Flow, mixes).
|
|
|
162
162
|
| `delete_playlist(playlist_id)` | Delete a playlist |
|
|
163
163
|
| `add_tracks_to_playlist(playlist_id, track_ids)` | Add tracks to a playlist |
|
|
164
164
|
| `remove_tracks_from_playlist(playlist_id, ...)` | Remove tracks from a playlist |
|
|
165
|
+
| `move_track_in_playlist(playlist_id, ...)` | Move a track behind another one or to the top |
|
|
165
166
|
|
|
166
167
|
### Podcast Episode Management
|
|
167
168
|
|
|
@@ -11,6 +11,7 @@ from dataclasses import dataclass
|
|
|
11
11
|
from typing import TYPE_CHECKING, Any, ClassVar, Self, cast
|
|
12
12
|
|
|
13
13
|
from aiohttp import ClientSession, ClientTimeout
|
|
14
|
+
from pydantic_core import to_jsonable_python
|
|
14
15
|
from yarl import URL
|
|
15
16
|
|
|
16
17
|
if TYPE_CHECKING:
|
|
@@ -227,8 +228,11 @@ class DeezerBaseClient:
|
|
|
227
228
|
# Inline import avoids depending on generated code at module level.
|
|
228
229
|
from deezer_python_gql.generated.base_model import UnsetType # noqa: PLC0415
|
|
229
230
|
|
|
231
|
+
# input types are pydantic models, sent under their GraphQL field names
|
|
230
232
|
payload["variables"] = {
|
|
231
|
-
k:
|
|
233
|
+
k: to_jsonable_python(v, by_alias=True)
|
|
234
|
+
for k, v in variables.items()
|
|
235
|
+
if not isinstance(v, UnsetType)
|
|
232
236
|
}
|
|
233
237
|
|
|
234
238
|
session = self._get_session()
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/__init__.py
RENAMED
|
@@ -63,10 +63,12 @@ from .enums import (
|
|
|
63
63
|
AudiobookContributorRoles,
|
|
64
64
|
DiscoveryTuner,
|
|
65
65
|
DiscoveryTunerInput,
|
|
66
|
+
MediaTypeInput,
|
|
66
67
|
MusicTogetherRefreshSuggestedTracklistMoodInput,
|
|
67
68
|
MusicTogetherSuggestedTracklistMoodInput,
|
|
68
69
|
PodcastEpisodeOrder,
|
|
69
70
|
PodcastType,
|
|
71
|
+
RepeatModeInput,
|
|
70
72
|
TrackContributorRoles,
|
|
71
73
|
)
|
|
72
74
|
from .fragments import (
|
|
@@ -551,6 +553,12 @@ from .get_user_playlists import (
|
|
|
551
553
|
GetUserPlaylistsMePlaylistsEdgesNode,
|
|
552
554
|
GetUserPlaylistsMePlaylistsPageInfo,
|
|
553
555
|
)
|
|
556
|
+
from .input_types import (
|
|
557
|
+
PushQueueContextInput,
|
|
558
|
+
PushQueueMediaInput,
|
|
559
|
+
PushQueueStateClientDetailsInput,
|
|
560
|
+
PushQueueStateInput,
|
|
561
|
+
)
|
|
554
562
|
from .mark_as_not_played_podcast_episode import (
|
|
555
563
|
MarkAsNotPlayedPodcastEpisode,
|
|
556
564
|
MarkAsNotPlayedPodcastEpisodeMarkAsNotPlayedPodcastEpisode,
|
|
@@ -561,6 +569,10 @@ from .mark_as_played_podcast_episode import (
|
|
|
561
569
|
MarkAsPlayedPodcastEpisodeMarkAsPlayedPodcastEpisode,
|
|
562
570
|
MarkAsPlayedPodcastEpisodeMarkAsPlayedPodcastEpisodeBookmark,
|
|
563
571
|
)
|
|
572
|
+
from .move_track_in_playlist import (
|
|
573
|
+
MoveTrackInPlaylist,
|
|
574
|
+
MoveTrackInPlaylistMoveTrackInPlaylist,
|
|
575
|
+
)
|
|
564
576
|
from .music_together_create_group import (
|
|
565
577
|
MusicTogetherCreateGroup,
|
|
566
578
|
MusicTogetherCreateGroupMusicTogetherCreateGroupMusicTogetherCreateGroupError,
|
|
@@ -595,6 +607,13 @@ from .music_together_update_group_settings import (
|
|
|
595
607
|
MusicTogetherUpdateGroupSettingsMusicTogetherUpdateGroupSettingsMusicTogetherUpdateGroupSettingsOutput,
|
|
596
608
|
MusicTogetherUpdateGroupSettingsMusicTogetherUpdateGroupSettingsMusicTogetherUpdateGroupSettingsOutputGroup,
|
|
597
609
|
)
|
|
610
|
+
from .push_queue_state import (
|
|
611
|
+
PushQueueState,
|
|
612
|
+
PushQueueStatePushQueueStatePushQueueStateError,
|
|
613
|
+
PushQueueStatePushQueueStatePushQueueStateErrorConflict,
|
|
614
|
+
PushQueueStatePushQueueStatePushQueueStateErrorConflictCurrent,
|
|
615
|
+
PushQueueStatePushQueueStatePushQueueStateOutput,
|
|
616
|
+
)
|
|
598
617
|
from .remove_album_from_favorite import (
|
|
599
618
|
RemoveAlbumFromFavorite,
|
|
600
619
|
RemoveAlbumFromFavoriteRemoveAlbumFromFavorite,
|
|
@@ -1143,6 +1162,9 @@ __all__ = [
|
|
|
1143
1162
|
"MarkAsPlayedPodcastEpisode",
|
|
1144
1163
|
"MarkAsPlayedPodcastEpisodeMarkAsPlayedPodcastEpisode",
|
|
1145
1164
|
"MarkAsPlayedPodcastEpisodeMarkAsPlayedPodcastEpisodeBookmark",
|
|
1165
|
+
"MediaTypeInput",
|
|
1166
|
+
"MoveTrackInPlaylist",
|
|
1167
|
+
"MoveTrackInPlaylistMoveTrackInPlaylist",
|
|
1146
1168
|
"MusicTogetherCreateGroup",
|
|
1147
1169
|
"MusicTogetherCreateGroupMusicTogetherCreateGroupMusicTogetherCreateGroupError",
|
|
1148
1170
|
"MusicTogetherCreateGroupMusicTogetherCreateGroupMusicTogetherCreateGroupOutput",
|
|
@@ -1179,6 +1201,15 @@ __all__ = [
|
|
|
1179
1201
|
"PodcastFields",
|
|
1180
1202
|
"PodcastFieldsCover",
|
|
1181
1203
|
"PodcastType",
|
|
1204
|
+
"PushQueueContextInput",
|
|
1205
|
+
"PushQueueMediaInput",
|
|
1206
|
+
"PushQueueState",
|
|
1207
|
+
"PushQueueStateClientDetailsInput",
|
|
1208
|
+
"PushQueueStateInput",
|
|
1209
|
+
"PushQueueStatePushQueueStatePushQueueStateError",
|
|
1210
|
+
"PushQueueStatePushQueueStatePushQueueStateErrorConflict",
|
|
1211
|
+
"PushQueueStatePushQueueStatePushQueueStateErrorConflictCurrent",
|
|
1212
|
+
"PushQueueStatePushQueueStatePushQueueStateOutput",
|
|
1182
1213
|
"RemoveAlbumFromFavorite",
|
|
1183
1214
|
"RemoveAlbumFromFavoriteRemoveAlbumFromFavorite",
|
|
1184
1215
|
"RemoveAlbumFromFavoriteRemoveAlbumFromFavoriteAlbum",
|
|
@@ -1198,6 +1229,7 @@ __all__ = [
|
|
|
1198
1229
|
"RemoveTrackFromFavoriteRemoveTrackFromFavoriteTrack",
|
|
1199
1230
|
"RemoveTracksFromPlaylist",
|
|
1200
1231
|
"RemoveTracksFromPlaylistRemoveTracksFromPlaylist",
|
|
1232
|
+
"RepeatModeInput",
|
|
1201
1233
|
"Search",
|
|
1202
1234
|
"SearchFlows",
|
|
1203
1235
|
"SearchFlowsSearch",
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/base_client.py
RENAMED
|
@@ -13,6 +13,7 @@ from dataclasses import dataclass
|
|
|
13
13
|
from typing import TYPE_CHECKING, Any, ClassVar, Self, cast
|
|
14
14
|
|
|
15
15
|
from aiohttp import ClientSession, ClientTimeout
|
|
16
|
+
from pydantic_core import to_jsonable_python
|
|
16
17
|
from yarl import URL
|
|
17
18
|
|
|
18
19
|
if TYPE_CHECKING:
|
|
@@ -229,8 +230,11 @@ class DeezerBaseClient:
|
|
|
229
230
|
# Inline import avoids depending on generated code at module level.
|
|
230
231
|
from deezer_python_gql.generated.base_model import UnsetType # noqa: PLC0415
|
|
231
232
|
|
|
233
|
+
# input types are pydantic models, sent under their GraphQL field names
|
|
232
234
|
payload["variables"] = {
|
|
233
|
-
k:
|
|
235
|
+
k: to_jsonable_python(v, by_alias=True)
|
|
236
|
+
for k, v in variables.items()
|
|
237
|
+
if not isinstance(v, UnsetType)
|
|
234
238
|
}
|
|
235
239
|
|
|
236
240
|
session = self._get_session()
|
|
@@ -119,6 +119,7 @@ from .get_track_mix import GetTrackMix, GetTrackMixTrackMix
|
|
|
119
119
|
from .get_tracks_by_ids import GetTracksByIds, GetTracksByIdsTracksByIds
|
|
120
120
|
from .get_user_charts import GetUserCharts, GetUserChartsMe
|
|
121
121
|
from .get_user_playlists import GetUserPlaylists, GetUserPlaylistsMe
|
|
122
|
+
from .input_types import PushQueueStateInput
|
|
122
123
|
from .mark_as_not_played_podcast_episode import (
|
|
123
124
|
MarkAsNotPlayedPodcastEpisode,
|
|
124
125
|
MarkAsNotPlayedPodcastEpisodeMarkAsNotPlayedPodcastEpisode,
|
|
@@ -127,6 +128,10 @@ from .mark_as_played_podcast_episode import (
|
|
|
127
128
|
MarkAsPlayedPodcastEpisode,
|
|
128
129
|
MarkAsPlayedPodcastEpisodeMarkAsPlayedPodcastEpisode,
|
|
129
130
|
)
|
|
131
|
+
from .move_track_in_playlist import (
|
|
132
|
+
MoveTrackInPlaylist,
|
|
133
|
+
MoveTrackInPlaylistMoveTrackInPlaylist,
|
|
134
|
+
)
|
|
130
135
|
from .music_together_create_group import (
|
|
131
136
|
MusicTogetherCreateGroup,
|
|
132
137
|
MusicTogetherCreateGroupMusicTogetherCreateGroupMusicTogetherCreateGroupError,
|
|
@@ -156,6 +161,11 @@ from .music_together_update_group_settings import (
|
|
|
156
161
|
MusicTogetherUpdateGroupSettingsMusicTogetherUpdateGroupSettingsMusicTogetherUpdateGroupSettingsError,
|
|
157
162
|
MusicTogetherUpdateGroupSettingsMusicTogetherUpdateGroupSettingsMusicTogetherUpdateGroupSettingsOutput,
|
|
158
163
|
)
|
|
164
|
+
from .push_queue_state import (
|
|
165
|
+
PushQueueState,
|
|
166
|
+
PushQueueStatePushQueueStatePushQueueStateError,
|
|
167
|
+
PushQueueStatePushQueueStatePushQueueStateOutput,
|
|
168
|
+
)
|
|
159
169
|
from .remove_album_from_favorite import (
|
|
160
170
|
RemoveAlbumFromFavorite,
|
|
161
171
|
RemoveAlbumFromFavoriteRemoveAlbumFromFavorite,
|
|
@@ -4435,6 +4445,67 @@ class DeezerGQLClient(DeezerBaseClient):
|
|
|
4435
4445
|
data = self.get_data(response)
|
|
4436
4446
|
return RemoveTracksFromPlaylist.model_validate(data).remove_tracks_from_playlist
|
|
4437
4447
|
|
|
4448
|
+
async def move_track_in_playlist(
|
|
4449
|
+
self,
|
|
4450
|
+
playlist_id: str,
|
|
4451
|
+
track_id: str,
|
|
4452
|
+
after_track_id: Union[Optional[str], UnsetType] = UNSET,
|
|
4453
|
+
**kwargs: Any,
|
|
4454
|
+
) -> MoveTrackInPlaylistMoveTrackInPlaylist:
|
|
4455
|
+
query = gql("""
|
|
4456
|
+
mutation MoveTrackInPlaylist($playlistId: String!, $trackId: String!, $afterTrackId: String) {
|
|
4457
|
+
moveTrackInPlaylist(
|
|
4458
|
+
input: {playlistId: $playlistId, trackId: $trackId, afterTrackId: $afterTrackId}
|
|
4459
|
+
) {
|
|
4460
|
+
moveStatus
|
|
4461
|
+
}
|
|
4462
|
+
}
|
|
4463
|
+
""")
|
|
4464
|
+
variables: dict[str, object] = {
|
|
4465
|
+
"playlistId": playlist_id,
|
|
4466
|
+
"trackId": track_id,
|
|
4467
|
+
"afterTrackId": after_track_id,
|
|
4468
|
+
}
|
|
4469
|
+
response = await self.execute(
|
|
4470
|
+
query=query,
|
|
4471
|
+
operation_name="MoveTrackInPlaylist",
|
|
4472
|
+
variables=variables,
|
|
4473
|
+
**kwargs,
|
|
4474
|
+
)
|
|
4475
|
+
data = self.get_data(response)
|
|
4476
|
+
return MoveTrackInPlaylist.model_validate(data).move_track_in_playlist
|
|
4477
|
+
|
|
4478
|
+
async def push_queue_state(
|
|
4479
|
+
self, input: PushQueueStateInput, **kwargs: Any
|
|
4480
|
+
) -> Union[
|
|
4481
|
+
PushQueueStatePushQueueStatePushQueueStateOutput,
|
|
4482
|
+
PushQueueStatePushQueueStatePushQueueStateError,
|
|
4483
|
+
]:
|
|
4484
|
+
query = gql("""
|
|
4485
|
+
mutation PushQueueState($input: PushQueueStateInput!) {
|
|
4486
|
+
pushQueueState(input: $input) {
|
|
4487
|
+
__typename
|
|
4488
|
+
... on PushQueueStateOutput {
|
|
4489
|
+
version
|
|
4490
|
+
}
|
|
4491
|
+
... on PushQueueStateError {
|
|
4492
|
+
isBadRequest
|
|
4493
|
+
conflict {
|
|
4494
|
+
current {
|
|
4495
|
+
version
|
|
4496
|
+
}
|
|
4497
|
+
}
|
|
4498
|
+
}
|
|
4499
|
+
}
|
|
4500
|
+
}
|
|
4501
|
+
""")
|
|
4502
|
+
variables: dict[str, object] = {"input": input}
|
|
4503
|
+
response = await self.execute(
|
|
4504
|
+
query=query, operation_name="PushQueueState", variables=variables, **kwargs
|
|
4505
|
+
)
|
|
4506
|
+
data = self.get_data(response)
|
|
4507
|
+
return PushQueueState.model_validate(data).push_queue_state
|
|
4508
|
+
|
|
4438
4509
|
async def ban_track_from_recommendation(
|
|
4439
4510
|
self, track_id: str, **kwargs: Any
|
|
4440
4511
|
) -> BanTrackFromRecommendationBanTrackFromRecommendation:
|
|
@@ -46,6 +46,20 @@ class PodcastEpisodeOrder(str, Enum):
|
|
|
46
46
|
LATEST = "LATEST"
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
class MediaTypeInput(str, Enum):
|
|
50
|
+
TRACK = "TRACK"
|
|
51
|
+
EPISODE = "EPISODE"
|
|
52
|
+
CHAPTER = "CHAPTER"
|
|
53
|
+
LIVE = "LIVE"
|
|
54
|
+
RAW_URL = "RAW_URL"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class RepeatModeInput(str, Enum):
|
|
58
|
+
NONE = "NONE"
|
|
59
|
+
ONE = "ONE"
|
|
60
|
+
ALL = "ALL"
|
|
61
|
+
|
|
62
|
+
|
|
49
63
|
class DiscoveryTuner(str, Enum):
|
|
50
64
|
DEFAULT = "DEFAULT"
|
|
51
65
|
DISCOVERY = "DISCOVERY"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Generated by ariadne-codegen
|
|
2
|
+
# Source: schema.graphql
|
|
3
|
+
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from pydantic import Field
|
|
7
|
+
|
|
8
|
+
from .base_model import BaseModel
|
|
9
|
+
from .enums import MediaTypeInput, RepeatModeInput
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PushQueueStateInput(BaseModel):
|
|
13
|
+
client_details: "PushQueueStateClientDetailsInput" = Field(alias="clientDetails")
|
|
14
|
+
"Details about the client pushing the queue state"
|
|
15
|
+
media_list: list["PushQueueMediaInput"] = Field(alias="mediaList")
|
|
16
|
+
"List of all media in the queue in playing order"
|
|
17
|
+
position: int
|
|
18
|
+
"Zero based index of the current playback position in the queue"
|
|
19
|
+
progress_ms: Optional[int] = Field(alias="progressMS", default=None)
|
|
20
|
+
"Progress in the current media in ms"
|
|
21
|
+
previous_version: Optional[str] = Field(alias="previousVersion", default=None)
|
|
22
|
+
"Previous known queue state version\nNote: Except when there is no queue state available, this version MUST be provided otherwise you'll get a conflict error"
|
|
23
|
+
queue_configuration: str = Field(alias="queueConfiguration")
|
|
24
|
+
"Queue's configuration"
|
|
25
|
+
repeat_mode: RepeatModeInput = Field(alias="repeatMode")
|
|
26
|
+
"Queue repeat mode"
|
|
27
|
+
contexts: Optional[list["PushQueueContextInput"]] = None
|
|
28
|
+
"The list of unique contexts referenced by mediaList.contextId"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class PushQueueMediaInput(BaseModel):
|
|
32
|
+
"""Details of media that belongs to the pushed queue"""
|
|
33
|
+
|
|
34
|
+
id: str
|
|
35
|
+
"The media id"
|
|
36
|
+
type_: MediaTypeInput = Field(alias="type")
|
|
37
|
+
"The media type"
|
|
38
|
+
context_id: Optional[str] = Field(alias="contextId", default=None)
|
|
39
|
+
'The context identifier, it should correspond to an entry in "PushQueueStateInput.contexts"\nEach media can have its own context or share multiple time the same context by using the same contextId'
|
|
40
|
+
local_queue_item_id: Optional[str] = Field(alias="localQueueItemId", default=None)
|
|
41
|
+
"Item identifier used on client side"
|
|
42
|
+
unshuffled_position: int = Field(alias="unshuffledPosition")
|
|
43
|
+
"The position within the unshuffled version of the queue"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class PushQueueContextInput(BaseModel):
|
|
47
|
+
id: str
|
|
48
|
+
"Context identifier"
|
|
49
|
+
content: str
|
|
50
|
+
"The context content itself"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class PushQueueStateClientDetailsInput(BaseModel):
|
|
54
|
+
"""Details about the client that wants to push the queue state"""
|
|
55
|
+
|
|
56
|
+
local_queue_id: str = Field(alias="localQueueID")
|
|
57
|
+
"Identifier of the client's local queue, doesn't necessarily match a real queue id"
|
|
58
|
+
locally_updated_at: str = Field(alias="locallyUpdatedAt")
|
|
59
|
+
"Date in ISO-8601 format including milliseconds when update was made on client"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
PushQueueStateInput.model_rebuild()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Generated by ariadne-codegen
|
|
2
|
+
# Source: queries
|
|
3
|
+
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from pydantic import Field
|
|
7
|
+
|
|
8
|
+
from .base_model import BaseModel
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MoveTrackInPlaylist(BaseModel):
|
|
12
|
+
move_track_in_playlist: "MoveTrackInPlaylistMoveTrackInPlaylist" = Field(
|
|
13
|
+
alias="moveTrackInPlaylist"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MoveTrackInPlaylistMoveTrackInPlaylist(BaseModel):
|
|
18
|
+
move_status: Optional[bool] = Field(alias="moveStatus")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
MoveTrackInPlaylist.model_rebuild()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Generated by ariadne-codegen
|
|
2
|
+
# Source: queries
|
|
3
|
+
|
|
4
|
+
from typing import Literal, Optional, Union
|
|
5
|
+
|
|
6
|
+
from pydantic import Field
|
|
7
|
+
|
|
8
|
+
from .base_model import BaseModel
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PushQueueState(BaseModel):
|
|
12
|
+
push_queue_state: Union[
|
|
13
|
+
"PushQueueStatePushQueueStatePushQueueStateOutput",
|
|
14
|
+
"PushQueueStatePushQueueStatePushQueueStateError",
|
|
15
|
+
] = Field(alias="pushQueueState", discriminator="typename__")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class PushQueueStatePushQueueStatePushQueueStateOutput(BaseModel):
|
|
19
|
+
typename__: Literal["PushQueueStateOutput"] = Field(alias="__typename")
|
|
20
|
+
version: str
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class PushQueueStatePushQueueStatePushQueueStateError(BaseModel):
|
|
24
|
+
typename__: Literal["PushQueueStateError"] = Field(alias="__typename")
|
|
25
|
+
is_bad_request: bool = Field(alias="isBadRequest")
|
|
26
|
+
conflict: Optional["PushQueueStatePushQueueStatePushQueueStateErrorConflict"]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class PushQueueStatePushQueueStatePushQueueStateErrorConflict(BaseModel):
|
|
30
|
+
current: Optional["PushQueueStatePushQueueStatePushQueueStateErrorConflictCurrent"]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class PushQueueStatePushQueueStatePushQueueStateErrorConflictCurrent(BaseModel):
|
|
34
|
+
version: str
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
PushQueueState.model_rebuild()
|
|
38
|
+
PushQueueStatePushQueueStatePushQueueStateError.model_rebuild()
|
|
39
|
+
PushQueueStatePushQueueStatePushQueueStateErrorConflict.model_rebuild()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deezer-python-gql
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.22.1
|
|
4
4
|
Summary: Async typed Python client for Deezer's Pipe GraphQL API.
|
|
5
5
|
Author-email: Julian Daberkow <jdaberkow@users.noreply.github.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -16,13 +16,13 @@ Requires-Dist: pydantic>=2.0.0
|
|
|
16
16
|
Requires-Dist: yarl>=1.22.0
|
|
17
17
|
Provides-Extra: test
|
|
18
18
|
Requires-Dist: codespell==2.4.3; extra == "test"
|
|
19
|
-
Requires-Dist: mypy==2.
|
|
20
|
-
Requires-Dist: pre-commit==4.
|
|
19
|
+
Requires-Dist: mypy==2.4.1; extra == "test"
|
|
20
|
+
Requires-Dist: pre-commit==4.7.0; extra == "test"
|
|
21
21
|
Requires-Dist: pre-commit-hooks==6.0.0; extra == "test"
|
|
22
|
-
Requires-Dist: pytest==9.
|
|
23
|
-
Requires-Dist: pytest-asyncio==1.4.
|
|
22
|
+
Requires-Dist: pytest==9.2.0; extra == "test"
|
|
23
|
+
Requires-Dist: pytest-asyncio==1.4.1.post1; extra == "test"
|
|
24
24
|
Requires-Dist: pytest-cov==7.1.0; extra == "test"
|
|
25
|
-
Requires-Dist: ruff==0.
|
|
25
|
+
Requires-Dist: ruff==0.17.3; extra == "test"
|
|
26
26
|
Provides-Extra: dev
|
|
27
27
|
Requires-Dist: ariadne-codegen[subscriptions]; extra == "dev"
|
|
28
28
|
Dynamic: license-file
|
|
@@ -191,6 +191,7 @@ Keep a track or artist out of the user's recommendations (Flow, mixes).
|
|
|
191
191
|
| `delete_playlist(playlist_id)` | Delete a playlist |
|
|
192
192
|
| `add_tracks_to_playlist(playlist_id, track_ids)` | Add tracks to a playlist |
|
|
193
193
|
| `remove_tracks_from_playlist(playlist_id, ...)` | Remove tracks from a playlist |
|
|
194
|
+
| `move_track_in_playlist(playlist_id, ...)` | Move a track behind another one or to the top |
|
|
194
195
|
|
|
195
196
|
### Podcast Episode Management
|
|
196
197
|
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql.egg-info/SOURCES.txt
RENAMED
|
@@ -76,12 +76,14 @@ deezer_python_gql/generated/get_user_playlists.py
|
|
|
76
76
|
deezer_python_gql/generated/input_types.py
|
|
77
77
|
deezer_python_gql/generated/mark_as_not_played_podcast_episode.py
|
|
78
78
|
deezer_python_gql/generated/mark_as_played_podcast_episode.py
|
|
79
|
+
deezer_python_gql/generated/move_track_in_playlist.py
|
|
79
80
|
deezer_python_gql/generated/music_together_create_group.py
|
|
80
81
|
deezer_python_gql/generated/music_together_generate_group_name.py
|
|
81
82
|
deezer_python_gql/generated/music_together_join_group.py
|
|
82
83
|
deezer_python_gql/generated/music_together_leave_group.py
|
|
83
84
|
deezer_python_gql/generated/music_together_refresh_suggested_tracklist.py
|
|
84
85
|
deezer_python_gql/generated/music_together_update_group_settings.py
|
|
86
|
+
deezer_python_gql/generated/push_queue_state.py
|
|
85
87
|
deezer_python_gql/generated/remove_album_from_favorite.py
|
|
86
88
|
deezer_python_gql/generated/remove_artist_from_favorite.py
|
|
87
89
|
deezer_python_gql/generated/remove_audiobook_from_favorite.py
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql.egg-info/requires.txt
RENAMED
|
@@ -7,10 +7,10 @@ ariadne-codegen[subscriptions]
|
|
|
7
7
|
|
|
8
8
|
[test]
|
|
9
9
|
codespell==2.4.3
|
|
10
|
-
mypy==2.
|
|
11
|
-
pre-commit==4.
|
|
10
|
+
mypy==2.4.1
|
|
11
|
+
pre-commit==4.7.0
|
|
12
12
|
pre-commit-hooks==6.0.0
|
|
13
|
-
pytest==9.
|
|
14
|
-
pytest-asyncio==1.4.
|
|
13
|
+
pytest==9.2.0
|
|
14
|
+
pytest-asyncio==1.4.1.post1
|
|
15
15
|
pytest-cov==7.1.0
|
|
16
|
-
ruff==0.
|
|
16
|
+
ruff==0.17.3
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "deezer-python-gql"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.22.1"
|
|
4
4
|
description = "Async typed Python client for Deezer's Pipe GraphQL API."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -24,13 +24,13 @@ text = "Apache-2.0"
|
|
|
24
24
|
[project.optional-dependencies]
|
|
25
25
|
test = [
|
|
26
26
|
"codespell==2.4.3",
|
|
27
|
-
"mypy==2.
|
|
28
|
-
"pre-commit==4.
|
|
27
|
+
"mypy==2.4.1",
|
|
28
|
+
"pre-commit==4.7.0",
|
|
29
29
|
"pre-commit-hooks==6.0.0",
|
|
30
|
-
"pytest==9.
|
|
31
|
-
"pytest-asyncio==1.4.
|
|
30
|
+
"pytest==9.2.0",
|
|
31
|
+
"pytest-asyncio==1.4.1.post1",
|
|
32
32
|
"pytest-cov==7.1.0",
|
|
33
|
-
"ruff==0.
|
|
33
|
+
"ruff==0.17.3",
|
|
34
34
|
]
|
|
35
35
|
dev = [
|
|
36
36
|
"ariadne-codegen[subscriptions]",
|
|
@@ -182,5 +182,5 @@ asyncio_mode = "auto"
|
|
|
182
182
|
|
|
183
183
|
[tool.uv]
|
|
184
184
|
override-dependencies = [
|
|
185
|
-
"ruff==0.
|
|
185
|
+
"ruff==0.17.3",
|
|
186
186
|
]
|
|
@@ -48,7 +48,7 @@ from deezer_python_gql.generated.ban_track_from_recommendation import (
|
|
|
48
48
|
from deezer_python_gql.generated.bookmark_podcast_episode import BookmarkPodcastEpisode
|
|
49
49
|
from deezer_python_gql.generated.create_playlist import CreatePlaylist
|
|
50
50
|
from deezer_python_gql.generated.delete_playlist import DeletePlaylist
|
|
51
|
-
from deezer_python_gql.generated.enums import PodcastType
|
|
51
|
+
from deezer_python_gql.generated.enums import MediaTypeInput, PodcastType, RepeatModeInput
|
|
52
52
|
from deezer_python_gql.generated.get_album import GetAlbum
|
|
53
53
|
from deezer_python_gql.generated.get_artist import GetArtist
|
|
54
54
|
from deezer_python_gql.generated.get_artist_mix import GetArtistMix
|
|
@@ -99,12 +99,18 @@ from deezer_python_gql.generated.get_track_mix import GetTrackMix
|
|
|
99
99
|
from deezer_python_gql.generated.get_tracks_by_ids import GetTracksByIds
|
|
100
100
|
from deezer_python_gql.generated.get_user_charts import GetUserCharts
|
|
101
101
|
from deezer_python_gql.generated.get_user_playlists import GetUserPlaylists
|
|
102
|
+
from deezer_python_gql.generated.input_types import (
|
|
103
|
+
PushQueueMediaInput,
|
|
104
|
+
PushQueueStateClientDetailsInput,
|
|
105
|
+
PushQueueStateInput,
|
|
106
|
+
)
|
|
102
107
|
from deezer_python_gql.generated.mark_as_not_played_podcast_episode import (
|
|
103
108
|
MarkAsNotPlayedPodcastEpisode,
|
|
104
109
|
)
|
|
105
110
|
from deezer_python_gql.generated.mark_as_played_podcast_episode import (
|
|
106
111
|
MarkAsPlayedPodcastEpisode,
|
|
107
112
|
)
|
|
113
|
+
from deezer_python_gql.generated.move_track_in_playlist import MoveTrackInPlaylist
|
|
108
114
|
from deezer_python_gql.generated.music_together_create_group import (
|
|
109
115
|
MusicTogetherCreateGroup,
|
|
110
116
|
)
|
|
@@ -113,6 +119,11 @@ from deezer_python_gql.generated.music_together_generate_group_name import (
|
|
|
113
119
|
)
|
|
114
120
|
from deezer_python_gql.generated.music_together_join_group import MusicTogetherJoinGroup
|
|
115
121
|
from deezer_python_gql.generated.music_together_leave_group import MusicTogetherLeaveGroup
|
|
122
|
+
from deezer_python_gql.generated.push_queue_state import (
|
|
123
|
+
PushQueueState,
|
|
124
|
+
PushQueueStatePushQueueStatePushQueueStateError,
|
|
125
|
+
PushQueueStatePushQueueStatePushQueueStateOutput,
|
|
126
|
+
)
|
|
116
127
|
from deezer_python_gql.generated.remove_album_from_favorite import RemoveAlbumFromFavorite
|
|
117
128
|
from deezer_python_gql.generated.remove_artist_from_favorite import RemoveArtistFromFavorite
|
|
118
129
|
from deezer_python_gql.generated.remove_audiobook_from_favorite import (
|
|
@@ -340,6 +351,7 @@ def test_client_has_generated_methods() -> None:
|
|
|
340
351
|
"delete_playlist",
|
|
341
352
|
"add_tracks_to_playlist",
|
|
342
353
|
"remove_tracks_from_playlist",
|
|
354
|
+
"move_track_in_playlist",
|
|
343
355
|
"get_podcast",
|
|
344
356
|
"get_podcast_episode",
|
|
345
357
|
"get_podcast_episodes_by_ids",
|
|
@@ -376,6 +388,7 @@ def test_client_has_generated_methods() -> None:
|
|
|
376
388
|
"get_latest_podcast_episodes",
|
|
377
389
|
"get_tracks_by_ids",
|
|
378
390
|
"set_flow_discovery_tuner",
|
|
391
|
+
"push_queue_state",
|
|
379
392
|
]
|
|
380
393
|
for method in expected_methods:
|
|
381
394
|
assert hasattr(client, method), f"Missing method: {method}"
|
|
@@ -1523,6 +1536,13 @@ def test_smoke_remove_tracks_from_playlist() -> None:
|
|
|
1523
1536
|
assert result.remove_tracks_from_playlist.removed_track_ids == ["100000001", "100000002"]
|
|
1524
1537
|
|
|
1525
1538
|
|
|
1539
|
+
def test_smoke_move_track_in_playlist() -> None:
|
|
1540
|
+
"""Verify MoveTrackInPlaylist fixture parses with move status."""
|
|
1541
|
+
data = _load_fixture("move_track_in_playlist.json")
|
|
1542
|
+
result = MoveTrackInPlaylist.model_validate(data)
|
|
1543
|
+
assert result.move_track_in_playlist.move_status is True
|
|
1544
|
+
|
|
1545
|
+
|
|
1526
1546
|
def test_smoke_get_livestream() -> None:
|
|
1527
1547
|
"""Verify GetLivestream fixture parses with fields and media URLs."""
|
|
1528
1548
|
data = _load_fixture("get_livestream.json")
|
|
@@ -2021,3 +2041,64 @@ def test_smoke_get_family() -> None:
|
|
|
2021
2041
|
("2002", True),
|
|
2022
2042
|
("3003", False),
|
|
2023
2043
|
]
|
|
2044
|
+
|
|
2045
|
+
|
|
2046
|
+
def test_smoke_push_queue_state() -> None:
|
|
2047
|
+
"""Verify PushQueueState fixture parses the new queue state version."""
|
|
2048
|
+
data = _load_fixture("push_queue_state.json")
|
|
2049
|
+
result = PushQueueState.model_validate(data).push_queue_state
|
|
2050
|
+
assert isinstance(result, PushQueueStatePushQueueStatePushQueueStateOutput)
|
|
2051
|
+
assert result.version == "01a1a613-c68c-731f-8677-15d9c535adbb"
|
|
2052
|
+
|
|
2053
|
+
|
|
2054
|
+
def test_smoke_push_queue_state_conflict() -> None:
|
|
2055
|
+
"""Verify a PushQueueState conflict parses the version it conflicts with."""
|
|
2056
|
+
data = _load_fixture("push_queue_state_conflict.json")
|
|
2057
|
+
result = PushQueueState.model_validate(data).push_queue_state
|
|
2058
|
+
assert isinstance(result, PushQueueStatePushQueueStatePushQueueStateError)
|
|
2059
|
+
assert result.is_bad_request is False
|
|
2060
|
+
assert result.conflict is not None
|
|
2061
|
+
assert result.conflict.current is not None
|
|
2062
|
+
assert result.conflict.current.version == "01a1a63d-1f5b-7d29-ae26-099eb9c20ab7"
|
|
2063
|
+
|
|
2064
|
+
|
|
2065
|
+
@pytest.mark.asyncio
|
|
2066
|
+
async def test_execute_sends_input_types_by_their_graphql_names() -> None:
|
|
2067
|
+
"""Verify an input type variable is sent as JSON with the API's field names."""
|
|
2068
|
+
client = DeezerGQLClient(arl="test_arl")
|
|
2069
|
+
client._jwt = _make_jwt(exp=time.time() + 600) # noqa: SLF001
|
|
2070
|
+
client._jwt_expires_at = time.time() + 600 # noqa: SLF001
|
|
2071
|
+
state = PushQueueStateInput(
|
|
2072
|
+
clientDetails=PushQueueStateClientDetailsInput(
|
|
2073
|
+
localQueueID="queue", locallyUpdatedAt="2026-11-04T10:21:16.223Z"
|
|
2074
|
+
),
|
|
2075
|
+
mediaList=[PushQueueMediaInput(id="1", type=MediaTypeInput.TRACK, unshuffledPosition=0)],
|
|
2076
|
+
position=0,
|
|
2077
|
+
queueConfiguration="{}",
|
|
2078
|
+
repeatMode=RepeatModeInput.NONE,
|
|
2079
|
+
)
|
|
2080
|
+
gql_cm = _mock_post_context_manager(
|
|
2081
|
+
json.dumps({"data": _load_fixture("push_queue_state.json")}).encode()
|
|
2082
|
+
)
|
|
2083
|
+
|
|
2084
|
+
# the generated client runs on the generated copy of the base client
|
|
2085
|
+
with patch("deezer_python_gql.generated.base_client.ClientSession") as mock_cls:
|
|
2086
|
+
mock_instance = MagicMock()
|
|
2087
|
+
mock_instance.post = MagicMock(return_value=gql_cm)
|
|
2088
|
+
mock_instance.close = AsyncMock()
|
|
2089
|
+
mock_cls.return_value = mock_instance
|
|
2090
|
+
|
|
2091
|
+
await client.push_queue_state(input=state)
|
|
2092
|
+
|
|
2093
|
+
sent = mock_instance.post.call_args.kwargs["json"]["variables"]["input"]
|
|
2094
|
+
assert sent["clientDetails"]["localQueueID"] == "queue"
|
|
2095
|
+
assert sent["mediaList"] == [
|
|
2096
|
+
{
|
|
2097
|
+
"id": "1",
|
|
2098
|
+
"type": "TRACK",
|
|
2099
|
+
"contextId": None,
|
|
2100
|
+
"localQueueItemId": None,
|
|
2101
|
+
"unshuffledPosition": 0,
|
|
2102
|
+
}
|
|
2103
|
+
]
|
|
2104
|
+
assert sent["repeatMode"] == "NONE"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/base_model.py
RENAMED
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/create_playlist.py
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/delete_playlist.py
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/fragments.py
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_album.py
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_artist.py
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_artist_mix.py
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_audiobook.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_charts.py
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_family.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_flow.py
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_flow_batch.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_flow_tuner.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_livestream.py
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_made_for_me.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_playlist.py
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_podcast.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_track.py
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_track_mix.py
RENAMED
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/get_user_charts.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/search_flows.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql/generated/update_playlist.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{deezer_python_gql-0.20.0 → deezer_python_gql-0.22.1}/deezer_python_gql.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|