deezer-python-gql 0.8.2__tar.gz → 0.9.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 (87) hide show
  1. {deezer_python_gql-0.8.2/deezer_python_gql.egg-info → deezer_python_gql-0.9.0}/PKG-INFO +3 -3
  2. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/base_client.py +52 -26
  3. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/client.py +48 -13
  4. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0/deezer_python_gql.egg-info}/PKG-INFO +3 -3
  5. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql.egg-info/requires.txt +2 -2
  6. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/pyproject.toml +3 -3
  7. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/LICENSE +0 -0
  8. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/MANIFEST.in +0 -0
  9. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/README.md +0 -0
  10. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/__init__.py +0 -0
  11. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/base_client.py +0 -0
  12. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/__init__.py +0 -0
  13. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/add_album_to_favorite.py +0 -0
  14. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/add_artist_to_favorite.py +0 -0
  15. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/add_audiobook_to_favorite.py +0 -0
  16. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/add_playlist_to_favorite.py +0 -0
  17. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/add_podcast_to_favorite.py +0 -0
  18. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/add_track_to_favorite.py +0 -0
  19. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/add_tracks_to_playlist.py +0 -0
  20. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/base_model.py +0 -0
  21. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/bookmark_podcast_episode.py +0 -0
  22. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/create_playlist.py +0 -0
  23. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/delete_playlist.py +0 -0
  24. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/enums.py +0 -0
  25. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/fragments.py +0 -0
  26. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_album.py +0 -0
  27. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_artist.py +0 -0
  28. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_artist_mix.py +0 -0
  29. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_audiobook.py +0 -0
  30. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_audiobook_chapter.py +0 -0
  31. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_charts.py +0 -0
  32. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_favorite_albums.py +0 -0
  33. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_favorite_artists.py +0 -0
  34. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_favorite_audiobooks.py +0 -0
  35. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_favorite_playlists.py +0 -0
  36. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_favorite_podcasts.py +0 -0
  37. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_favorite_tracks.py +0 -0
  38. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_flow.py +0 -0
  39. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_flow_batch.py +0 -0
  40. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_flow_config_tracks.py +0 -0
  41. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_flow_configs.py +0 -0
  42. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_livestream.py +0 -0
  43. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_made_for_me.py +0 -0
  44. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_me.py +0 -0
  45. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_music_together_affinity.py +0 -0
  46. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_music_together_group.py +0 -0
  47. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_music_together_groups.py +0 -0
  48. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_playlist.py +0 -0
  49. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_podcast.py +0 -0
  50. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_podcast_episode.py +0 -0
  51. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_podcast_episode_bookmarks.py +0 -0
  52. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_podcast_episodes_by_ids.py +0 -0
  53. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_recently_played.py +0 -0
  54. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_recommendations.py +0 -0
  55. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_similar_tracks.py +0 -0
  56. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_smart_tracklist.py +0 -0
  57. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_track.py +0 -0
  58. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_track_mix.py +0 -0
  59. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_user_charts.py +0 -0
  60. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/get_user_playlists.py +0 -0
  61. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/input_types.py +0 -0
  62. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/mark_as_not_played_podcast_episode.py +0 -0
  63. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/mark_as_played_podcast_episode.py +0 -0
  64. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/music_together_create_group.py +0 -0
  65. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/music_together_generate_group_name.py +0 -0
  66. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/music_together_join_group.py +0 -0
  67. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/music_together_leave_group.py +0 -0
  68. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/music_together_refresh_suggested_tracklist.py +0 -0
  69. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/music_together_update_group_settings.py +0 -0
  70. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/remove_album_from_favorite.py +0 -0
  71. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/remove_artist_from_favorite.py +0 -0
  72. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/remove_audiobook_from_favorite.py +0 -0
  73. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/remove_playlist_from_favorite.py +0 -0
  74. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/remove_podcast_from_favorite.py +0 -0
  75. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/remove_track_from_favorite.py +0 -0
  76. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/remove_tracks_from_playlist.py +0 -0
  77. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/search.py +0 -0
  78. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/search_flows.py +0 -0
  79. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/unbookmark_podcast_episode.py +0 -0
  80. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/generated/update_playlist.py +0 -0
  81. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql/py.typed +0 -0
  82. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql.egg-info/SOURCES.txt +0 -0
  83. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql.egg-info/dependency_links.txt +0 -0
  84. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql.egg-info/not-zip-safe +0 -0
  85. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/deezer_python_gql.egg-info/top_level.txt +0 -0
  86. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/setup.cfg +0 -0
  87. {deezer_python_gql-0.8.2 → deezer_python_gql-0.9.0}/tests/test_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deezer-python-gql
3
- Version: 0.8.2
3
+ Version: 0.9.0
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
@@ -15,13 +15,13 @@ Requires-Dist: httpx>=0.27.0
15
15
  Requires-Dist: pydantic>=2.0.0
