-
Notifications
You must be signed in to change notification settings - Fork 1.9k
spotify: Handle API failures #5910
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -25,7 +25,7 @@ | |||||
import re | ||||||
import time | ||||||
import webbrowser | ||||||
from typing import TYPE_CHECKING, Any, Literal, Sequence, Union | ||||||
from typing import TYPE_CHECKING, Any, Literal, Sequence, Tuple, Union | ||||||
|
||||||
import confuse | ||||||
import requests | ||||||
|
@@ -293,7 +293,13 @@ def album_for_id(self, album_id: str) -> AlbumInfo | None: | |||||
if not (spotify_id := self._extract_id(album_id)): | ||||||
return None | ||||||
|
||||||
album_data = self._handle_response("get", self.album_url + spotify_id) | ||||||
try: | ||||||
album_data = self._handle_response( | ||||||
"get", self.album_url + spotify_id | ||||||
) | ||||||
except APIError: | ||||||
return None | ||||||
|
||||||
if album_data["name"] == "": | ||||||
self._log.debug("Album removed from Spotify: {}", album_id) | ||||||
return None | ||||||
|
@@ -324,7 +330,10 @@ def album_for_id(self, album_id: str) -> AlbumInfo | None: | |||||
tracks_data = album_data["tracks"] | ||||||
tracks_items = tracks_data["items"] | ||||||
while tracks_data["next"]: | ||||||
tracks_data = self._handle_response("get", tracks_data["next"]) | ||||||
try: | ||||||
tracks_data = self._handle_response("get", tracks_data["next"]) | ||||||
except APIError: | ||||||
return None | ||||||
tracks_items.extend(tracks_data["items"]) | ||||||
|
||||||
tracks = [] | ||||||
|
@@ -397,22 +406,29 @@ def track_for_id(self, track_id: str) -> None | TrackInfo: | |||||
self._log.debug("Invalid Spotify ID: {}", track_id) | ||||||
return None | ||||||
|
||||||
if not ( | ||||||
track_data := self._handle_response( | ||||||
"get", f"{self.track_url}{spotify_id}" | ||||||
) | ||||||
): | ||||||
self._log.debug("Track not found: {}", track_id) | ||||||
try: | ||||||
if not ( | ||||||
track_data := self._handle_response( | ||||||
"get", f"{self.track_url}{spotify_id}" | ||||||
) | ||||||
): | ||||||
self._log.debug("Track not found: {}", track_id) | ||||||
return None | ||||||
except APIError: | ||||||
return None | ||||||
|
||||||
track = self._get_track(track_data) | ||||||
|
||||||
# Get album's tracks to set `track.index` (position on the entire | ||||||
# release) and `track.medium_total` (total number of tracks on | ||||||
# the track's disc). | ||||||
album_data = self._handle_response( | ||||||
"get", self.album_url + track_data["album"]["id"] | ||||||
) | ||||||
try: | ||||||
# Get album's tracks to set `track.index` (position on the entire | ||||||
# release) and `track.medium_total` (total number of tracks on | ||||||
# the track's disc). | ||||||
album_data = self._handle_response( | ||||||
"get", self.album_url + track_data["album"]["id"] | ||||||
) | ||||||
except APIError: | ||||||
return None | ||||||
|
||||||
medium_total = 0 | ||||||
for i, track_data in enumerate(album_data["tracks"]["items"], start=1): | ||||||
if track_data["disc_number"] == track.medium: | ||||||
|
@@ -707,7 +723,10 @@ def _fetch_info(self, items, write, force): | |||||
self._log.debug("No track_id present for: {}", item) | ||||||
continue | ||||||
|
||||||
popularity, isrc, ean, upc = self.track_info(spotify_track_id) | ||||||
maybe_track_info = self.track_info(spotify_track_id) | ||||||
if maybe_track_info is None: | ||||||
continue | ||||||
popularity, isrc, ean, upc = maybe_track_info | ||||||
item["spotify_track_popularity"] = popularity | ||||||
item["isrc"] = isrc | ||||||
item["ean"] = ean | ||||||
|
@@ -726,9 +745,15 @@ def _fetch_info(self, items, write, force): | |||||
if write: | ||||||
item.try_write() | ||||||
|
||||||
def track_info(self, track_id: str): | ||||||
def track_info( | ||||||
self, track_id: str | ||||||
) -> Tuple[Any | None, Any | None, Any | None, Any | None] | None: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nitpick] The return type annotation is verbose and unclear. Consider creating a type alias or using a more descriptive approach, such as
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||
"""Fetch a track's popularity and external IDs using its Spotify ID.""" | ||||||
track_data = self._handle_response("get", self.track_url + track_id) | ||||||
try: | ||||||
track_data = self._handle_response("get", self.track_url + track_id) | ||||||
except APIError: | ||||||
return None | ||||||
|
||||||
external_ids = track_data.get("external_ids", {}) | ||||||
popularity = track_data.get("popularity") | ||||||
self._log.debug( | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach introduces a lot of duplication in the code. I think a cleaner approach would be to never raise APIError in the first place.
See
_handle_response
method - I'd suggest removing all lines that raiseAPIError
and returningNone
instead.