deezer-python 5.11.1__tar.gz → 6.0.0__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.
Files changed (24) hide show
  1. {deezer_python-5.11.1 → deezer_python-6.0.0}/PKG-INFO +2 -3
  2. {deezer_python-5.11.1 → deezer_python-6.0.0}/pyproject.toml +4 -4
  3. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/__init__.py +1 -1
  4. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/client.py +5 -2
  5. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/resource.py +26 -0
  6. deezer_python-6.0.0/src/deezer/resources/user.py +205 -0
  7. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/utils.py +10 -6
  8. deezer_python-5.11.1/src/deezer/resources/user.py +0 -102
  9. {deezer_python-5.11.1 → deezer_python-6.0.0}/LICENSE.txt +0 -0
  10. {deezer_python-5.11.1 → deezer_python-6.0.0}/README.md +0 -0
  11. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/dates.py +0 -0
  12. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/exceptions.py +0 -0
  13. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/pagination.py +0 -0
  14. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/__init__.py +0 -0
  15. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/album.py +0 -0
  16. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/artist.py +0 -0
  17. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/chart.py +0 -0
  18. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/editorial.py +0 -0
  19. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/episode.py +0 -0
  20. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/genre.py +0 -0
  21. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/playlist.py +0 -0
  22. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/podcast.py +0 -0
  23. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/radio.py +0 -0
  24. {deezer_python-5.11.1 → deezer_python-6.0.0}/src/deezer/resources/track.py +0 -0
@@ -1,20 +1,19 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: deezer-python
3
- Version: 5.11.1
3
+ Version: 6.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
7
7
  Keywords: deezer,sdk,client,requests
8
8
  Author: Bruno Alla
9
9
  Author-email: alla.brunoo@gmail.com
10
- Requires-Python: >=3.7,<4.0
10
+ Requires-Python: >=3.8,<4.0
11
11
  Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Natural Language :: English
15
15
  Classifier: Operating System :: OS Independent
16
16
  Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.7
18
17
  Classifier: Programming Language :: Python :: 3.8
19
18
  Classifier: Programming Language :: Python :: 3.9
20
19
  Classifier: Programming Language :: Python :: 3.10
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "deezer-python"
3
- version = "5.11.1"
3
+ version = "6.0.0"
4
4
  description = "A friendly wrapper library for the Deezer API"
5
5
  authors = ["Bruno Alla <alla.brunoo@gmail.com>"]
6
6
  license = "MIT"
