Make a pass for cleanup and PEP8 compliance

This commit is contained in:
Nathan Coleman 2016-05-31 20:02:25 -04:00
parent 1fae780adb
commit 80bcbb1893

View File

@ -3,7 +3,6 @@
from __future__ import print_function from __future__ import print_function
import sys import sys
import base64
import requests import requests
import json import json
import time import time
@ -11,6 +10,7 @@ import time
''' A simple and thin Python library for the Spotify Web API ''' A simple and thin Python library for the Spotify Web API
''' '''
class SpotifyException(Exception): class SpotifyException(Exception):
def __init__(self, http_status, code, msg): def __init__(self, http_status, code, msg):
self.http_status = http_status self.http_status = http_status
@ -21,6 +21,7 @@ class SpotifyException(Exception):
return 'http status: {0}, code:{1} - {2}'.format( return 'http status: {0}, code:{1} - {2}'.format(
self.http_status, self.code, self.msg) self.http_status, self.code, self.msg)
class Spotify(object): class Spotify(object):
''' '''
Example usage:: Example usage::
@ -107,11 +108,12 @@ class Spotify(object):
r.raise_for_status() r.raise_for_status()
except: except:
if r.text and len(r.text) > 0 and r.text != 'null': if r.text and len(r.text) > 0 and r.text != 'null':
raise SpotifyException(r.status_code, raise SpotifyException(
-1, '%s:\n %s' % (r.url, r.json()['error']['message'])) r.status_code, -1,
'%s:\n %s' % (r.url, r.json()['error']['message']))
else: else:
raise SpotifyException(r.status_code, raise SpotifyException(
-1, '%s:\n %s' % (r.url, 'error')) r.status_code, -1, '%s:\n %s' % (r.url, 'error'))
finally: finally:
r.connection.close() r.connection.close()
if r.text and len(r.text) > 0 and r.text != 'null': if r.text and len(r.text) > 0 and r.text != 'null':
@ -157,7 +159,6 @@ class Spotify(object):
else: else:
raise raise
def _post(self, url, args=None, payload=None, **kwargs): def _post(self, url, args=None, payload=None, **kwargs):
if args: if args:
kwargs.update(args) kwargs.update(args)
@ -228,7 +229,6 @@ class Spotify(object):
trid = self._get_id('artist', artist_id) trid = self._get_id('artist', artist_id)
return self._get('artists/' + trid) return self._get('artists/' + trid)
def artists(self, artists): def artists(self, artists):
''' returns a list of artists given the artist IDs, URIs, or URLs ''' returns a list of artists given the artist IDs, URIs, or URLs
@ -239,8 +239,8 @@ class Spotify(object):
tlist = [self._get_id('artist', a) for a in artists] tlist = [self._get_id('artist', a) for a in artists]
return self._get('artists/?ids=' + ','.join(tlist)) return self._get('artists/?ids=' + ','.join(tlist))
def artist_albums(self, artist_id, album_type=None, country=None, def artist_albums(self, artist_id, album_type=None, country=None, limit=20,
limit=20, offset=0): offset=0):
''' Get Spotify catalog information about an artist's albums ''' Get Spotify catalog information about an artist's albums
Parameters: Parameters:
@ -298,7 +298,8 @@ class Spotify(object):
''' '''
trid = self._get_id('album', album_id) trid = self._get_id('album', album_id)
return self._get('albums/' + trid + '/tracks/', limit=limit, offset=offset) return self._get('albums/' + trid + '/tracks/', limit=limit,
offset=offset)
def albums(self, albums): def albums(self, albums):
''' returns a list of albums given the album IDs, URIs, or URLs ''' returns a list of albums given the album IDs, URIs, or URLs
@ -338,21 +339,22 @@ class Spotify(object):
- limit - the number of items to return - limit - the number of items to return
- offset - the index of the first item to return - offset - the index of the first item to return
''' '''
return self._get("users/%s/playlists" % user, limit=limit, offset=offset) return self._get("users/%s/playlists" % user, limit=limit,
offset=offset)
def user_playlist(self, user, playlist_id = None, fields=None): def user_playlist(self, user, playlist_id=None, fields=None):
''' Gets playlist of a user ''' Gets playlist of a user
Parameters: Parameters:
- user - the id of the user - user - the id of the user
- playlist_id - the id of the playlist - playlist_id - the id of the playlist
- fields - which fields to return - fields - which fields to return
''' '''
if playlist_id == None: if playlist_id is None:
return self._get("users/%s/starred" % (user), fields=fields) return self._get("users/%s/starred" % (user), fields=fields)
plid = self._get_id('playlist', playlist_id) plid = self._get_id('playlist', playlist_id)
return self._get("users/%s/playlists/%s" % (user, plid), fields=fields) return self._get("users/%s/playlists/%s" % (user, plid), fields=fields)
def user_playlist_tracks(self, user, playlist_id = None, fields=None, def user_playlist_tracks(self, user, playlist_id=None, fields=None,
limit=100, offset=0): limit=100, offset=0):
''' Get full details of the tracks of a playlist owned by a user. ''' Get full details of the tracks of a playlist owned by a user.
@ -375,8 +377,8 @@ class Spotify(object):
- name - the name of the playlist - name - the name of the playlist
- public - is the created playlist public - public - is the created playlist public
''' '''
data = {'name':name, 'public':public } data = {'name': name, 'public': public}
return self._post("users/%s/playlists" % (user,), payload = data) return self._post("users/%s/playlists" % (user,), payload=data)
def user_playlist_change_details( def user_playlist_change_details(
self, user, playlist_id, name=None, public=None): self, user, playlist_id, name=None, public=None):
@ -407,9 +409,9 @@ class Spotify(object):
- position - the position to add the tracks - position - the position to add the tracks
''' '''
plid = self._get_id('playlist', playlist_id) plid = self._get_id('playlist', playlist_id)
ftracks = [ self._get_uri('track', tid) for tid in tracks] ftracks = [self._get_uri('track', tid) for tid in tracks]
return self._post("users/%s/playlists/%s/tracks" % (user,plid), return self._post("users/%s/playlists/%s/tracks" % (user, plid),
payload = ftracks, position=position) payload=ftracks, position=position)
def user_playlist_replace_tracks(self, user, playlist_id, tracks): def user_playlist_replace_tracks(self, user, playlist_id, tracks):
''' Replace all tracks in a playlist ''' Replace all tracks in a playlist
@ -420,12 +422,13 @@ class Spotify(object):
- tracks - the list of track ids to add to the playlist - tracks - the list of track ids to add to the playlist
''' '''
plid = self._get_id('playlist', playlist_id) plid = self._get_id('playlist', playlist_id)
ftracks = [ self._get_uri('track', tid) for tid in tracks] ftracks = [self._get_uri('track', tid) for tid in tracks]
payload = { "uris": ftracks } payload = {"uris": ftracks}
return self._put("users/%s/playlists/%s/tracks" % (user,plid), return self._put("users/%s/playlists/%s/tracks" % (user, plid),
payload = payload) payload=payload)
def user_playlist_reorder_tracks(self, user, playlist_id, range_start, insert_before, def user_playlist_reorder_tracks(
self, user, playlist_id, range_start, insert_before,
range_length=1, snapshot_id=None): range_length=1, snapshot_id=None):
''' Reorder tracks in a playlist ''' Reorder tracks in a playlist
@ -438,16 +441,16 @@ class Spotify(object):
- snapshot_id - optional playlist's snapshot ID - snapshot_id - optional playlist's snapshot ID
''' '''
plid = self._get_id('playlist', playlist_id) plid = self._get_id('playlist', playlist_id)
payload = { "range_start": range_start, payload = {"range_start": range_start,
"range_length": range_length, "range_length": range_length,
"insert_before": insert_before } "insert_before": insert_before}
if snapshot_id: if snapshot_id:
payload["snapshot_id"] = snapshot_id payload["snapshot_id"] = snapshot_id
return self._put("users/%s/playlists/%s/tracks" % (user,plid), return self._put("users/%s/playlists/%s/tracks" % (user, plid),
payload = payload) payload=payload)
def user_playlist_remove_all_occurrences_of_tracks(self, user, playlist_id, def user_playlist_remove_all_occurrences_of_tracks(
tracks, snapshot_id=None): self, user, playlist_id, tracks, snapshot_id=None):
''' Removes all occurrences of the given tracks from the given playlist ''' Removes all occurrences of the given tracks from the given playlist
Parameters: Parameters:
@ -459,15 +462,15 @@ class Spotify(object):
''' '''
plid = self._get_id('playlist', playlist_id) plid = self._get_id('playlist', playlist_id)
ftracks = [ self._get_uri('track', tid) for tid in tracks] ftracks = [self._get_uri('track', tid) for tid in tracks]
payload = { "tracks": [ {"uri": track} for track in ftracks] } payload = {"tracks": [{"uri": track} for track in ftracks]}
if snapshot_id: if snapshot_id:
payload["snapshot_id"] = snapshot_id payload["snapshot_id"] = snapshot_id
return self._delete("users/%s/playlists/%s/tracks" % (user, plid), return self._delete("users/%s/playlists/%s/tracks" % (user, plid),
payload = payload) payload=payload)
def user_playlist_remove_specific_occurrences_of_tracks(self, user, def user_playlist_remove_specific_occurrences_of_tracks(
playlist_id, tracks, snapshot_id=None): self, user, playlist_id, tracks, snapshot_id=None):
''' Removes all occurrences of the given tracks from the given playlist ''' Removes all occurrences of the given tracks from the given playlist
Parameters: Parameters:
@ -486,11 +489,11 @@ class Spotify(object):
"uri": self._get_uri("track", tr["uri"]), "uri": self._get_uri("track", tr["uri"]),
"positions": tr["positions"], "positions": tr["positions"],
}) })
payload = { "tracks": ftracks } payload = {"tracks": ftracks}
if snapshot_id: if snapshot_id:
payload["snapshot_id"] = snapshot_id payload["snapshot_id"] = snapshot_id
return self._delete("users/%s/playlists/%s/tracks" % (user, plid), return self._delete("users/%s/playlists/%s/tracks" % (user, plid),
payload = payload) payload=payload)
def me(self): def me(self):
''' Get detailed profile information about the current user. ''' Get detailed profile information about the current user.
@ -534,64 +537,73 @@ class Spotify(object):
- after - ghe last artist ID retrieved from the previous request - after - ghe last artist ID retrieved from the previous request
''' '''
return self._get('me/following', type='artist', limit=limit, after=after) return self._get('me/following', type='artist', limit=limit,
after=after)
def current_user_saved_tracks_delete(self, tracks=[]): def current_user_saved_tracks_delete(self, tracks=None):
''' Remove one or more tracks from the current user's ''' Remove one or more tracks from the current user's
"Your Music" library. "Your Music" library.
Parameters: Parameters:
- tracks - a list of track URIs, URLs or IDs - tracks - a list of track URIs, URLs or IDs
''' '''
tlist = []
if tracks is not None:
tlist = [self._get_id('track', t) for t in tracks] tlist = [self._get_id('track', t) for t in tracks]
return self._delete('me/tracks/?ids=' + ','.join(tlist)) return self._delete('me/tracks/?ids=' + ','.join(tlist))
def current_user_saved_tracks_contains(self, tracks=[]): def current_user_saved_tracks_contains(self, tracks=None):
''' Check if one or more tracks is already saved in ''' Check if one or more tracks is already saved in
the current Spotify users Your Music library. the current Spotify users Your Music library.
Parameters: Parameters:
- tracks - a list of track URIs, URLs or IDs - tracks - a list of track URIs, URLs or IDs
''' '''
tlist = []
if tracks is not None:
tlist = [self._get_id('track', t) for t in tracks] tlist = [self._get_id('track', t) for t in tracks]
return self._get('me/tracks/contains?ids=' + ','.join(tlist)) return self._get('me/tracks/contains?ids=' + ','.join(tlist))
def current_user_saved_tracks_add(self, tracks=None):
def current_user_saved_tracks_add(self, tracks=[]):
''' Add one or more tracks to the current user's ''' Add one or more tracks to the current user's
"Your Music" library. "Your Music" library.
Parameters: Parameters:
- tracks - a list of track URIs, URLs or IDs - tracks - a list of track URIs, URLs or IDs
''' '''
tlist = []
if tracks is not None:
tlist = [self._get_id('track', t) for t in tracks] tlist = [self._get_id('track', t) for t in tracks]
return self._put('me/tracks/?ids=' + ','.join(tlist)) return self._put('me/tracks/?ids=' + ','.join(tlist))
def current_user_top_artists(self, limit=20, offset=0, time_range='medium_term'): def current_user_top_artists(self, limit=20, offset=0,
time_range='medium_term'):
''' Get the current user's top artists ''' Get the current user's top artists
Parameters: Parameters:
- limit - the number of entities to return - limit - the number of entities to return
- offset - the index of the first entity to return - offset - the index of the first entity to return
- time_range - Over what time frame are the affinities computed. - time_range - Over what time frame are the affinities computed
Valid-values: short_term, medium_term, long_term Valid-values: short_term, medium_term, long_term
''' '''
return self._get('me/top/artists', time_range=time_range, limit=limit,offset=offset) return self._get('me/top/artists', time_range=time_range, limit=limit,
offset=offset)
def current_user_top_tracks(self, limit=20, offset=0, time_range='medium_term'): def current_user_top_tracks(self, limit=20, offset=0,
time_range='medium_term'):
''' Get the current user's top tracks ''' Get the current user's top tracks
Parameters: Parameters:
- limit - the number of entities to return - limit - the number of entities to return
- offset - the index of the first entity to return - offset - the index of the first entity to return
- time_range - Over what time frame are the affinities computed. - time_range - Over what time frame are the affinities computed
Valid-values: short_term, medium_term, long_term Valid-values: short_term, medium_term, long_term
''' '''
return self._get('me/top/tracks', time_range=time_range, limit=limit,offset=offset) return self._get('me/top/tracks', time_range=time_range, limit=limit,
offset=offset)
def featured_playlists(self, locale=None, country=None, timestamp=None,
def featured_playlists(self, locale=None, country=None, limit=20, offset=0):
timestamp=None, limit=20, offset = 0):
''' Get a list of Spotify featured playlists ''' Get a list of Spotify featured playlists
Parameters: Parameters:
@ -614,9 +626,10 @@ class Spotify(object):
items. items.
''' '''
return self._get('browse/featured-playlists', locale=locale, return self._get('browse/featured-playlists', locale=locale,
country=country, timestamp=timestamp, limit=limit, offset=offset) country=country, timestamp=timestamp, limit=limit,
offset=offset)
def new_releases(self, country=None, limit=20, offset = 0): def new_releases(self, country=None, limit=20, offset=0):
''' Get a list of new album releases featured in Spotify ''' Get a list of new album releases featured in Spotify
Parameters: Parameters:
@ -629,10 +642,10 @@ class Spotify(object):
(the first object). Use with limit to get the next set of (the first object). Use with limit to get the next set of
items. items.
''' '''
return self._get('browse/new-releases', country=country, return self._get('browse/new-releases', country=country, limit=limit,
limit=limit, offset=offset) offset=offset)
def categories(self, country=None, locale=None, limit=20, offset = 0): def categories(self, country=None, locale=None, limit=20, offset=0):
''' Get a list of new album releases featured in Spotify ''' Get a list of new album releases featured in Spotify
Parameters: Parameters:
@ -651,7 +664,8 @@ class Spotify(object):
return self._get('browse/categories', country=country, locale=locale, return self._get('browse/categories', country=country, locale=locale,
limit=limit, offset=offset) limit=limit, offset=offset)
def category_playlists(self, category_id=None, country=None, limit=20, offset = 0): def category_playlists(self, category_id=None, country=None, limit=20,
offset=0):
''' Get a list of new album releases featured in Spotify ''' Get a list of new album releases featured in Spotify
Parameters: Parameters:
@ -666,11 +680,11 @@ class Spotify(object):
(the first object). Use with limit to get the next set of (the first object). Use with limit to get the next set of
items. items.
''' '''
return self._get('browse/categories/' + category_id + '/playlists', country=country, return self._get('browse/categories/' + category_id + '/playlists',
limit=limit, offset=offset) country=country, limit=limit, offset=offset)
def recommendations(self, seed_artists=[], seed_genres=[], seed_tracks=[], def recommendations(self, seed_artists=None, seed_genres=None,
limit = 20, country=None, **kwargs): seed_tracks=None, limit=20, country=None, **kwargs):
''' Get a list of recommended tracks for one to five seeds. ''' Get a list of recommended tracks for one to five seeds.
Parameters: Parameters:
@ -693,17 +707,20 @@ class Spotify(object):
''' '''
params = dict(limit=limit) params = dict(limit=limit)
if seed_artists: if seed_artists:
params['seed_artists'] = [self._get_id('artist', a) for a in seed_artists] params['seed_artists'] = [self._get_id('artist', a)
for a in seed_artists]
if seed_genres: if seed_genres:
params['seed_genres'] = seed_genres params['seed_genres'] = seed_genres
if seed_tracks: if seed_tracks:
params['seed_tracks'] = [self._get_id('track', t) for t in seed_tracks] params['seed_tracks'] = [self._get_id('track', t)
for t in seed_tracks]
if country: if country:
params['market'] = country params['market'] = country
for attribute in ["acousticness", "danceability", "duration_ms", "energy", for attribute in ["acousticness", "danceability", "duration_ms",
"instrumentalness", "key", "liveness", "loudness", "mode", "popularity", "energy", "instrumentalness", "key", "liveness",
"speechiness", "tempo", "time_signature", "valence"]: "loudness", "mode", "popularity", "speechiness",
"tempo", "time_signature", "valence"]:
for prefix in ["min_", "max_", "target_"]: for prefix in ["min_", "max_", "target_"]:
param = prefix + attribute param = prefix + attribute
if param in kwargs: if param in kwargs:
@ -733,15 +750,15 @@ class Spotify(object):
fields = id.split(':') fields = id.split(':')
if len(fields) >= 3: if len(fields) >= 3:
if type != fields[-2]: if type != fields[-2]:
self._warn('expected id of type ' + type + ' but found type ' \ self._warn('expected id of type %s but found type %s %s',
+ fields[2] + " " + id) type, fields[-2], id)
return fields[-1] return fields[-1]
fields = id.split('/') fields = id.split('/')
if len(fields) >= 3: if len(fields) >= 3:
itype = fields[-2] itype = fields[-2]
if type != itype: if type != itype:
self._warn('expected id of type ' + type + ' but found type ' \ self._warn('expected id of type %s but found type %s %s',
+ itype + " " + id) type, itype, id)
return fields[-1] return fields[-1]
return id return id