deezer-python-gql 0.8.2__tar.gz → 0.8.3__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.8.3}/PKG-INFO +3 -3
  2. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/base_client.py +52 -26
  3. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3/deezer_python_gql.egg-info}/PKG-INFO +3 -3
  4. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql.egg-info/requires.txt +2 -2
  5. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/pyproject.toml +3 -3
  6. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/LICENSE +0 -0
  7. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/MANIFEST.in +0 -0
  8. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/README.md +0 -0
  9. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/__init__.py +0 -0
  10. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/base_client.py +0 -0
  11. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/__init__.py +0 -0
  12. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/add_album_to_favorite.py +0 -0
  13. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/add_artist_to_favorite.py +0 -0
  14. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/add_audiobook_to_favorite.py +0 -0
  15. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/add_playlist_to_favorite.py +0 -0
  16. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/add_podcast_to_favorite.py +0 -0
  17. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/add_track_to_favorite.py +0 -0
  18. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/add_tracks_to_playlist.py +0 -0
  19. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/base_model.py +0 -0
  20. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/bookmark_podcast_episode.py +0 -0
  21. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/client.py +0 -0
  22. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/create_playlist.py +0 -0
  23. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/delete_playlist.py +0 -0
  24. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/enums.py +0 -0
  25. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/fragments.py +0 -0
  26. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_album.py +0 -0
  27. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_artist.py +0 -0
  28. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_artist_mix.py +0 -0
  29. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_audiobook.py +0 -0
  30. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_audiobook_chapter.py +0 -0
  31. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_charts.py +0 -0
  32. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_favorite_albums.py +0 -0
  33. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_favorite_artists.py +0 -0
  34. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_favorite_audiobooks.py +0 -0
  35. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_favorite_playlists.py +0 -0
  36. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_favorite_podcasts.py +0 -0
  37. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_favorite_tracks.py +0 -0
  38. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_flow.py +0 -0
  39. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_flow_batch.py +0 -0
  40. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_flow_config_tracks.py +0 -0
  41. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_flow_configs.py +0 -0
  42. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_livestream.py +0 -0
  43. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_made_for_me.py +0 -0
  44. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_me.py +0 -0
  45. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_music_together_affinity.py +0 -0
  46. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_music_together_group.py +0 -0
  47. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_music_together_groups.py +0 -0
  48. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_playlist.py +0 -0
  49. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_podcast.py +0 -0
  50. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_podcast_episode.py +0 -0
  51. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_podcast_episode_bookmarks.py +0 -0
  52. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_podcast_episodes_by_ids.py +0 -0
  53. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_recently_played.py +0 -0
  54. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_recommendations.py +0 -0
  55. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_similar_tracks.py +0 -0
  56. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_smart_tracklist.py +0 -0
  57. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_track.py +0 -0
  58. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_track_mix.py +0 -0
  59. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_user_charts.py +0 -0
  60. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/get_user_playlists.py +0 -0
  61. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/input_types.py +0 -0
  62. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/mark_as_not_played_podcast_episode.py +0 -0
  63. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/mark_as_played_podcast_episode.py +0 -0
  64. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/music_together_create_group.py +0 -0
  65. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/music_together_generate_group_name.py +0 -0
  66. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/music_together_join_group.py +0 -0
  67. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/music_together_leave_group.py +0 -0
  68. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/music_together_refresh_suggested_tracklist.py +0 -0
  69. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/music_together_update_group_settings.py +0 -0
  70. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/remove_album_from_favorite.py +0 -0
  71. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/remove_artist_from_favorite.py +0 -0
  72. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/remove_audiobook_from_favorite.py +0 -0
  73. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/remove_playlist_from_favorite.py +0 -0
  74. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/remove_podcast_from_favorite.py +0 -0
  75. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/remove_track_from_favorite.py +0 -0
  76. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/remove_tracks_from_playlist.py +0 -0
  77. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/search.py +0 -0
  78. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/search_flows.py +0 -0
  79. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/unbookmark_podcast_episode.py +0 -0
  80. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/generated/update_playlist.py +0 -0
  81. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql/py.typed +0 -0
  82. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql.egg-info/SOURCES.txt +0 -0
  83. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql.egg-info/dependency_links.txt +0 -0
  84. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql.egg-info/not-zip-safe +0 -0
  85. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/deezer_python_gql.egg-info/top_level.txt +0 -0
  86. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/setup.cfg +0 -0
  87. {deezer_python_gql-0.8.2 → deezer_python_gql-0.8.3}/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.8.3
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deezer-python-gql
3
- Version: 0.8.2
3
+ Version: 0.8.3
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.8.3"
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]",