Skip to content

Commit

Permalink
Merge branch 'master' into 508chris-branch
Browse files Browse the repository at this point in the history
  • Loading branch information
stephanebruckert authored Jan 14, 2025
2 parents d1c1294 + 2243e13 commit ee47dad
Show file tree
Hide file tree
Showing 17 changed files with 72 additions and 110 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Add your changes below.
### Added

- Added examples for audiobooks, shows and episodes methods to examples directory
- Use newer string formatters (https://pyformat.info)

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class SpotifyClientCredentials that can be used to authenticate requests like so
playlists = sp.user_playlists('spotify')
while playlists:
for i, playlist in enumerate(playlists['items']):
print("%4d %s %s" % (i + 1 + playlists['offset'], playlist['uri'], playlist['name']))
print(f"{i + 1 + playlists['offset']:4d} {playlist['uri']} {playlist['name']}")
if playlists['next']:
playlists = sp.next(playlists)
else:
Expand Down
4 changes: 2 additions & 2 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Sphinx~=7.4.7
sphinx-rtd-theme~=2.0.0
Sphinx~=8.1.3
sphinx-rtd-theme~=3.0.2
redis>=3.5.3
9 changes: 3 additions & 6 deletions examples/artist_albums.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ def get_args():
def get_artist(name):
results = sp.search(q='artist:' + name, type='artist')
items = results['artists']['items']
if len(items) > 0:
return items[0]
else:
return None
return items[0] if items else None


def show_artist_albums(artist):
Expand All @@ -38,7 +35,7 @@ def show_artist_albums(artist):
for album in albums:
name = album['name']
if name not in seen:
logger.info('ALBUM: %s', name)
logger.info(f'ALBUM: {name}')
seen.add(name)


Expand All @@ -48,7 +45,7 @@ def main():
if artist:
show_artist_albums(artist)
else:
logger.error("Can't find artist: %s", artist)
logger.error(f"Can't find artist: {artist}")


if __name__ == '__main__':
Expand Down
17 changes: 7 additions & 10 deletions examples/artist_discography.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ def get_args():
def get_artist(name):
results = sp.search(q='artist:' + name, type='artist')
items = results['artists']['items']
if len(items) > 0:
return items[0]
else:
return None
return items[0] if items else None


def show_album_tracks(album):
Expand All @@ -34,7 +31,7 @@ def show_album_tracks(album):
results = sp.next(results)
tracks.extend(results['items'])
for i, track in enumerate(tracks):
logger.info('%s. %s', i + 1, track['name'])
logger.info(f'{i + 1}. {track["name"]}')


def show_artist_albums(artist):
Expand All @@ -44,21 +41,21 @@ def show_artist_albums(artist):
while results['next']:
results = sp.next(results)
albums.extend(results['items'])
logger.info('Total albums: %s', len(albums))
logger.info(f'Total albums: {len(albums)}')
unique = set() # skip duplicate albums
for album in albums:
name = album['name'].lower()
if name not in unique:
logger.info('ALBUM: %s', name)
logger.info(f'ALBUM: {name}')
unique.add(name)
show_album_tracks(album)


def show_artist(artist):
logger.info('====%s====', artist['name'])
logger.info('Popularity: %s', artist['popularity'])
logger.info(f'===={artist["name"]}====')
logger.info(f'Popularity: {artist["popularity"]}')
if len(artist['genres']) > 0:
logger.info('Genres: %s', ','.join(artist['genres']))
logger.info(f"Genres: {', '.join(artist['genres'])}")


def main():
Expand Down
8 changes: 2 additions & 6 deletions examples/artist_recommendations.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,13 @@ def get_args():
def get_artist(name):
results = sp.search(q='artist:' + name, type='artist')
items = results['artists']['items']
if len(items) > 0:
return items[0]
else:
return None
return items[0] if items else None


def show_recommendations_for_artist(artist):
results = sp.recommendations(seed_artists=[artist['id']])
for track in results['tracks']:
logger.info('Recommendation: %s - %s', track['name'],
track['artists'][0]['name'])
logger.info(f'Recommendation: {track["name"]} - {track["artists"][0]["name"]}')


def main():
Expand Down
4 changes: 3 additions & 1 deletion examples/follow_playlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ def get_args():

def main():
args = get_args()
sp.current_user_follow_playlist(args.playlist)
# Uses Lofi Girl playlist
playlist = args.playlist or '0vvXsWCC9xrXsKd4FyS8kM'
spotipy.Spotify(auth_manager=SpotifyOAuth()).current_user_follow_playlist(playlist)

if __name__ == '__main__':
main()
2 changes: 1 addition & 1 deletion examples/my_playlists.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@

results = sp.current_user_playlists(limit=50)
for i, item in enumerate(results['items']):
print("%d %s" % (i, item['name']))
print(f"{i} {item['name']}")
2 changes: 1 addition & 1 deletion examples/show_my_saved_tracks.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
def show_tracks(results):
for item in results['items']:
track = item['track']
print("%32.32s %s" % (track['artists'][0]['name'], track['name']))
print(f"{track['artists'][0]['name']:>32.32} {track['name']}")


sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
Expand Down
7 changes: 2 additions & 5 deletions examples/track_recommendations.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,5 @@

# Display the recommendations
for i, track in enumerate(recommendations['tracks']):
print(
"{}. {} by {}"
.format(i+1, track['name'], ', '
.join([artist['name'] for artist in track['artists']]))
)
print(f"{i+1}. {track['name']} by "
f"{', '.join([artist['name'] for artist in track['artists']])}")
4 changes: 1 addition & 3 deletions examples/user_playlists_contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
def show_tracks(results):
for i, item in enumerate(results['items']):
track = item['track']
print(
" %d %32.32s %s" %
(i, track['artists'][0]['name'], track['name']))
print(f" {i} {track['artists'][0]['name']:>32.32} {track['name']}")


if __name__ == '__main__':
Expand Down
8 changes: 1 addition & 7 deletions examples/user_public_playlists.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,7 @@

while playlists:
for i, playlist in enumerate(playlists['items']):
print(
"%4d %s %s" %
(i +
1 +
playlists['offset'],
playlist['uri'],
playlist['name']))
print(f"{i + 1 + playlists['offset']:4d} {playlist['uri']} {playlist['name']}")
if playlists['next']:
playlists = sp.next(playlists)
else:
Expand Down
19 changes: 8 additions & 11 deletions spotipy/cache_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,11 @@ def get_cached_token(self):
token_info = json.loads(token_info_string)
except OSError as error:
if error.errno == errno.ENOENT:
logger.debug("cache does not exist at: %s", self.cache_path)
logger.debug(f"cache does not exist at: {self.cache_path}")
else:
logger.warning("Couldn't read cache at: %s", self.cache_path)
except json.JSONDecodeError:
logger.warning("Couldn't decode JSON from cache at: %s", self.cache_path)
except json.JSONDecodeError:
logger.warning("Couldn't decode JSON from cache at: %s", self.cache_path)

return token_info

Expand All @@ -96,8 +94,7 @@ def save_token_to_cache(self, token_info):
with open(self.cache_path, "w") as f:
f.write(json.dumps(token_info, cls=self.encoder_cls))
except OSError:
logger.warning('Couldn\'t write token to cache at: %s',
self.cache_path)
logger.warning(f"Couldn't write token to cache at: {self.cache_path}")


class MemoryCacheHandler(CacheHandler):
Expand Down Expand Up @@ -150,7 +147,7 @@ def save_token_to_cache(self, token_info):
try:
self.request.session['token_info'] = token_info
except Exception as e:
logger.warning("Error saving token to cache: " + str(e))
logger.warning(f"Error saving token to cache: {e}")


class FlaskSessionCacheHandler(CacheHandler):
Expand All @@ -175,7 +172,7 @@ def save_token_to_cache(self, token_info):
try:
self.session["token_info"] = token_info
except Exception as e:
logger.warning("Error saving token to cache: " + str(e))
logger.warning(f"Error saving token to cache: {e}")


class RedisCacheHandler(CacheHandler):
Expand All @@ -201,15 +198,15 @@ def get_cached_token(self):
if token_info:
return json.loads(token_info)
except RedisError as e:
logger.warning('Error getting token from cache: ' + str(e))
logger.warning(f"Error getting token from cache: {e}")

return token_info

def save_token_to_cache(self, token_info):
try:
self.redis.set(self.key, json.dumps(token_info))
except RedisError as e:
logger.warning('Error saving token to cache: ' + str(e))
logger.warning(f"Error saving token to cache: {e}")


class MemcacheCacheHandler(CacheHandler):
Expand All @@ -233,11 +230,11 @@ def get_cached_token(self):
if token_info:
return json.loads(token_info.decode())
except MemcacheError as e:
logger.warning('Error getting token from cache' + str(e))
logger.warning(f"Error getting token to cache: {e}")

def save_token_to_cache(self, token_info):
from pymemcache import MemcacheError
try:
self.memcache.set(self.key, json.dumps(token_info))
except MemcacheError as e:
logger.warning('Error saving token to cache' + str(e))
logger.warning(f"Error saving token to cache: {e}")
20 changes: 8 additions & 12 deletions spotipy/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ def _internal_call(self, method, url, payload, params):
if self.language is not None:
headers["Accept-Language"] = self.language

logger.debug('Sending %s to %s with Params: %s Headers: %s and Body: %r ',
method, url, args.get("params"), headers, args.get('data'))
logger.debug(f"Sending {method} to {url} with Params: "
f"{args.get('params')} Headers: {headers} and Body: {args.get('data')!r}")

try:
response = self._session.request(
Expand All @@ -289,10 +289,8 @@ def _internal_call(self, method, url, payload, params):
msg = response.text or None
reason = None

logger.error(
'HTTP Error for %s to %s with Params: %s returned %s due to %s',
method, url, args.get("params"), response.status_code, msg
)
logger.error(f"HTTP Error for {method} to {url} with Params: "
f"{args.get('params')} returned {response.status_code} due to {msg}")

raise SpotifyException(
response.status_code,
Expand All @@ -317,7 +315,7 @@ def _internal_call(self, method, url, payload, params):
except ValueError:
results = None

logger.debug('RESULTS: %s', results)
logger.debug(f'RESULTS: {results}')
return results

def _get(self, url, args=None, payload=None, **kwargs):
Expand Down Expand Up @@ -2066,11 +2064,9 @@ def _is_uri(self, uri):
def _search_multiple_markets(self, q, limit, offset, type, markets, total):
if total and limit > total:
limit = total
warnings.warn(
"limit was auto-adjusted to equal {} as it must not be higher than total".format(
total),
UserWarning,
)
warnings.warn(f"limit was auto-adjusted to equal {total} "
f"as it must not be higher than total",
UserWarning)

results = defaultdict(dict)
item_types = [item_type + "s" for item_type in type.split(",")]
Expand Down
5 changes: 3 additions & 2 deletions spotipy/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ def __init__(self, http_status, code, msg, reason=None, headers=None):
self.headers = headers

def __str__(self):
return 'http status: {}, code:{} - {}, reason: {}'.format(
self.http_status, self.code, self.msg, self.reason)
return (f"http status: {self.http_status}, "
f"code: {self.code} - {self.msg}, "
f"reason: {self.reason}")


class SpotifyOauthError(SpotifyBaseException):
Expand Down
Loading

0 comments on commit ee47dad

Please sign in to comment.