@@ -26,7 +26,7 @@ packages = [
26
26
  "Mastodon" = "https://fosstodon.org/@browniebroke"
27
27
 
28
28
  [tool.poetry.dependencies]
29
- python = "^3.7"
29
+ python = "^3.8"
30
30
  requests = ">=2.18"
31
31
 
32
32
  [tool.poetry.group.docs]
@@ -45,8 +45,8 @@ pytest = "^7.0"
45
45
  pytest-cov = "^4.0"
46
46
  pytest-mock = "^3.6"
47
47
  pytest-vcr = "^1.0"
48
- vcrpy = "^4.1"
49
- deezer-oauth-cli = "^0.4"
48
+ vcrpy = "^5.0.0"
49
+ deezer-oauth-cli = "^1.0.0"
50
50
 
51
51
  [tool.semantic_release]
52
52
  version_toml = "pyproject.toml:tool.poetry.version"
@@ -15,7 +15,7 @@ from deezer.resources import (
15
15
  User,
16
16
  )
17
17
 
18
- __version__ = "5.11.1"
18
+ __version__ = "6.0.0"
19
19
  __all__ = [
20
20
  "Album",
21
21
  "Artist",
@@ -565,9 +565,12 @@ class Client:
565
565
  Create a playlist on the user's account
566
566
 
567
567
  :param playlist_name: the name of the playlist.
568
- :return: ID of the new playlist.
568
+ :return: the ID of the playlist that was created
569
569
  """
570
- return self.request("POST", "user/me/playlists", title=playlist_name).id
570
+ result = self.request("POST", "user/me/playlists", title=playlist_name)
571
+ # Note: the REST API call returns a dict with just the "id" key in it,
572
+ # so we return that instead of the full Playlist object
573
+ return result.id
571
574
 
572
575
  def delete_playlist(self, playlist_id) -> bool:
573
576
  """
@@ -71,6 +71,32 @@ class Resource:
71
71
  **kwargs,
72
72
  )
73
73
 
74
+ def post_relation(self, relation, **kwargs):
75
+ """
76
+ Generic method to make a POST request to a relation from any resource.
77
+
78
+ This is not meant to be used directly by a client, it's more
79
+ a helper method for the child objects.
80
+ """
81
+ return self.client.request(
82
+ "POST",
83
+ f"{self.type}/{self.id}/{relation}",
84
+ **kwargs,
85
+ )
86
+
87
+ def delete_relation(self, relation, **kwargs):
88
+ """
89
+ Generic method to make a DELETE request to a relation from any resource.
90
+
91
+ This is not meant to be used directly by a client, it's more
92
+ a helper method for the child objects.
93
+ """
94
+ return self.client.request(
95
+ "DELETE",
96
+ f"{self.type}/{self.id}/{relation}",
97
+ **kwargs,
98
+ )
99
+
74
100
  def get_paginated_list(
75
101
  self,
76
102
  relation: str,
@@ -0,0 +1,205 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime as dt
4
+ from typing import TYPE_CHECKING
5
+
6
+ from ..dates import parse_date
7
+ from ..utils import get_id
8
+ from .resource import Resource
9
+
10
+ if TYPE_CHECKING:
11
+ from ..pagination import PaginatedList
12
+ from .album import Album
13
+ from .artist import Artist
14
+ from .playlist import Playlist
15
+ from .track import Track
16
+
17
+
18
+ class User(Resource):
19
+ """
20
+ To work with Deezer user objects.
21
+
22
+ Check the :deezer-api:`Deezer documentation <user>`
23
+ for more details about each field.
24
+ """
25
+
26
+ id: int
27
+ name: str
28
+ lastname: str | None
29
+ firstname: str | None
30
+ email: str | None
31
+ status: int | None
32
+ birthday: dt.date | None
33
+ inscription_date: dt.date
34
+ gender: str | None
35
+ link: str
36
+ picture: str
37
+ picture_small: str
38
+ picture_medium: str
39
+ picture_big: str
40
+ picture_xl: str
41
+ country: str
42
+ lang: str | None
43
+ is_kid: bool | None
44
+ explicit_content_level: str | None
45
+ explicit_content_levels_available: list[str] | None
46
+ tracklist: str
47
+
48
+ _parse_birthday = staticmethod(parse_date)
49
+ _parse_inscription_date = staticmethod(parse_date)
50
+
51
+ def get_albums(self, **kwargs) -> PaginatedList[Album]:
52
+ """
53
+ Get user's favorite albums.
54
+
55
+ :returns: a :class:`PaginatedList <deezer.PaginatedList>`
56
+ of :class:`Album <deezer.Album>` instances
57
+ """
58
+ return self.get_paginated_list("albums", **kwargs)
59
+
60
+ def add_album(self, album: Album | int):
61
+ """
62
+ Add an album to user's favorite albums.
63
+
64
+ :param album: an :class:`~deezer.Album` instance or its ID
65
+ :returns: a boolean that tells if the operation was successful
66
+ """
67
+ return self.post_relation("albums", album_id=get_id(album))
68
+
69
+ def remove_album(self, album: Album | int):
70
+ """
71
+ Remove an album from user's favorite albums.
72
+
73
+ :param album: an :class:`~deezer.Album` instance or its ID
74
+ :returns: a boolean that tells if the operation was successful
75
+ """
76
+ return self.delete_relation("albums", album_id=get_id(album))
77
+
78
+ def get_tracks(self, **kwargs) -> PaginatedList[Track]:
79
+ """
80
+ Get user's favorite tracks.
81
+
82
+ :returns: a :class:`PaginatedList <deezer.PaginatedList>`
83
+ of :class:`Track <deezer.Track>` instances
84
+ """
85
+ return self.get_paginated_list("tracks", **kwargs)
86
+
87
+ def add_track(self, track: Track | int):
88
+ """
89
+ Add a track to user's favorite tracks.
90
+
91
+ :param track: a :class:`~deezer.Track` instance or its ID
92
+ :returns: a boolean that tells if the operation was successful
93
+ """
94
+ return self.post_relation("tracks", track_id=get_id(track))
95
+
96
+ def remove_track(self, track: Track | int):
97
+ """
98
+ Remove a track from user's favorite tracks.
99
+
100
+ :param track: a :class:`~deezer.Track` instance or its ID
101
+ :returns: a boolean that tells if the operation was successful
102
+ """
103
+ return self.delete_relation("tracks", track_id=get_id(track))
104
+
105
+ def get_artists(self, **kwargs) -> PaginatedList[Artist]:
106
+ """
107
+ Get user's favorite artists.
108
+
109
+ :returns: a :class:`PaginatedList <deezer.PaginatedList>`
110
+ of :class:`Artist <deezer.Artist>` instances
111
+ """
112
+ return self.get_paginated_list("artists", **kwargs)
113
+
114
+ def add_artist(self, artist: Artist | int):
115
+ """
116
+ Add an artist to user's favorite artists.
117
+
118
+ :param artist: an :class:`~deezer.Artist` instance or its ID
119
+ :returns: a boolean that tells if the operation was successful
120
+ """
121
+ return self.post_relation("artists", artist_id=get_id(artist))
122
+
123
+ def remove_artist(self, artist: Artist | int):
124
+ """
125
+ Remove an artist from user's favorite artists.
126
+
127
+ :param artist: an :class:`~deezer.Artist` instance or its ID
128
+ :returns: a boolean that tells if the operation was successful
129
+ """
130
+ return self.delete_relation("artists", artist_id=get_id(artist))
131
+
132
+ def get_followers(self, **kwargs) -> PaginatedList[User]:
133
+ """
134
+ Get user's followers.
135
+
136
+ :returns: a :class:`PaginatedList <deezer.PaginatedList>`
137
+ of :class:`User <deezer.User>` instances
138
+ """
139
+ return self.get_paginated_list("followers", **kwargs)
140
+
141
+ def get_followings(self, **kwargs) -> PaginatedList[User]:
142
+ """
143
+ Get user's followings.
144
+
145
+ :returns: a :class:`PaginatedList <deezer.PaginatedList>`
146
+ of :class:`User <deezer.User>` instances
147
+ """
148
+ return self.get_paginated_list("followings", **kwargs)
149
+
150
+ def follow(self, user: User | int):
151
+ """
152
+ Follow a user.
153
+
154
+ :param user: a :class:`~deezer.User` instance or its ID
155
+ :returns: a boolean that tells if the operation was successful
156
+ """
157
+ return self.post_relation("followings", user_id=get_id(user))
158
+
159
+ def unfollow(self, user: User | int):
160
+ """
161
+ Unfollow a user.
162
+
163
+ :param user: a :class:`~deezer.User` instance or its ID
164
+ :returns: a boolean that tells if the operation was successful
165
+ """
166
+ return self.delete_relation("followings", user_id=get_id(user))
167
+
168
+ def get_playlists(self, **kwargs) -> PaginatedList[Playlist]:
169
+ """
170
+ Get user's public playlists.
171
+
172
+ :returns: a :class:`PaginatedList <deezer.PaginatedList>`
173
+ of :class:`Playlist <deezer.Playlist>` instances
174
+ """
175
+ return self.get_paginated_list("playlists", **kwargs)
176
+
177
+ def add_playlist(self, playlist: Playlist | int):
178
+ """
179
+ Add a playlist to user's public playlists.
180
+
181
+ :param playlist: a :class:`~deezer.Playlist` instance or its ID
182
+ :returns: a boolean that tells if the operation was successful
183
+ """
184
+ return self.post_relation("playlists", playlist_id=get_id(playlist))
185
+
186
+ def remove_playlist(self, playlist: Playlist | int):
187
+ """
188
+ Remove a playlist from user's public playlists.
189
+
190
+ :param playlist: a :class:`~deezer.Playlist` instance or its ID
191
+ :returns: a boolean that tells if the operation was successful
192
+ """
193
+ return self.delete_relation("playlists", playlist_id=get_id(playlist))
194
+
195
+ def create_playlist(self, title: str) -> int:
196
+ """
197
+ Create a playlist.
198
+
199
+ :param title: the title of the playlist
200
+ :returns: the ID of the playlist that was created
201
+ """
202
+ result = self.post_relation("playlists", title=title)
203
+ # Note: the REST API call returns a dict with just the "id" key in it,
204
+ # so we return that instead of the full Playlist object
205
+ return result.id
@@ -9,9 +9,13 @@ if TYPE_CHECKING:
9
9
  def gen_ids(item_list: Iterable[int | Resource]) -> Generator[int, None, None]:
10
10
  """Get IDs for an iterable of `int` or `Resources`."""
11
11
  for item in item_list:
12
- if isinstance(item, int):
13
- yield item
14
- elif hasattr(item, "id"):
15
- yield item.id
16
- else:
17
- raise NotImplementedError(f"Unknown type for {item}")
12
+ yield get_id(item)
13
+
14
+
15
+ def get_id(item: int | Resource) -> int:
16
+ """Get ID for an `int` or `Resource`."""
17
+ if isinstance(item, int):
18
+ return item
19
+ if hasattr(item, "id"):
20
+ return item.id
21
+ raise NotImplementedError(f"Unknown type for {item}")
@@ -1,102 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import datetime as dt
4
- from typing import TYPE_CHECKING
5
-
6
- from ..dates import parse_date
7
- from .resource import Resource
8
-
9
- if TYPE_CHECKING:
10
- from ..pagination import PaginatedList
11
- from .album import Album
12
- from .artist import Artist
13
- from .playlist import Playlist
14
- from .track import Track
15
-
16
-
17
- class User(Resource):
18
- """
19
- To work with Deezer user objects.
20
-
21
- Check the :deezer-api:`Deezer documentation <user>`
22
- for more details about each field.
23
- """
24
-
25
- id: int
26
- name: str
27
- lastname: str | None
28
- firstname: str | None
29
- email: str | None
30
- status: int | None
31
- birthday: dt.date | None
32
- inscription_date: dt.date
33
- gender: str | None
34
- link: str
35
- picture: str
36
- picture_small: str
37
- picture_medium: str
38
- picture_big: str
39
- picture_xl: str
40
- country: str
41
- lang: str | None
42
- is_kid: bool | None
43
- explicit_content_level: str | None
44
- explicit_content_levels_available: list[str] | None
45
- tracklist: str
46
-
47
- _parse_birthday = staticmethod(parse_date)
48
- _parse_inscription_date = staticmethod(parse_date)
49
-
50
- def get_albums(self, **kwargs) -> PaginatedList[Album]:
51
- """
52
- Get user's favorite albums.
53
-
54
- :returns: a :class:`PaginatedList <deezer.PaginatedList>`
55
- of :class:`Album <deezer.Album>` instances
56
- """
57
- return self.get_paginated_list("albums", **kwargs)
58
-
59
- def get_tracks(self, **kwargs) -> PaginatedList[Track]:
60
- """
61
- Get user's favorite tracks.
62
-
63
- :returns: a :class:`PaginatedList <deezer.PaginatedList>`
64
- of :class:`Track <deezer.Track>` instances
65
- """
66
- return self.get_paginated_list("tracks", **kwargs)
67
-
68
- def get_artists(self, **kwargs) -> PaginatedList[Artist]:
69
- """
70
- Get user's favorite artists.
71
-
72
- :returns: a :class:`PaginatedList <deezer.PaginatedList>`
73
- of :class:`Artist <deezer.Artist>` instances
74
- """
75
- return self.get_paginated_list("artists", **kwargs)
76
-
77
- def get_followers(self, **kwargs) -> PaginatedList[User]:
78
- """
79
- Get user's followers.
80
-
81
- :returns: a :class:`PaginatedList <deezer.PaginatedList>`
82
- of :class:`User <deezer.User>` instances
83
- """
84
- return self.get_paginated_list("followers", **kwargs)
85
-
86
- def get_followings(self, **kwargs) -> PaginatedList[User]:
87
- """
88
- Get user's followings.
89
-
90
- :returns: a :class:`PaginatedList <deezer.PaginatedList>`
91
- of :class:`User <deezer.User>` instances
92
- """
93
- return self.get_paginated_list("followings", **kwargs)
94
-
95
- def get_playlists(self, **kwargs) -> PaginatedList[Playlist]:
96
- """
97
- Get user's public playlists.
98
-
99
- :returns: a :class:`PaginatedList <deezer.PaginatedList>`
100
- of :class:`Playlist <deezer.Playlist>` instances
101
- """
102
- return self.get_paginated_list("playlists", **kwargs)
File without changes