deezer-python-gql 0.22.1__tar.gz → 0.22.2__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 (103) hide show
  1. {deezer_python_gql-0.22.1/deezer_python_gql.egg-info → deezer_python_gql-0.22.2}/PKG-INFO +1 -1
  2. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/base_client.py +4 -3
  3. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/base_client.py +4 -3
  4. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2/deezer_python_gql.egg-info}/PKG-INFO +1 -1
  5. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/pyproject.toml +1 -1
  6. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/tests/test_client.py +25 -4
  7. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/LICENSE +0 -0
  8. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/MANIFEST.in +0 -0
  9. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/README.md +0 -0
  10. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/__init__.py +0 -0
  11. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/__init__.py +0 -0
  12. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/add_album_to_favorite.py +0 -0
  13. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/add_artist_to_favorite.py +0 -0
  14. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/add_audiobook_to_favorite.py +0 -0
  15. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/add_playlist_to_favorite.py +0 -0
  16. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/add_podcast_to_favorite.py +0 -0
  17. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/add_track_to_favorite.py +0 -0
  18. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/add_tracks_to_playlist.py +0 -0
  19. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/ban_artist_from_recommendation.py +0 -0
  20. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/ban_track_from_recommendation.py +0 -0
  21. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/base_model.py +0 -0
  22. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/bookmark_podcast_episode.py +0 -0
  23. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/client.py +0 -0
  24. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/create_playlist.py +0 -0
  25. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/delete_playlist.py +0 -0
  26. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/enums.py +0 -0
  27. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/fragments.py +0 -0
  28. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_album.py +0 -0
  29. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_artist.py +0 -0
  30. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_artist_mix.py +0 -0
  31. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_audiobook.py +0 -0
  32. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_audiobook_chapter.py +0 -0
  33. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_banned_artists.py +0 -0
  34. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_banned_tracks.py +0 -0
  35. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_charts.py +0 -0
  36. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_family.py +0 -0
  37. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_favorite_albums.py +0 -0
  38. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_favorite_artists.py +0 -0
  39. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_favorite_audiobooks.py +0 -0
  40. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_favorite_playlists.py +0 -0
  41. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_favorite_podcasts.py +0 -0
  42. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_favorite_tracks.py +0 -0
  43. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_flow.py +0 -0
  44. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_flow_batch.py +0 -0
  45. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_flow_config_tracks.py +0 -0
  46. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_flow_configs.py +0 -0
  47. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_flow_tuner.py +0 -0
  48. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_infinite_track_mix.py +0 -0
  49. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_latest_podcast_episodes.py +0 -0
  50. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_livestream.py +0 -0
  51. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_made_for_me.py +0 -0
  52. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_me.py +0 -0
  53. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_music_together_affinity.py +0 -0
  54. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_music_together_group.py +0 -0
  55. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_music_together_groups.py +0 -0
  56. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_personal_tracks.py +0 -0
  57. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_playlist.py +0 -0
  58. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_podcast.py +0 -0
  59. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_podcast_episode.py +0 -0
  60. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_podcast_episode_bookmarks.py +0 -0
  61. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_podcast_episodes_by_ids.py +0 -0
  62. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_recently_played.py +0 -0
  63. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_recommendations.py +0 -0
  64. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_similar_artists.py +0 -0
  65. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_similar_tracks.py +0 -0
  66. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_smart_tracklist.py +0 -0
  67. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_track.py +0 -0
  68. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_track_mix.py +0 -0
  69. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_tracks_by_ids.py +0 -0
  70. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_user_charts.py +0 -0
  71. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/get_user_playlists.py +0 -0
  72. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/input_types.py +0 -0
  73. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/mark_as_not_played_podcast_episode.py +0 -0
  74. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/mark_as_played_podcast_episode.py +0 -0
  75. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/move_track_in_playlist.py +0 -0
  76. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/music_together_create_group.py +0 -0
  77. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/music_together_generate_group_name.py +0 -0
  78. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/music_together_join_group.py +0 -0
  79. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/music_together_leave_group.py +0 -0
  80. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/music_together_refresh_suggested_tracklist.py +0 -0
  81. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/music_together_update_group_settings.py +0 -0
  82. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/push_queue_state.py +0 -0
  83. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/remove_album_from_favorite.py +0 -0
  84. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/remove_artist_from_favorite.py +0 -0
  85. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/remove_audiobook_from_favorite.py +0 -0
  86. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/remove_playlist_from_favorite.py +0 -0
  87. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/remove_podcast_from_favorite.py +0 -0
  88. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/remove_track_from_favorite.py +0 -0
  89. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/remove_tracks_from_playlist.py +0 -0
  90. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/search.py +0 -0
  91. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/search_flows.py +0 -0
  92. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/set_flow_discovery_tuner.py +0 -0
  93. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/unban_artist_from_recommendation.py +0 -0
  94. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/unban_track_from_recommendation.py +0 -0
  95. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/unbookmark_podcast_episode.py +0 -0
  96. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/generated/update_playlist.py +0 -0
  97. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql/py.typed +0 -0
  98. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql.egg-info/SOURCES.txt +0 -0
  99. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql.egg-info/dependency_links.txt +0 -0
  100. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql.egg-info/not-zip-safe +0 -0
  101. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql.egg-info/requires.txt +0 -0
  102. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/deezer_python_gql.egg-info/top_level.txt +0 -0
  103. {deezer_python_gql-0.22.1 → deezer_python_gql-0.22.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deezer-python-gql
3
- Version: 0.22.1
3
+ Version: 0.22.2
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
@@ -288,11 +288,11 @@ class DeezerBaseClient:
288
288
  variables = response.variables
289
289
  if data:
290
290
  # Partial success — some items failed (e.g. deleted albums in favorites).
291
- # Log the errors but return the valid data.
291
+ # That is expected, so log at debug level and return the valid data.
292
292
  error_details = [
293
293
  f"{e.get('message', 'Unknown error')} (path={e.get('path')})" for e in errors
294
294
  ]
295
- logger.warning(
295
+ logger.debug(
296
296
  "GraphQL response for %s (variables=%s) contained %d error(s): %s",
297
297
  op,
298
298
  variables,
@@ -377,7 +377,8 @@ class DeezerBaseClient:
377
377
  text = await resp.text()
378
378
 
379
379
  if not is_success:
380
- if 400 <= status < 500:
380
+ # 429 is rate limiting, not a rejected ARL
381
+ if 400 <= status < 500 and status != 429:
381
382
  msg = f"ARL authentication rejected by auth.deezer.com (HTTP {status})"
382
383
  raise GraphQLClientAuthError(msg)
383
384
  raise GraphQLClientHttpError(
@@ -290,11 +290,11 @@ class DeezerBaseClient:
290
290
  variables = response.variables
291
291
  if data:
292
292
  # Partial success — some items failed (e.g. deleted albums in favorites).
293
- # Log the errors but return the valid data.
293
+ # That is expected, so log at debug level and return the valid data.
294
294
  error_details = [
295
295
  f"{e.get('message', 'Unknown error')} (path={e.get('path')})" for e in errors
296
296
  ]
297
- logger.warning(
297
+ logger.debug(
298
298
  "GraphQL response for %s (variables=%s) contained %d error(s): %s",
299
299
  op,
300
300
  variables,
@@ -379,7 +379,8 @@ class DeezerBaseClient:
379
379
  text = await resp.text()
380
380
 
381
381
  if not is_success:
382
- if 400 <= status < 500:
382
+ # 429 is rate limiting, not a rejected ARL
383
+ if 400 <= status < 500 and status != 429:
383
384
  msg = f"ARL authentication rejected by auth.deezer.com (HTTP {status})"
384
385
  raise GraphQLClientAuthError(msg)
385
386
  raise GraphQLClientHttpError(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deezer-python-gql
3
- Version: 0.22.1
3
+ Version: 0.22.2
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "deezer-python-gql"
3
- version = "0.22.1"
3
+ version = "0.22.2"
4
4
  description = "Async typed Python client for Deezer's Pipe GraphQL API."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -12,6 +12,7 @@ from __future__ import annotations
12
12
  import asyncio
13
13
  import base64
14
14
  import json
15
+ import logging
15
16
  import time
16
17
  from http.cookies import SimpleCookie
17
18
  from pathlib import Path
@@ -648,10 +649,11 @@ async def test_auth_rejected_arl_raises_auth_error() -> None:
648
649
 
649
650
 
650
651
  @pytest.mark.asyncio
651
- async def test_auth_server_error_raises_http_error() -> None:
652
- """Verify a 5xx from auth.deezer.com raises GraphQLClientHttpError, not AuthError."""
652
+ @pytest.mark.parametrize("status", [429, 503])
653
+ async def test_auth_server_error_raises_http_error(status: int) -> None:
654
+ """Verify a 5xx or 429 from auth.deezer.com raises GraphQLClientHttpError, not AuthError."""
653
655
  client = DeezerBaseClient(arl="test_arl")
654
- auth_cm = _mock_post_context_manager(b"Service Unavailable", status=503)
656
+ auth_cm = _mock_post_context_manager(b"Service Unavailable", status=status)
655
657
 
656
658
  with patch("deezer_python_gql.base_client.ClientSession") as mock_cls:
657
659
  mock_instance = MagicMock()
@@ -661,7 +663,7 @@ async def test_auth_server_error_raises_http_error() -> None:
661
663
 
662
664
  with pytest.raises(GraphQLClientHttpError) as exc_info:
663
665
  await client._ensure_jwt() # noqa: SLF001
664
- assert exc_info.value.status_code == 503
666
+ assert exc_info.value.status_code == status
665
667
 
666
668
 
667
669
  @pytest.mark.asyncio
@@ -784,6 +786,25 @@ def test_get_data_raises_on_missing_data_key() -> None:
784
786
  client.get_data(response)
785
787
 
786
788
 
789
+ def test_get_data_logs_partial_errors_at_debug(caplog: pytest.LogCaptureFixture) -> None:
790
+ """Verify items Deezer no longer has are logged at debug level, not as a warning."""
791
+ client = DeezerBaseClient(arl="test")
792
+ response = GQLResponse(
793
+ status=200,
794
+ data=json.dumps(
795
+ {
796
+ "data": {"me": {"id": "1"}},
797
+ "errors": [{"message": "PodcastEpisode does not exist", "path": ["me"]}],
798
+ }
799
+ ).encode(),
800
+ is_success=True,
801
+ )
802
+
803
+ with caplog.at_level(logging.DEBUG, logger="deezer_python_gql"):
804
+ assert client.get_data(response) == {"me": {"id": "1"}}
805
+ assert [record.levelno for record in caplog.records] == [logging.DEBUG]
806
+
807
+
787
808
  def test_get_data_raises_on_graphql_errors() -> None:
788
809
  """Verify get_data raises GraphQLClientGraphQLMultiError for GraphQL-level errors."""
789
810
  client = DeezerBaseClient(arl="test")