deezer-python 6.2.0__py3-none-any.whl → 7.0.0__py3-none-any.whl
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/__init__.py +1 -1
- deezer/auth.py +27 -0
- deezer/client.py +48 -85
- deezer/exceptions.py +6 -6
- deezer/pagination.py +5 -5
- deezer/resources/editorial.py +4 -4
- deezer/resources/episode.py +4 -5
- deezer/resources/playlist.py +8 -14
- deezer/resources/resource.py +15 -11
- deezer/resources/user.py +22 -22
- {deezer_python-6.2.0.dist-info → deezer_python-7.0.0.dist-info}/METADATA +5 -5
- deezer_python-7.0.0.dist-info/RECORD +24 -0
- deezer_python-6.2.0.dist-info/RECORD +0 -23
- {deezer_python-6.2.0.dist-info → deezer_python-7.0.0.dist-info}/LICENSE.txt +0 -0
- {deezer_python-6.2.0.dist-info → deezer_python-7.0.0.dist-info}/WHEEL +0 -0
deezer/__init__.py
CHANGED
deezer/auth.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DeezerQueryAuth(httpx.Auth):
|
|
7
|
+
"""
|
|
8
|
+
Deezer Auth for httpx.
|
|
9
|
+
|
|
10
|
+
Attach given access token to the request,
|
|
11
|
+
by passing it as query parameter.
|
|
12
|
+
|
|
13
|
+
:param access_token: Your Deezer access token.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, access_token: str):
|
|
17
|
+
self.access_token = access_token
|
|
18
|
+
|
|
19
|
+
def auth_flow(self, request: httpx.Request) -> typing.Generator[httpx.Request, None, None]:
|
|
20
|
+
"""
|
|
21
|
+
Add authentication query parameter to the request.
|
|
22
|
+
|
|
23
|
+
:param request: httpx.Request
|
|
24
|
+
:return: httpx.Request
|
|
25
|
+
"""
|
|
26
|
+
request.url = request.url.copy_merge_params({"access_token": self.access_token})
|
|
27
|
+
yield request
|
deezer/client.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import warnings
|
|
4
3
|
from typing import Any, ClassVar
|
|
5
4
|
|
|
6
|
-
import
|
|
5
|
+
import httpx
|
|
6
|
+
from httpx._types import HeaderTypes
|
|
7
7
|
|
|
8
|
+
from deezer.auth import DeezerQueryAuth
|
|
8
9
|
from deezer.exceptions import (
|
|
9
10
|
DeezerErrorResponse,
|
|
10
11
|
DeezerHTTPError,
|
|
@@ -26,10 +27,8 @@ from deezer.resources import (
|
|
|
26
27
|
User,
|
|
27
28
|
)
|
|
28
29
|
|
|
29
|
-
_UNSET = object()
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
class Client:
|
|
31
|
+
class Client(httpx.Client):
|
|
33
32
|
"""
|
|
34
33
|
A client to retrieve some basic infos about Deezer resources.
|
|
35
34
|
|
|
@@ -50,15 +49,6 @@ class Client:
|
|
|
50
49
|
|
|
51
50
|
:param access_token: user access token.
|
|
52
51
|
:param headers: a dictionary of headers to be used.
|
|
53
|
-
|
|
54
|
-
.. deprecated:: 6.2.0
|
|
55
|
-
|
|
56
|
-
The following parameters will be removed in the next major version:
|
|
57
|
-
|
|
58
|
-
* **app_id**
|
|
59
|
-
* **app_secret**
|
|
60
|
-
|
|
61
|
-
They were never actively used by the package.
|
|
62
52
|
"""
|
|
63
53
|
|
|
64
54
|
objects_types: ClassVar[dict[str, type[Resource] | None]] = {
|
|
@@ -76,37 +66,21 @@ class Client:
|
|
|
76
66
|
"track": Track,
|
|
77
67
|
"user": User,
|
|
78
68
|
}
|
|
79
|
-
base_url = "https://api.deezer.com"
|
|
80
69
|
|
|
81
70
|
def __init__(
|
|
82
71
|
self,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
access_token=None,
|
|
86
|
-
headers=None,
|
|
87
|
-
**kwargs,
|
|
72
|
+
access_token: str | None = None,
|
|
73
|
+
headers: HeaderTypes | None = None,
|
|
88
74
|
):
|
|
89
|
-
if
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
warnings.warn(
|
|
99
|
-
"The 'app_secret' parameter is not actually used and is deprecated. "
|
|
100
|
-
"It will be removed in the next major release.",
|
|
101
|
-
DeprecationWarning,
|
|
102
|
-
stacklevel=2,
|
|
103
|
-
)
|
|
104
|
-
self.app_secret = app_secret
|
|
105
|
-
self.access_token = access_token
|
|
106
|
-
self.session = requests.Session()
|
|
107
|
-
|
|
108
|
-
headers = headers or {}
|
|
109
|
-
self.session.headers.update(headers)
|
|
75
|
+
if access_token:
|
|
76
|
+
deezer_auth = DeezerQueryAuth(access_token=access_token)
|
|
77
|
+
else:
|
|
78
|
+
deezer_auth = None
|
|
79
|
+
super().__init__(
|
|
80
|
+
base_url="https://api.deezer.com",
|
|
81
|
+
auth=deezer_auth,
|
|
82
|
+
headers=headers,
|
|
83
|
+
)
|
|
110
84
|
|
|
111
85
|
def _process_json(
|
|
112
86
|
self,
|
|
@@ -127,9 +101,7 @@ class Client:
|
|
|
127
101
|
:returns: instance of :class:`~deezer.Resource`
|
|
128
102
|
"""
|
|
129
103
|
if "data" in item:
|
|
130
|
-
parsed_data = [
|
|
131
|
-
self._process_json(i, parent, paginate_list=False) for i in item["data"]
|
|
132
|
-
]
|
|
104
|
+
parsed_data = [self._process_json(i, parent, paginate_list=False) for i in item["data"]]
|
|
133
105
|
if not paginate_list:
|
|
134
106
|
return parsed_data
|
|
135
107
|
item["data"] = parsed_data
|
|
@@ -168,7 +140,7 @@ class Client:
|
|
|
168
140
|
resource_type: type[Resource] | None = None,
|
|
169
141
|
resource_id: int | None = None,
|
|
170
142
|
paginate_list=False,
|
|
171
|
-
**
|
|
143
|
+
**kwargs,
|
|
172
144
|
):
|
|
173
145
|
"""
|
|
174
146
|
Make a request to the API and parse the response.
|
|
@@ -179,18 +151,15 @@ class Client:
|
|
|
179
151
|
:param resource_type: The resource class to use as top level.
|
|
180
152
|
:param resource_id: The resource id to use as top level.
|
|
181
153
|
:param paginate_list: Whether to wrap list into a pagination object.
|
|
182
|
-
:param params: Query parameters to add to the request
|
|
183
154
|
"""
|
|
184
|
-
|
|
185
|
-
params["access_token"] = str(self.access_token)
|
|
186
|
-
response = self.session.request(
|
|
155
|
+
response = super().request(
|
|
187
156
|
method,
|
|
188
|
-
|
|
189
|
-
|
|
157
|
+
path,
|
|
158
|
+
**kwargs,
|
|
190
159
|
)
|
|
191
160
|
try:
|
|
192
161
|
response.raise_for_status()
|
|
193
|
-
except
|
|
162
|
+
except httpx.HTTPStatusError as exc:
|
|
194
163
|
raise DeezerHTTPError.from_http_error(exc) from exc
|
|
195
164
|
json_data = response.json()
|
|
196
165
|
if not isinstance(json_data, dict):
|
|
@@ -205,8 +174,8 @@ class Client:
|
|
|
205
174
|
paginate_list=paginate_list,
|
|
206
175
|
)
|
|
207
176
|
|
|
208
|
-
def _get_paginated_list(self, path,
|
|
209
|
-
return PaginatedList(client=self, base_path=path,
|
|
177
|
+
def _get_paginated_list(self, path: str, params: dict | None = None):
|
|
178
|
+
return PaginatedList(client=self, base_path=path, params=params)
|
|
210
179
|
|
|
211
180
|
def get_album(self, album_id: int) -> Album:
|
|
212
181
|
"""
|
|
@@ -233,9 +202,7 @@ class Client:
|
|
|
233
202
|
:param genre_id: the genre ID, default to `All` genre (genre_id = 0).
|
|
234
203
|
:returns: a :class:`~deezer.Chart` instance.
|
|
235
204
|
"""
|
|
236
|
-
return self.request(
|
|
237
|
-
"GET", f"chart/{genre_id}", resource_type=Chart, resource_id=genre_id
|
|
238
|
-
)
|
|
205
|
+
return self.request("GET", f"chart/{genre_id}", resource_type=Chart, resource_id=genre_id)
|
|
239
206
|
|
|
240
207
|
def get_tracks_chart(self, genre_id: int = 0) -> list[Track]:
|
|
241
208
|
"""
|
|
@@ -388,9 +355,7 @@ class Client:
|
|
|
388
355
|
:returns: a :class:`PaginatedList <deezer.PaginatedList>`
|
|
389
356
|
of :class:`Track <deezer.Track>` instances
|
|
390
357
|
"""
|
|
391
|
-
return PaginatedList(
|
|
392
|
-
client=self, base_path="user/me/recommendations/tracks", **kwargs
|
|
393
|
-
)
|
|
358
|
+
return PaginatedList(client=self, base_path="user/me/recommendations/tracks", **kwargs)
|
|
394
359
|
|
|
395
360
|
def get_user_recommended_albums(self, **kwargs) -> PaginatedList[Album]:
|
|
396
361
|
"""
|
|
@@ -399,9 +364,7 @@ class Client:
|
|
|
399
364
|
:returns: a :class:`PaginatedList <deezer.PaginatedList>`
|
|
400
365
|
of :class:`Track <deezer.Album>` instances
|
|
401
366
|
"""
|
|
402
|
-
return PaginatedList(
|
|
403
|
-
client=self, base_path="user/me/recommendations/albums", **kwargs
|
|
404
|
-
)
|
|
367
|
+
return PaginatedList(client=self, base_path="user/me/recommendations/albums", **kwargs)
|
|
405
368
|
|
|
406
369
|
def get_user_recommended_artists(self, **kwargs) -> PaginatedList[Artist]:
|
|
407
370
|
"""
|
|
@@ -410,9 +373,7 @@ class Client:
|
|
|
410
373
|
:returns: a :class:`PaginatedList <deezer.PaginatedList>`
|
|
411
374
|
of :class:`Track <deezer.Artist>` instances
|
|
412
375
|
"""
|
|
413
|
-
return PaginatedList(
|
|
414
|
-
client=self, base_path="user/me/recommendations/artists", **kwargs
|
|
415
|
-
)
|
|
376
|
+
return PaginatedList(client=self, base_path="user/me/recommendations/artists", **kwargs)
|
|
416
377
|
|
|
417
378
|
def get_user_recommended_playlists(self, **kwargs) -> PaginatedList[Playlist]:
|
|
418
379
|
"""
|
|
@@ -421,9 +382,7 @@ class Client:
|
|
|
421
382
|
:returns: a :class:`PaginatedList <deezer.PaginatedList>`
|
|
422
383
|
of :class:`Track <deezer.Playlist>` instances
|
|
423
384
|
"""
|
|
424
|
-
return PaginatedList(
|
|
425
|
-
client=self, base_path="user/me/recommendations/playlists", **kwargs
|
|
426
|
-
)
|
|
385
|
+
return PaginatedList(client=self, base_path="user/me/recommendations/playlists", **kwargs)
|
|
427
386
|
|
|
428
387
|
def get_user_flow(self, **kwargs) -> PaginatedList[Track]:
|
|
429
388
|
"""
|
|
@@ -452,7 +411,7 @@ class Client:
|
|
|
452
411
|
:param album_id: the ID of the album to add.
|
|
453
412
|
:return: boolean whether the operation succeeded.
|
|
454
413
|
"""
|
|
455
|
-
return self.request("POST", "user/me/albums",
|
|
414
|
+
return self.request("POST", "user/me/albums", params={"album_id": album_id})
|
|
456
415
|
|
|
457
416
|
def remove_user_album(self, album_id: int) -> bool:
|
|
458
417
|
"""
|
|
@@ -461,7 +420,7 @@ class Client:
|
|
|
461
420
|
:param album_id: the ID of the album to remove.
|
|
462
421
|
:return: boolean whether the operation succeeded.
|
|
463
422
|
"""
|
|
464
|
-
return self.request("DELETE", "user/me/albums",
|
|
423
|
+
return self.request("DELETE", "user/me/albums", params={"album_id": album_id})
|
|
465
424
|
|
|
466
425
|
def get_user_artists(self, user_id: int | None = None) -> PaginatedList[Artist]:
|
|
467
426
|
"""
|
|
@@ -481,7 +440,7 @@ class Client:
|
|
|
481
440
|
:param artist_id: the ID of the artist to add.
|
|
482
441
|
:return: boolean whether the operation succeeded.
|
|
483
442
|
"""
|
|
484
|
-
return self.request("POST", "user/me/artists",
|
|
443
|
+
return self.request("POST", "user/me/artists", params={"artist_id": artist_id})
|
|
485
444
|
|
|
486
445
|
def remove_user_artist(self, artist_id: int) -> bool:
|
|
487
446
|
"""
|
|
@@ -490,7 +449,11 @@ class Client:
|
|
|
490
449
|
:param artist_id: the ID of the artist to remove.
|
|
491
450
|
:return: boolean whether the operation succeeded.
|
|
492
451
|
"""
|
|
493
|
-
return self.request(
|
|
452
|
+
return self.request(
|
|
453
|
+
"DELETE",
|
|
454
|
+
"user/me/artists",
|
|
455
|
+
params={"artist_id": artist_id},
|
|
456
|
+
)
|
|
494
457
|
|
|
495
458
|
def get_user_followers(self, user_id: int | None = None) -> PaginatedList[User]:
|
|
496
459
|
"""
|
|
@@ -521,7 +484,7 @@ class Client:
|
|
|
521
484
|
:param user_id: the ID of the user to follow.
|
|
522
485
|
:return: boolean whether the operation succeeded.
|
|
523
486
|
"""
|
|
524
|
-
return self.request("POST", "user/me/followings",
|
|
487
|
+
return self.request("POST", "user/me/followings", params={"user_id": user_id})
|
|
525
488
|
|
|
526
489
|
def remove_user_following(self, user_id: int) -> bool:
|
|
527
490
|
"""
|
|
@@ -530,7 +493,7 @@ class Client:
|
|
|
530
493
|
:param user_id: the ID of the user to stop following.
|
|
531
494
|
:return: boolean whether the operation succeeded.
|
|
532
495
|
"""
|
|
533
|
-
return self.request("DELETE", "user/me/followings",
|
|
496
|
+
return self.request("DELETE", "user/me/followings", params={"user_id": user_id})
|
|
534
497
|
|
|
535
498
|
def get_user_history(self) -> PaginatedList[Track]:
|
|
536
499
|
"""
|
|
@@ -559,7 +522,7 @@ class Client:
|
|
|
559
522
|
:param track_id: the ID of the track to add.
|
|
560
523
|
:return: boolean whether the operation succeeded.
|
|
561
524
|
"""
|
|
562
|
-
return self.request("POST", "user/me/tracks",
|
|
525
|
+
return self.request("POST", "user/me/tracks", params={"track_id": track_id})
|
|
563
526
|
|
|
564
527
|
def remove_user_track(self, track_id: int) -> bool:
|
|
565
528
|
"""
|
|
@@ -568,7 +531,7 @@ class Client:
|
|
|
568
531
|
:param track_id: the ID of the track to remove.
|
|
569
532
|
:return: boolean whether the operation succeeded.
|
|
570
533
|
"""
|
|
571
|
-
return self.request("DELETE", "user/me/tracks",
|
|
534
|
+
return self.request("DELETE", "user/me/tracks", params={"track_id": track_id})
|
|
572
535
|
|
|
573
536
|
def remove_user_playlist(self, playlist_id: int) -> bool:
|
|
574
537
|
"""
|
|
@@ -577,7 +540,7 @@ class Client:
|
|
|
577
540
|
:param playlist_id: the ID of the playlist to remove.
|
|
578
541
|
:return: boolean whether the operation succeeded.
|
|
579
542
|
"""
|
|
580
|
-
return self.request("DELETE", "user/me/playlists",
|
|
543
|
+
return self.request("DELETE", "user/me/playlists", params={"playlist_id": playlist_id})
|
|
581
544
|
|
|
582
545
|
def add_user_playlist(self, playlist_id: int) -> bool:
|
|
583
546
|
"""
|
|
@@ -586,7 +549,7 @@ class Client:
|
|
|
586
549
|
:param playlist_id: the ID of the playlist to add.
|
|
587
550
|
:return: boolean whether the operation succeeded.
|
|
588
551
|
"""
|
|
589
|
-
return self.request("POST", "user/me/playlists",
|
|
552
|
+
return self.request("POST", "user/me/playlists", params={"playlist_id": playlist_id})
|
|
590
553
|
|
|
591
554
|
def create_playlist(self, playlist_name) -> int:
|
|
592
555
|
"""
|
|
@@ -595,7 +558,7 @@ class Client:
|
|
|
595
558
|
:param playlist_name: the name of the playlist.
|
|
596
559
|
:return: the ID of the playlist that was created
|
|
597
560
|
"""
|
|
598
|
-
result = self.request("POST", "user/me/playlists", title
|
|
561
|
+
result = self.request("POST", "user/me/playlists", params={"title": playlist_name})
|
|
599
562
|
# Note: the REST API call returns a dict with just the "id" key in it,
|
|
600
563
|
# so we return that instead of the full Playlist object
|
|
601
564
|
return result.id
|
|
@@ -626,15 +589,15 @@ class Client:
|
|
|
626
589
|
if query:
|
|
627
590
|
query_parts.append(query)
|
|
628
591
|
query_parts.extend(
|
|
629
|
-
f'{param_name}:"{param_value}"'
|
|
630
|
-
for param_name, param_value in advanced_params.items()
|
|
631
|
-
if param_value
|
|
592
|
+
f'{param_name}:"{param_value}"' for param_name, param_value in advanced_params.items() if param_value
|
|
632
593
|
)
|
|
633
594
|
|
|
634
595
|
return self._get_paginated_list(
|
|
635
596
|
path=f"search/{path}" if path else "search",
|
|
636
|
-
|
|
637
|
-
|
|
597
|
+
params={
|
|
598
|
+
"q": " ".join(query_parts),
|
|
599
|
+
**optional_params,
|
|
600
|
+
},
|
|
638
601
|
)
|
|
639
602
|
|
|
640
603
|
def search(
|
deezer/exceptions.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import httpx
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class DeezerAPIException(Exception):
|
|
@@ -12,9 +12,9 @@ class DeezerRetryableException(DeezerAPIException):
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class DeezerHTTPError(DeezerAPIException):
|
|
15
|
-
"""
|
|
15
|
+
"""Specialization wrapping HTTPError from the httpx library."""
|
|
16
16
|
|
|
17
|
-
def __init__(self, http_exception:
|
|
17
|
+
def __init__(self, http_exception: httpx.HTTPStatusError, *args: object) -> None:
|
|
18
18
|
if http_exception.response is not None and http_exception.response.text:
|
|
19
19
|
url = http_exception.response.request.url
|
|
20
20
|
status_code = http_exception.response.status_code
|
|
@@ -24,8 +24,8 @@ class DeezerHTTPError(DeezerAPIException):
|
|
|
24
24
|
super().__init__(http_exception, *args)
|
|
25
25
|
|
|
26
26
|
@classmethod
|
|
27
|
-
def from_http_error(cls, exc:
|
|
28
|
-
"""
|
|
27
|
+
def from_http_error(cls, exc: httpx.HTTPStatusError) -> DeezerHTTPError:
|
|
28
|
+
"""Initialize the appropriate internal exception from a HTTPError."""
|
|
29
29
|
if exc.response is not None:
|
|
30
30
|
if exc.response.status_code in {502, 503, 504}:
|
|
31
31
|
return DeezerRetryableHTTPError(exc)
|
|
@@ -37,7 +37,7 @@ class DeezerHTTPError(DeezerAPIException):
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
class DeezerRetryableHTTPError(DeezerRetryableException, DeezerHTTPError):
|
|
40
|
-
"""
|
|
40
|
+
"""An HTTP error due to a potentially temporary issue."""
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
class DeezerForbiddenError(DeezerHTTPError):
|
deezer/pagination.py
CHANGED
|
@@ -20,14 +20,14 @@ class PaginatedList(Generic[ResourceType]):
|
|
|
20
20
|
client: deezer.Client,
|
|
21
21
|
base_path: str,
|
|
22
22
|
parent: deezer.Resource | None = None,
|
|
23
|
-
|
|
23
|
+
params: dict | None = None,
|
|
24
24
|
):
|
|
25
25
|
self.__elements: list[ResourceType] = []
|
|
26
26
|
self.__client = client
|
|
27
27
|
self.__base_path = base_path
|
|
28
|
-
self.__base_params = params
|
|
28
|
+
self.__base_params = params or {}
|
|
29
29
|
self.__next_path: str | None = base_path
|
|
30
|
-
self.__next_params = params
|
|
30
|
+
self.__next_params = params or {}
|
|
31
31
|
self.__parent = parent
|
|
32
32
|
self.__total = None
|
|
33
33
|
self.__iter = iter(self)
|
|
@@ -90,7 +90,7 @@ class PaginatedList(Generic[ResourceType]):
|
|
|
90
90
|
self.__next_path,
|
|
91
91
|
parent=self.__parent,
|
|
92
92
|
paginate_list=True,
|
|
93
|
-
|
|
93
|
+
params=self.__next_params,
|
|
94
94
|
)
|
|
95
95
|
self.__next_path = None
|
|
96
96
|
self.__total = response_payload.get("total")
|
|
@@ -116,7 +116,7 @@ class PaginatedList(Generic[ResourceType]):
|
|
|
116
116
|
self.__base_path,
|
|
117
117
|
parent=self.__parent,
|
|
118
118
|
paginate_list=True,
|
|
119
|
-
|
|
119
|
+
params=params,
|
|
120
120
|
)
|
|
121
121
|
self.__total = response_payload["total"]
|
|
122
122
|
assert self.__total is not None # noqa S101
|
deezer/resources/editorial.py
CHANGED
|
@@ -26,21 +26,21 @@ class Editorial(Resource):
|
|
|
26
26
|
picture_big: str
|
|
27
27
|
picture_xl: str
|
|
28
28
|
|
|
29
|
-
def get_selection(self
|
|
29
|
+
def get_selection(self) -> list[Album]:
|
|
30
30
|
"""
|
|
31
31
|
Get a list of albums selected every week by the Deezer Team.
|
|
32
32
|
|
|
33
33
|
:returns: a list of :class:`Album <deezer.Album>` instances
|
|
34
34
|
"""
|
|
35
|
-
return self.get_relation("selection"
|
|
35
|
+
return self.get_relation("selection")
|
|
36
36
|
|
|
37
|
-
def get_chart(self
|
|
37
|
+
def get_chart(self) -> Chart:
|
|
38
38
|
"""
|
|
39
39
|
Get top charts for tracks, albums, artists and playlists.
|
|
40
40
|
|
|
41
41
|
:returns: a :class:`~deezer.Chart` instance
|
|
42
42
|
"""
|
|
43
|
-
return self.get_relation("charts", resource_type=Chart
|
|
43
|
+
return self.get_relation("charts", resource_type=Chart)
|
|
44
44
|
|
|
45
45
|
def get_releases(self, **kwargs) -> PaginatedList[Album]:
|
|
46
46
|
"""
|
deezer/resources/episode.py
CHANGED
|
@@ -42,7 +42,7 @@ class Episode(Resource):
|
|
|
42
42
|
return f"{self.link}?utm_source=deezer&utm_content=episode-{self.id}&utm_medium=web"
|
|
43
43
|
return super()._infer_missing_field(item)
|
|
44
44
|
|
|
45
|
-
def add_bookmark(self, offset: int
|
|
45
|
+
def add_bookmark(self, offset: int) -> bool:
|
|
46
46
|
"""
|
|
47
47
|
Sets a bookmark on the episode.
|
|
48
48
|
|
|
@@ -52,14 +52,13 @@ class Episode(Resource):
|
|
|
52
52
|
return self.client.request(
|
|
53
53
|
"POST",
|
|
54
54
|
f"episode/{self.id}/bookmark",
|
|
55
|
-
|
|
56
|
-
**kwargs,
|
|
55
|
+
params={"offset": offset},
|
|
57
56
|
)
|
|
58
57
|
|
|
59
|
-
def remove_bookmark(self
|
|
58
|
+
def remove_bookmark(self) -> bool:
|
|
60
59
|
"""
|
|
61
60
|
Removes the bookmark on the episode.
|
|
62
61
|
|
|
63
62
|
:returns: a boolean that tells if the operation was successful
|
|
64
63
|
"""
|
|
65
|
-
return self.client.request("DELETE", f"episode/{self.id}/bookmark"
|
|
64
|
+
return self.client.request("DELETE", f"episode/{self.id}/bookmark")
|
deezer/resources/playlist.py
CHANGED
|
@@ -58,15 +58,15 @@ class Playlist(Resource):
|
|
|
58
58
|
"""
|
|
59
59
|
return self.get_paginated_list("fans", **kwargs)
|
|
60
60
|
|
|
61
|
-
def mark_seen(self
|
|
61
|
+
def mark_seen(self) -> bool:
|
|
62
62
|
"""
|
|
63
63
|
Mark the playlist as seen.
|
|
64
64
|
|
|
65
65
|
:returns: a boolean that tells if the operation was successful
|
|
66
66
|
"""
|
|
67
|
-
return self.client.request("POST", f"playlist/{self.id}/seen"
|
|
67
|
+
return self.client.request("POST", f"playlist/{self.id}/seen")
|
|
68
68
|
|
|
69
|
-
def add_tracks(self, tracks: Iterable[int | Track]
|
|
69
|
+
def add_tracks(self, tracks: Iterable[int | Track]) -> bool:
|
|
70
70
|
"""
|
|
71
71
|
Add tracks to a playlist.
|
|
72
72
|
|
|
@@ -75,11 +75,9 @@ class Playlist(Resource):
|
|
|
75
75
|
:returns: a boolean that tells if the operation was successful
|
|
76
76
|
"""
|
|
77
77
|
track_ids_str = ",".join(str(tid) for tid in gen_ids(tracks))
|
|
78
|
-
return self.client.request(
|
|
79
|
-
"POST", f"playlist/{self.id}/tracks", songs=track_ids_str, **kwargs
|
|
80
|
-
)
|
|
78
|
+
return self.client.request("POST", f"playlist/{self.id}/tracks", params={"songs": track_ids_str})
|
|
81
79
|
|
|
82
|
-
def delete_tracks(self, tracks: Iterable[int | Track]
|
|
80
|
+
def delete_tracks(self, tracks: Iterable[int | Track]) -> bool:
|
|
83
81
|
"""
|
|
84
82
|
Delete tracks from a playlist.
|
|
85
83
|
|
|
@@ -88,11 +86,9 @@ class Playlist(Resource):
|
|
|
88
86
|
:returns: a boolean that tells if the operation was successful
|
|
89
87
|
"""
|
|
90
88
|
track_ids_str = ",".join(map(str, gen_ids(tracks)))
|
|
91
|
-
return self.client.request(
|
|
92
|
-
"DELETE", f"playlist/{self.id}/tracks", songs=track_ids_str, **kwargs
|
|
93
|
-
)
|
|
89
|
+
return self.client.request("DELETE", f"playlist/{self.id}/tracks", params={"songs": track_ids_str})
|
|
94
90
|
|
|
95
|
-
def reorder_tracks(self, order: Iterable[int | Track]
|
|
91
|
+
def reorder_tracks(self, order: Iterable[int | Track]) -> bool:
|
|
96
92
|
"""
|
|
97
93
|
Reorder the tracks of a playlist.
|
|
98
94
|
|
|
@@ -101,6 +97,4 @@ class Playlist(Resource):
|
|
|
101
97
|
:returns: a boolean that tells if the operation was successful
|
|
102
98
|
"""
|
|
103
99
|
order_track_ids_str = ",".join(map(str, gen_ids(order)))
|
|
104
|
-
return self.client.request(
|
|
105
|
-
"POST", f"playlist/{self.id}/tracks", order=order_track_ids_str, **kwargs
|
|
106
|
-
)
|
|
100
|
+
return self.client.request("POST", f"playlist/{self.id}/tracks", params={"order": order_track_ids_str})
|
deezer/resources/resource.py
CHANGED
|
@@ -56,7 +56,12 @@ class Resource:
|
|
|
56
56
|
result[key] = value
|
|
57
57
|
return result
|
|
58
58
|
|
|
59
|
-
def get_relation(
|
|
59
|
+
def get_relation(
|
|
60
|
+
self,
|
|
61
|
+
relation: str,
|
|
62
|
+
resource_type: type[Resource] | None = None, # type: ignore[valid-type]
|
|
63
|
+
params: dict | None = None,
|
|
64
|
+
):
|
|
60
65
|
"""
|
|
61
66
|
Generic method to load the relation from any resource.
|
|
62
67
|
|
|
@@ -69,10 +74,11 @@ class Resource:
|
|
|
69
74
|
"GET",
|
|
70
75
|
f"{self.type}/{self.id}/{relation}",
|
|
71
76
|
parent=self,
|
|
72
|
-
|
|
77
|
+
resource_type=resource_type,
|
|
78
|
+
params=params,
|
|
73
79
|
)
|
|
74
80
|
|
|
75
|
-
def post_relation(self, relation,
|
|
81
|
+
def post_relation(self, relation: str, params: dict):
|
|
76
82
|
"""
|
|
77
83
|
Generic method to make a POST request to a relation from any resource.
|
|
78
84
|
|
|
@@ -82,10 +88,10 @@ class Resource:
|
|
|
82
88
|
return self.client.request(
|
|
83
89
|
"POST",
|
|
84
90
|
f"{self.type}/{self.id}/{relation}",
|
|
85
|
-
|
|
91
|
+
params=params,
|
|
86
92
|
)
|
|
87
93
|
|
|
88
|
-
def delete_relation(self, relation,
|
|
94
|
+
def delete_relation(self, relation: str, params: dict | None = None):
|
|
89
95
|
"""
|
|
90
96
|
Generic method to make a DELETE request to a relation from any resource.
|
|
91
97
|
|
|
@@ -95,20 +101,20 @@ class Resource:
|
|
|
95
101
|
return self.client.request(
|
|
96
102
|
"DELETE",
|
|
97
103
|
f"{self.type}/{self.id}/{relation}",
|
|
98
|
-
|
|
104
|
+
params=params,
|
|
99
105
|
)
|
|
100
106
|
|
|
101
107
|
def get_paginated_list(
|
|
102
108
|
self,
|
|
103
109
|
relation: str,
|
|
104
|
-
|
|
110
|
+
params: dict | None = None,
|
|
105
111
|
) -> PaginatedList:
|
|
106
112
|
"""Build the pagination object based on the relation."""
|
|
107
113
|
return PaginatedList(
|
|
108
114
|
client=self.client,
|
|
109
115
|
base_path=f"{self.type}/{self.id}/{relation}",
|
|
110
116
|
parent=self,
|
|
111
|
-
|
|
117
|
+
params=params,
|
|
112
118
|
)
|
|
113
119
|
|
|
114
120
|
def __getattr__(self, item: str) -> Any:
|
|
@@ -132,9 +138,7 @@ class Resource:
|
|
|
132
138
|
setattr(self, field_name, getattr(full_resource, field_name))
|
|
133
139
|
self._fields += (field_name,)
|
|
134
140
|
return getattr(self, item)
|
|
135
|
-
raise AttributeError(
|
|
136
|
-
f"'{self.__class__.__name__}' object has no attribute '{item}'"
|
|
137
|
-
)
|
|
141
|
+
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{item}'")
|
|
138
142
|
|
|
139
143
|
def _infer_missing_field(self, item: str) -> Any:
|
|
140
144
|
"""
|
deezer/resources/user.py
CHANGED
|
@@ -48,14 +48,14 @@ class User(Resource):
|
|
|
48
48
|
_parse_birthday = staticmethod(parse_date)
|
|
49
49
|
_parse_inscription_date = staticmethod(parse_date)
|
|
50
50
|
|
|
51
|
-
def get_albums(self, **
|
|
51
|
+
def get_albums(self, **params) -> PaginatedList[Album]:
|
|
52
52
|
"""
|
|
53
53
|
Get user's favorite albums.
|
|
54
54
|
|
|
55
55
|
:returns: a :class:`PaginatedList <deezer.PaginatedList>`
|
|
56
56
|
of :class:`Album <deezer.Album>` instances
|
|
57
57
|
"""
|
|
58
|
-
return self.get_paginated_list("albums",
|
|
58
|
+
return self.get_paginated_list("albums", params=params)
|
|
59
59
|
|
|
60
60
|
def add_album(self, album: Album | int):
|
|
61
61
|
"""
|
|
@@ -64,7 +64,7 @@ class User(Resource):
|
|
|
64
64
|
:param album: an :class:`~deezer.Album` instance or its ID
|
|
65
65
|
:returns: a boolean that tells if the operation was successful
|
|
66
66
|
"""
|
|
67
|
-
return self.post_relation("albums", album_id
|
|
67
|
+
return self.post_relation("albums", params={"album_id": get_id(album)})
|
|
68
68
|
|
|
69
69
|
def remove_album(self, album: Album | int):
|
|
70
70
|
"""
|
|
@@ -73,7 +73,7 @@ class User(Resource):
|
|
|
73
73
|
:param album: an :class:`~deezer.Album` instance or its ID
|
|
74
74
|
:returns: a boolean that tells if the operation was successful
|
|
75
75
|
"""
|
|
76
|
-
return self.delete_relation("albums", album_id
|
|
76
|
+
return self.delete_relation("albums", params={"album_id": get_id(album)})
|
|
77
77
|
|
|
78
78
|
def get_tracks(self, **kwargs) -> PaginatedList[Track]:
|
|
79
79
|
"""
|
|
@@ -82,7 +82,7 @@ class User(Resource):
|
|
|
82
82
|
:returns: a :class:`PaginatedList <deezer.PaginatedList>`
|
|
83
83
|
of :class:`Track <deezer.Track>` instances
|
|
84
84
|
"""
|
|
85
|
-
return self.get_paginated_list("tracks"
|
|
85
|
+
return self.get_paginated_list("tracks")
|
|
86
86
|
|
|
87
87
|
def add_track(self, track: Track | int):
|
|
88
88
|
"""
|
|
@@ -91,7 +91,7 @@ class User(Resource):
|
|
|
91
91
|
:param track: a :class:`~deezer.Track` instance or its ID
|
|
92
92
|
:returns: a boolean that tells if the operation was successful
|
|
93
93
|
"""
|
|
94
|
-
return self.post_relation("tracks", track_id
|
|
94
|
+
return self.post_relation("tracks", params={"track_id": get_id(track)})
|
|
95
95
|
|
|
96
96
|
def remove_track(self, track: Track | int):
|
|
97
97
|
"""
|
|
@@ -100,16 +100,16 @@ class User(Resource):
|
|
|
100
100
|
:param track: a :class:`~deezer.Track` instance or its ID
|
|
101
101
|
:returns: a boolean that tells if the operation was successful
|
|
102
102
|
"""
|
|
103
|
-
return self.delete_relation("tracks", track_id
|
|
103
|
+
return self.delete_relation("tracks", params={"track_id": get_id(track)})
|
|
104
104
|
|
|
105
|
-
def get_artists(self, **
|
|
105
|
+
def get_artists(self, **params) -> PaginatedList[Artist]:
|
|
106
106
|
"""
|
|
107
107
|
Get user's favorite artists.
|
|
108
108
|
|
|
109
109
|
:returns: a :class:`PaginatedList <deezer.PaginatedList>`
|
|
110
110
|
of :class:`Artist <deezer.Artist>` instances
|
|
111
111
|
"""
|
|
112
|
-
return self.get_paginated_list("artists",
|
|
112
|
+
return self.get_paginated_list("artists", params=params)
|
|
113
113
|
|
|
114
114
|
def add_artist(self, artist: Artist | int):
|
|
115
115
|
"""
|
|
@@ -118,7 +118,7 @@ class User(Resource):
|
|
|
118
118
|
:param artist: an :class:`~deezer.Artist` instance or its ID
|
|
119
119
|
:returns: a boolean that tells if the operation was successful
|
|
120
120
|
"""
|
|
121
|
-
return self.post_relation("artists", artist_id
|
|
121
|
+
return self.post_relation("artists", params={"artist_id": get_id(artist)})
|
|
122
122
|
|
|
123
123
|
def remove_artist(self, artist: Artist | int):
|
|
124
124
|
"""
|
|
@@ -127,25 +127,25 @@ class User(Resource):
|
|
|
127
127
|
:param artist: an :class:`~deezer.Artist` instance or its ID
|
|
128
128
|
:returns: a boolean that tells if the operation was successful
|
|
129
129
|
"""
|
|
130
|
-
return self.delete_relation("artists", artist_id
|
|
130
|
+
return self.delete_relation("artists", params={"artist_id": get_id(artist)})
|
|
131
131
|
|
|
132
|
-
def get_followers(self, **
|
|
132
|
+
def get_followers(self, **params) -> PaginatedList[User]:
|
|
133
133
|
"""
|
|
134
134
|
Get user's followers.
|
|
135
135
|
|
|
136
136
|
:returns: a :class:`PaginatedList <deezer.PaginatedList>`
|
|
137
137
|
of :class:`User <deezer.User>` instances
|
|
138
138
|
"""
|
|
139
|
-
return self.get_paginated_list("followers",
|
|
139
|
+
return self.get_paginated_list("followers", params=params)
|
|
140
140
|
|
|
141
|
-
def get_followings(self, **
|
|
141
|
+
def get_followings(self, **params) -> PaginatedList[User]:
|
|
142
142
|
"""
|
|
143
143
|
Get user's followings.
|
|
144
144
|
|
|
145
145
|
:returns: a :class:`PaginatedList <deezer.PaginatedList>`
|
|
146
146
|
of :class:`User <deezer.User>` instances
|
|
147
147
|
"""
|
|
148
|
-
return self.get_paginated_list("followings",
|
|
148
|
+
return self.get_paginated_list("followings", params=params)
|
|
149
149
|
|
|
150
150
|
def follow(self, user: User | int):
|
|
151
151
|
"""
|
|
@@ -154,7 +154,7 @@ class User(Resource):
|
|
|
154
154
|
:param user: a :class:`~deezer.User` instance or its ID
|
|
155
155
|
:returns: a boolean that tells if the operation was successful
|
|
156
156
|
"""
|
|
157
|
-
return self.post_relation("followings", user_id
|
|
157
|
+
return self.post_relation("followings", params={"user_id": get_id(user)})
|
|
158
158
|
|
|
159
159
|
def unfollow(self, user: User | int):
|
|
160
160
|
"""
|
|
@@ -163,16 +163,16 @@ class User(Resource):
|
|
|
163
163
|
:param user: a :class:`~deezer.User` instance or its ID
|
|
164
164
|
:returns: a boolean that tells if the operation was successful
|
|
165
165
|
"""
|
|
166
|
-
return self.delete_relation("followings", user_id
|
|
166
|
+
return self.delete_relation("followings", params={"user_id": get_id(user)})
|
|
167
167
|
|
|
168
|
-
def get_playlists(self, **
|
|
168
|
+
def get_playlists(self, **params) -> PaginatedList[Playlist]:
|
|
169
169
|
"""
|
|
170
170
|
Get user's public playlists.
|
|
171
171
|
|
|
172
172
|
:returns: a :class:`PaginatedList <deezer.PaginatedList>`
|
|
173
173
|
of :class:`Playlist <deezer.Playlist>` instances
|
|
174
174
|
"""
|
|
175
|
-
return self.get_paginated_list("playlists",
|
|
175
|
+
return self.get_paginated_list("playlists", params=params)
|
|
176
176
|
|
|
177
177
|
def add_playlist(self, playlist: Playlist | int):
|
|
178
178
|
"""
|
|
@@ -181,7 +181,7 @@ class User(Resource):
|
|
|
181
181
|
:param playlist: a :class:`~deezer.Playlist` instance or its ID
|
|
182
182
|
:returns: a boolean that tells if the operation was successful
|
|
183
183
|
"""
|
|
184
|
-
return self.post_relation("playlists", playlist_id
|
|
184
|
+
return self.post_relation("playlists", params={"playlist_id": get_id(playlist)})
|
|
185
185
|
|
|
186
186
|
def remove_playlist(self, playlist: Playlist | int):
|
|
187
187
|
"""
|
|
@@ -190,7 +190,7 @@ class User(Resource):
|
|
|
190
190
|
:param playlist: a :class:`~deezer.Playlist` instance or its ID
|
|
191
191
|
:returns: a boolean that tells if the operation was successful
|
|
192
192
|
"""
|
|
193
|
-
return self.delete_relation("playlists", playlist_id
|
|
193
|
+
return self.delete_relation("playlists", params={"playlist_id": get_id(playlist)})
|
|
194
194
|
|
|
195
195
|
def create_playlist(self, title: str) -> int:
|
|
196
196
|
"""
|
|
@@ -199,7 +199,7 @@ class User(Resource):
|
|
|
199
199
|
:param title: the title of the playlist
|
|
200
200
|
:returns: the ID of the playlist that was created
|
|
201
201
|
"""
|
|
202
|
-
result = self.post_relation("playlists",
|
|
202
|
+
result = self.post_relation("playlists", params={"title": title})
|
|
203
203
|
# Note: the REST API call returns a dict with just the "id" key in it,
|
|
204
204
|
# so we return that instead of the full Playlist object
|
|
205
205
|
return result.id
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: deezer-python
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.0.0
|
|
4
4
|
Summary: A friendly wrapper library for the Deezer API
|
|
5
5
|
Home-page: https://github.com/browniebroke/deezer-python
|
|
6
6
|
License: MIT
|
|
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
22
|
Classifier: Topic :: Software Development :: Libraries
|
|
23
|
-
Requires-Dist:
|
|
23
|
+
Requires-Dist: httpx (>=0.23.0)
|
|
24
24
|
Project-URL: Bug Tracker, https://github.com/browniebroke/deezer-python/issues
|
|
25
25
|
Project-URL: Changelog, https://deezer-python.readthedocs.io/en/latest/changelog.html
|
|
26
26
|
Project-URL: Documentation, https://deezer-python.readthedocs.io
|
|
@@ -44,10 +44,10 @@ Description-Content-Type: text/markdown
|
|
|
44
44
|
</p>
|
|
45
45
|
<p align="center">
|
|
46
46
|
<a href="https://python-poetry.org/">
|
|
47
|
-
<img src="https://img.shields.io/
|
|
47
|
+
<img src="https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json" alt="Poetry">
|
|
48
48
|
</a>
|
|
49
|
-
<a href="https://github.com/
|
|
50
|
-
<img src="https://img.shields.io/badge/
|
|
49
|
+
<a href="https://github.com/astral-sh/ruff">
|
|
50
|
+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
51
51
|
</a>
|
|
52
52
|
<a href="https://github.com/pre-commit/pre-commit">
|
|
53
53
|
<img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" alt="pre-commit">
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
deezer/__init__.py,sha256=5Rja7dJ3fy4eDgn_SU8WvnPFj26DW8UQ7_3UUACF5fw,556
|
|
2
|
+
deezer/auth.py,sha256=mKnPDiNBJKEq7Qo0CDu2kW_agviGpTdCbj_duFpYWco,691
|
|
3
|
+
deezer/client.py,sha256=rOQjcwvEb3tbySLWUqAhNna3zr97MBDMC5JHZm0-53c,24780
|
|
4
|
+
deezer/dates.py,sha256=raTeUAAOkajl0TTzM2cupzieTY0amzTeZCaaT3gp_iU,648
|
|
5
|
+
deezer/exceptions.py,sha256=fDLZ63QllqaTwX83cJm1czwEz39ysAcKPB4ie_rAhYI,2004
|
|
6
|
+
deezer/pagination.py,sha256=XXk8uh-9XjXDxx8Fw-cmX2zq-yGNQf9yhum2AISAVZE,4081
|
|
7
|
+
deezer/resources/__init__.py,sha256=WLHWGhV5rLyzZe9IjAtVWUsLvNJDWoldgE2JIADC0L4,549
|
|
8
|
+
deezer/resources/album.py,sha256=83PXZNSSkxY7qVVgyvgyHceaV4IMoQxfqcbTR5v-l38,1734
|
|
9
|
+
deezer/resources/artist.py,sha256=A2mZDceh82cQOsMl3cczgm97UCCUHehNeoPYR8IWjds,2150
|
|
10
|
+
deezer/resources/chart.py,sha256=l4l5M7bYcW1-lFKZl874CGWi-gjOVBcskJ-zL5DMcXE,2193
|
|
11
|
+
deezer/resources/editorial.py,sha256=eD2W9BctUSdUMo3VTMHEFkzGIRkvolLLz20ZD_pWclw,1373
|
|
12
|
+
deezer/resources/episode.py,sha256=1dOBQeNQeKofO_HaMFCg-rKYaPxyqgIm2eMTw0RA-vk,1722
|
|
13
|
+
deezer/resources/genre.py,sha256=CDWyNyFT3fXQM7jPkz3UtGr8gNtVn9430h11Jl0ZwAc,1355
|
|
14
|
+
deezer/resources/playlist.py,sha256=9ErXYNhGGNQ3c9COfMRfEvTWJ9QlJsGjxipgKtIIq7s,3215
|
|
15
|
+
deezer/resources/podcast.py,sha256=FwfOe-m4xI1iRwauZpMjKzXKfLDryDz9Y5cVVzP8wVo,915
|
|
16
|
+
deezer/resources/radio.py,sha256=moOdlSJABqCcluInvgbHSwIzSIhDvBQaVyDGdgeVr_0,805
|
|
17
|
+
deezer/resources/resource.py,sha256=F_u1hJBqTlF_gIC00fqGfWXuDoxLgEYz5m_qeLYv_hA,5202
|
|
18
|
+
deezer/resources/track.py,sha256=e3DPTsYWq5yNCjMRQhGTrFQHfQUe3xn0mEVYbpL3O_0,1546
|
|
19
|
+
deezer/resources/user.py,sha256=kCgMUEbKt1QJzzBEpYxPNM3IbojMlm1fYYTSgqa4Sug,6899
|
|
20
|
+
deezer/utils.py,sha256=Z4QA5Ud5KPiGGv5buTdUidixmkEF9UhwCoYZiGXE-cE,583
|
|
21
|
+
deezer_python-7.0.0.dist-info/LICENSE.txt,sha256=lGqKEubFaPBoiJVRoHOxg1LYlte1e5kLoq6zWUSRQzQ,1054
|
|
22
|
+
deezer_python-7.0.0.dist-info/METADATA,sha256=qHc5BbQrj_dvLh6DqOhIIdOzI9iWP-uCSgjJ0JqdnX8,13718
|
|
23
|
+
deezer_python-7.0.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
24
|
+
deezer_python-7.0.0.dist-info/RECORD,,
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
deezer/__init__.py,sha256=ohzXzQw4o6AhcuubYDivDtiJMIxd_Q69OU2opi4W4Os,556
|
|
2
|
-
deezer/client.py,sha256=Xr_NDiVUT5b-YIkzfresHd76GWrUEgE-MeLYhI7TEKI,25651
|
|
3
|
-
deezer/dates.py,sha256=raTeUAAOkajl0TTzM2cupzieTY0amzTeZCaaT3gp_iU,648
|
|
4
|
-
deezer/exceptions.py,sha256=LmJ9vU_mRQ9o9T26ihD36cIMWMC1lg4sBBLiKta3pQA,2003
|
|
5
|
-
deezer/pagination.py,sha256=MrlUiuKczEHb0bdThwzG9y48M30F4AaobhvReJHzWx8,4041
|
|
6
|
-
deezer/resources/__init__.py,sha256=WLHWGhV5rLyzZe9IjAtVWUsLvNJDWoldgE2JIADC0L4,549
|
|
7
|
-
deezer/resources/album.py,sha256=83PXZNSSkxY7qVVgyvgyHceaV4IMoQxfqcbTR5v-l38,1734
|
|
8
|
-
deezer/resources/artist.py,sha256=A2mZDceh82cQOsMl3cczgm97UCCUHehNeoPYR8IWjds,2150
|
|
9
|
-
deezer/resources/chart.py,sha256=l4l5M7bYcW1-lFKZl874CGWi-gjOVBcskJ-zL5DMcXE,2193
|
|
10
|
-
deezer/resources/editorial.py,sha256=BbYsJeMeGU65dSrO-Wy_oS52zqnVZZni281zdpdb5HQ,1413
|
|
11
|
-
deezer/resources/episode.py,sha256=AuJQZweeu7MMJ89eMPs7RSBoQU4oQeX1O5QMBwDi94E,1762
|
|
12
|
-
deezer/resources/genre.py,sha256=CDWyNyFT3fXQM7jPkz3UtGr8gNtVn9430h11Jl0ZwAc,1355
|
|
13
|
-
deezer/resources/playlist.py,sha256=8pAMmqUG4S9QLZOX5OrEoj4qA8pggDQBVxbG-DNxqgk,3325
|
|
14
|
-
deezer/resources/podcast.py,sha256=FwfOe-m4xI1iRwauZpMjKzXKfLDryDz9Y5cVVzP8wVo,915
|
|
15
|
-
deezer/resources/radio.py,sha256=moOdlSJABqCcluInvgbHSwIzSIhDvBQaVyDGdgeVr_0,805
|
|
16
|
-
deezer/resources/resource.py,sha256=X_65glzz62jHtVB2U-WtuXM8B5E9U2HbjpcRzOdVOiY,4978
|
|
17
|
-
deezer/resources/track.py,sha256=e3DPTsYWq5yNCjMRQhGTrFQHfQUe3xn0mEVYbpL3O_0,1546
|
|
18
|
-
deezer/resources/user.py,sha256=6-46PX80xEgtCY2FecwzzgbvYu1aL1WShFXcCOaVGlU,6752
|
|
19
|
-
deezer/utils.py,sha256=Z4QA5Ud5KPiGGv5buTdUidixmkEF9UhwCoYZiGXE-cE,583
|
|
20
|
-
deezer_python-6.2.0.dist-info/LICENSE.txt,sha256=lGqKEubFaPBoiJVRoHOxg1LYlte1e5kLoq6zWUSRQzQ,1054
|
|
21
|
-
deezer_python-6.2.0.dist-info/METADATA,sha256=4POY_crEa5ogOvMKiy6cmuSbFqwi2ON6khahRQWFw8Y,14629
|
|
22
|
-
deezer_python-6.2.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
23
|
-
deezer_python-6.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|