16
16
  Provides-Extra: test
17
17
  Requires-Dist: codespell==2.4.2; extra == "test"
18
- Requires-Dist: mypy==1.19.1; extra == "test"
18
+ Requires-Dist: mypy==1.20.0; extra == "test"
19
19
  Requires-Dist: pre-commit==4.5.1; extra == "test"
20
20
  Requires-Dist: pre-commit-hooks==6.0.0; extra == "test"
21
21
  Requires-Dist: pytest==9.0.2; extra == "test"
22
22
  Requires-Dist: pytest-asyncio==1.3.0; extra == "test"
23
23
  Requires-Dist: pytest-cov==7.1.0; extra == "test"
24
- Requires-Dist: ruff==0.15.7; extra == "test"
24
+ Requires-Dist: ruff==0.15.8; extra == "test"
25
25
  Provides-Extra: dev
26
26
  Requires-Dist: ariadne-codegen[subscriptions]; extra == "dev"
27
27
  Dynamic: license-file
@@ -8,7 +8,7 @@ import json
8
8
  import logging
9
9
  import time
10
10
  from base64 import urlsafe_b64decode
11
- from typing import Any, ClassVar, cast
11
+ from typing import Any, ClassVar, Self, cast
12
12
 
13
13
  import httpx
14
14
 
@@ -78,9 +78,13 @@ class DeezerBaseClient:
78
78
  Handles the ARL cookie → JWT token exchange and automatic refresh.
79
79
  This class is used as the base client for ariadne-codegen's generated client.
80
80
 
81
+ Manages its own httpx connection pool by default. Pass an external
82
+ ``http_client`` only if you need to share a pool across multiple clients.
83
+
81
84
  :param arl: Deezer ARL cookie value for authentication.
82
85
  :param url: GraphQL endpoint URL (defaults to Pipe API).
83
86
  :param http_client: Optional pre-configured httpx.AsyncClient.
87
+ If provided, the caller is responsible for closing it.
84
88
  """
85
89
 
86
90
  PIPE_URL = "https://pipe.deezer.com/api"
@@ -96,9 +100,35 @@ class DeezerBaseClient:
96
100
  self.url = url
97
101
  self._arl = arl
98
102
  self._http_client = http_client
103
+ self._owns_http_client = http_client is None
99
104
  self._jwt: str | None = None
100
105
  self._jwt_expires_at: float = 0
101
106
 
107
+ def _get_http_client(self) -> httpx.AsyncClient:
108
+ """Return the HTTP client, creating an internal one if needed."""
109
+ if self._http_client is None:
110
+ self._http_client = httpx.AsyncClient()
111
+ self._owns_http_client = True
112
+ return self._http_client
113
+
114
+ async def close(self) -> None:
115
+ """Close the internal HTTP client if we own it.
116
+
117
+ Safe to call multiple times. Does nothing if an external
118
+ ``http_client`` was provided at construction time.
119
+ """
120
+ if self._owns_http_client and self._http_client is not None:
121
+ await self._http_client.aclose()
122
+ self._http_client = None
123
+
124
+ async def __aenter__(self) -> Self:
125
+ """Enter the async context manager."""
126
+ return self
127
+
128
+ async def __aexit__(self, *args: object) -> None:
129
+ """Exit the async context manager, closing internal resources."""
130
+ await self.close()
131
+
102
132
  async def execute(
103
133
  self,
104
134
  query: str,
@@ -134,24 +164,20 @@ class DeezerBaseClient:
134
164
  k: v for k, v in variables.items() if not isinstance(v, UnsetType)
135
165
  }
136
166
 
137
- client = self._http_client or httpx.AsyncClient()
138
- try:
139
- resp = await client.post(
140
- self.url,
141
- json=payload,
142
- headers=headers,
143
- **kwargs,
144
- )
145
- logger.debug(
146
- "GQL response: %s status=%s length=%s",
147
- operation_name or "<unnamed>",
148
- resp.status_code,
149
- len(resp.content),
150
- )
151
- return resp
152
- finally:
153
- if not self._http_client:
154
- await client.aclose()
167
+ client = self._get_http_client()
168
+ resp = await client.post(
169
+ self.url,
170
+ json=payload,
171
+ headers=headers,
172
+ **kwargs,
173
+ )
174
+ logger.debug(
175
+ "GQL response: %s status=%s length=%s",
176
+ operation_name or "<unnamed>",
177
+ resp.status_code,
178
+ len(resp.content),
179
+ )
180
+ return resp
155
181
 
156
182
  def get_data(self, response: httpx.Response) -> dict[str, Any]:
157
183
  """Parse a GraphQL response and return the data dict.
@@ -238,13 +264,13 @@ class DeezerBaseClient:
238
264
  logger.debug("JWT expired or missing, refreshing from ARL")
239
265
  params = {"jo": "p", "rto": "c", "i": "c"}
240
266
 
241
- async with httpx.AsyncClient() as http:
242
- resp = await http.post(
243
- self.AUTH_URL,
244
- params=params,
245
- cookies={"arl": self._arl},
246
- )
247
- resp.raise_for_status()
267
+ client = self._get_http_client()
268
+ resp = await client.post(
269
+ self.AUTH_URL,
270
+ params=params,
271
+ cookies={"arl": self._arl},
272
+ )
273
+ resp.raise_for_status()
248
274
 
249
275
  # Response body is text/plain containing JSON
250
276
  data = json.loads(resp.text)
@@ -554,9 +554,15 @@ class DeezerGQLClient(DeezerBaseClient):
554
554
  data
555
555
  ).remove_audiobook_from_favorite
556
556
 
557
- async def get_album(self, album_id: str, **kwargs: Any) -> Optional[GetAlbumAlbum]:
557
+ async def get_album(
558
+ self,
559
+ album_id: str,
560
+ tracks_first: Union[Optional[int], UnsetType] = UNSET,
561
+ tracks_after: Union[Optional[str], UnsetType] = UNSET,
562
+ **kwargs: Any
563
+ ) -> Optional[GetAlbumAlbum]:
558
564
  query = gql("""
559
- query GetAlbum($albumId: String!) {
565
+ query GetAlbum($albumId: String!, $tracksFirst: Int = 50, $tracksAfter: String) {
560
566
  album(albumId: $albumId) {
561
567
  ...AlbumFields
562
568
  duration
@@ -567,7 +573,7 @@ class DeezerGQLClient(DeezerBaseClient):
567
573
  id
568
574
  displayTitle
569
575
  }
570
- tracks(first: 50) {
576
+ tracks(first: $tracksFirst, after: $tracksAfter) {
571
577
  edges {
572
578
  cursor
573
579
  node {
@@ -651,7 +657,11 @@ class DeezerGQLClient(DeezerBaseClient):
651
657
  }
652
658
  }
653
659
  """)
654
- variables: dict[str, object] = {"albumId": album_id}
660
+ variables: dict[str, object] = {
661
+ "albumId": album_id,
662
+ "tracksFirst": tracks_first,
663
+ "tracksAfter": tracks_after,
664
+ }
655
665
  response = await self.execute(
656
666
  query=query, operation_name="GetAlbum", variables=variables, **kwargs
657
667
  )
@@ -659,10 +669,16 @@ class DeezerGQLClient(DeezerBaseClient):
659
669
  return GetAlbum.model_validate(data).album
660
670
 
661
671
  async def get_artist(
662
- self, artist_id: str, **kwargs: Any
672
+ self,
673
+ artist_id: str,
674
+ top_tracks_first: Union[Optional[int], UnsetType] = UNSET,
675
+ top_tracks_after: Union[Optional[str], UnsetType] = UNSET,
676
+ albums_first: Union[Optional[int], UnsetType] = UNSET,
677
+ albums_after: Union[Optional[str], UnsetType] = UNSET,
678
+ **kwargs: Any
663
679
  ) -> Optional[GetArtistArtist]:
664
680
  query = gql("""
665
- query GetArtist($artistId: String!) {
681
+ query GetArtist($artistId: String!, $topTracksFirst: Int = 50, $topTracksAfter: String, $albumsFirst: Int = 25, $albumsAfter: String) {
666
682
  artist(artistId: $artistId) {
667
683
  ...ArtistFields
668
684
  url {
@@ -671,7 +687,7 @@ class DeezerGQLClient(DeezerBaseClient):
671
687
  webUrl
672
688
  }
673
689
  }
674
- topTracks(first: 50) {
690
+ topTracks(first: $topTracksFirst, after: $topTracksAfter) {
675
691
  edges {
676
692
  cursor
677
693
  node {
@@ -682,7 +698,12 @@ class DeezerGQLClient(DeezerBaseClient):
682
698
  ...PageInfoFields
683
699
  }
684
700
  }
685
- albums(types: [ALBUM, SINGLES, EP], order: RELEASE_DATE, first: 25) {
701
+ albums(
702
+ types: [ALBUM, SINGLES, EP]
703
+ order: RELEASE_DATE
704
+ first: $albumsFirst
705
+ after: $albumsAfter
706
+ ) {
686
707
  edges {
687
708
  cursor
688
709
  node {
@@ -776,7 +797,13 @@ class DeezerGQLClient(DeezerBaseClient):
776
797
  }
777
798
  }
778
799
  """)
779
- variables: dict[str, object] = {"artistId": artist_id}
800
+ variables: dict[str, object] = {
801
+ "artistId": artist_id,
802
+ "topTracksFirst": top_tracks_first,
803
+ "topTracksAfter": top_tracks_after,
804
+ "albumsFirst": albums_first,
805
+ "albumsAfter": albums_after,
806
+ }
780
807
  response = await self.execute(
781
808
  query=query, operation_name="GetArtist", variables=variables, **kwargs
782
809
  )
@@ -2221,16 +2248,20 @@ class DeezerGQLClient(DeezerBaseClient):
2221
2248
  return GetMusicTogetherGroups.model_validate(data).me
2222
2249
 
2223
2250
  async def get_playlist(
2224
- self, playlist_id: str, **kwargs: Any
2251
+ self,
2252
+ playlist_id: str,
2253
+ tracks_first: Union[Optional[int], UnsetType] = UNSET,
2254
+ tracks_after: Union[Optional[str], UnsetType] = UNSET,
2255
+ **kwargs: Any
2225
2256
  ) -> Optional[GetPlaylistPlaylist]:
2226
2257
  query = gql("""
2227
- query GetPlaylist($playlistId: String!) {
2258
+ query GetPlaylist($playlistId: String!, $tracksFirst: Int = 50, $tracksAfter: String) {
2228
2259
  playlist(playlistId: $playlistId) {
2229
2260
  ...PlaylistFields
2230
2261
  isPrivate
2231
2262
  isCollaborative
2232
2263
  estimatedDuration
2233
- tracks(first: 50) {
2264
+ tracks(first: $tracksFirst, after: $tracksAfter) {
2234
2265
  edges {
2235
2266
  cursor
2236
2267
  node {
@@ -2299,7 +2330,11 @@ class DeezerGQLClient(DeezerBaseClient):
2299
2330
  }
2300
2331
  }
2301
2332
  """)
2302
- variables: dict[str, object] = {"playlistId": playlist_id}
2333
+ variables: dict[str, object] = {
2334
+ "playlistId": playlist_id,
2335
+ "tracksFirst": tracks_first,
2336
+ "tracksAfter": tracks_after,
2337
+ }
2303
2338
  response = await self.execute(
2304
2339
  query=query, operation_name="GetPlaylist", variables=variables, **kwargs
2305
2340
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deezer-python-gql
3
- Version: 0.8.2
3
+ Version: 0.9.0
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
@@ -15,13 +15,13 @@ Requires-Dist: httpx>=0.27.0
15
15
  Requires-Dist: pydantic>=2.0.0
16
16
  Provides-Extra: test
17
17
  Requires-Dist: codespell==2.4.2; extra == "test"
18
- Requires-Dist: mypy==1.19.1; extra == "test"
18
+ Requires-Dist: mypy==1.20.0; extra == "test"
19
19
  Requires-Dist: pre-commit==4.5.1; extra == "test"
20
20
  Requires-Dist: pre-commit-hooks==6.0.0; extra == "test"
21
21
  Requires-Dist: pytest==9.0.2; extra == "test"
22
22
  Requires-Dist: pytest-asyncio==1.3.0; extra == "test"
23
23
  Requires-Dist: pytest-cov==7.1.0; extra == "test"
24
- Requires-Dist: ruff==0.15.7; extra == "test"
24
+ Requires-Dist: ruff==0.15.8; extra == "test"
25
25
  Provides-Extra: dev
26
26
  Requires-Dist: ariadne-codegen[subscriptions]; extra == "dev"
27
27
  Dynamic: license-file
@@ -6,10 +6,10 @@ ariadne-codegen[subscriptions]
6
6
 
7
7
  [test]
8
8
  codespell==2.4.2
9
- mypy==1.19.1
9
+ mypy==1.20.0
10
10
  pre-commit==4.5.1
11
11
  pre-commit-hooks==6.0.0
12
12
  pytest==9.0.2
13
13
  pytest-asyncio==1.3.0
14
14
  pytest-cov==7.1.0
15
- ruff==0.15.7
15
+ ruff==0.15.8
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "deezer-python-gql"
3
- version = "0.8.2"
3
+ version = "0.9.0"
4
4
  description = "Async typed Python client for Deezer's Pipe GraphQL API."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -23,13 +23,13 @@ text = "Apache-2.0"
23
23
  [project.optional-dependencies]
24
24
  test = [
25
25
  "codespell==2.4.2",
26
- "mypy==1.19.1",
26
+ "mypy==1.20.0",
27
27
  "pre-commit==4.5.1",
28
28
  "pre-commit-hooks==6.0.0",
29
29
  "pytest==9.0.2",
30
30
  "pytest-asyncio==1.3.0",
31
31
  "pytest-cov==7.1.0",
32
- "ruff==0.15.7",
32
+ "ruff==0.15.8",
33
33
  ]
34
34
  dev = [
35
35
  "ariadne-codegen[subscriptions]",