spotipy/spotipy/__init__.py

242 lines
7.5 KiB
Python
Raw Normal View History

2014-05-16 02:51:42 +00:00
# coding: utf-8
2014-04-07 17:10:25 +00:00
from __future__ import print_function
2014-05-18 11:08:51 +00:00
2014-05-16 02:51:42 +00:00
import base64
2014-04-05 13:12:01 +00:00
import requests
2014-06-16 17:30:57 +00:00
import simplejson as json
2014-04-05 13:12:01 +00:00
2014-05-18 11:08:51 +00:00
__all__ = ['oauth2']
2014-04-05 18:52:57 +00:00
''' A simple and thin Python library for the Spotify Web API
2014-04-05 13:12:01 +00:00
'''
class SpotifyException(Exception):
def __init__(self, http_status, code, msg):
self.http_status = http_status
self.code = code
self.msg = msg
2014-04-05 18:52:57 +00:00
2014-04-05 13:12:01 +00:00
def __str__(self):
2014-04-05 18:52:57 +00:00
return u'http status: {0}, code:{1} - {2}'.format(
self.http_status, self.code, self.msg)
2014-04-05 13:12:01 +00:00
class Spotify(object):
2014-05-16 11:56:59 +00:00
'''
Example usage:
import spotipy
urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu'
sp = spotipy.Spotify()
sp.trace = True # turn on tracing
artist = sp.artist(urn)
print(artist)
user = sp.user('plamere')
print(user)
'''
trace = False
_auth = None
2014-05-16 02:51:42 +00:00
def __init__(self, auth=None):
2014-04-05 13:12:01 +00:00
self.prefix = 'https://api.spotify.com/v1/'
2014-05-16 11:56:59 +00:00
self._auth = auth
2014-05-16 02:51:42 +00:00
2014-05-16 11:56:59 +00:00
def _auth_headers(self):
if self._auth:
return {'Authorization': 'Bearer {0}'.format(self._auth)}
2014-05-16 02:51:42 +00:00
else:
return None
2014-04-05 13:12:01 +00:00
def _internal_call(self, verb, method, params):
2014-05-19 10:49:08 +00:00
if not method.startswith('http'):
url = self.prefix + method
else:
url = method
2014-04-05 13:12:01 +00:00
args = dict(params=params)
2014-05-16 11:56:59 +00:00
headers = self._auth_headers()
2014-05-16 02:51:42 +00:00
r = requests.request(verb, url, headers=headers, **args)
2014-05-16 11:56:59 +00:00
if self.trace:
print()
print(verb, r.url)
2014-04-05 13:12:01 +00:00
if r.status_code != 200:
2014-04-07 17:10:25 +00:00
raise SpotifyException(r.status_code, -1, u'the requested resource could not be found: ' + r.url)
2014-05-16 11:56:59 +00:00
results = r.json()
if self.trace:
print('RESP', results)
print()
return results
2014-04-05 13:12:01 +00:00
2014-04-05 18:52:57 +00:00
def get(self, method, args=None, **kwargs):
2014-04-05 13:12:01 +00:00
if args:
kwargs.update(args)
return self._internal_call('GET', method, kwargs)
2014-06-16 17:30:57 +00:00
def post(self, method, payload=None, **kwargs):
args = dict(params=kwargs)
if not method.startswith('http'):
url = self.prefix + method
else:
url = method
headers = self._auth_headers()
headers['Content-Type'] = 'application/json'
print('headers', headers)
if payload:
r = requests.post(url, headers=headers, data=json.dumps(payload), **args)
else:
r = requests.post(url, headers=headers, **args)
if self.trace:
print()
print("POST", r.url)
print("DATA", json.dumps(payload))
if r.status_code != 200:
raise SpotifyException(r.status_code, -1, u'the requested resource could not be found: ' + r.url)
results = r.json()
if self.trace:
print('RESP', results)
print()
return results
2014-05-19 10:49:08 +00:00
def next(self, result):
''' returns the next result given a result
'''
if result['next']:
return self.get(result['next'])
else:
return None
def previous(self, result):
''' returns the previous result given a result
'''
if result['previous']:
return self.get(result['previous'])
else:
return None
2014-04-05 13:12:01 +00:00
def _warn(self, msg):
2014-04-07 17:10:25 +00:00
print('warning:' + msg, file=sys.stderr)
2014-04-05 13:12:01 +00:00
def track(self, track_id):
''' returns a single track given the track's ID, URN or URL
'''
trid = self._get_id('track', track_id)
return self.get('tracks/' + trid)
def tracks(self, tracks):
''' returns a list of tracks given the track IDs, URNs, or URLs
'''
tlist = [self._get_id('track', t) for t in tracks]
return self.get('tracks/?ids=' + ','.join(tlist))
def artist(self, artist_id):
''' returns a single artist given the artist's ID, URN or URL
'''
trid = self._get_id('artist', artist_id)
return self.get('artists/' + trid)
2014-05-16 11:56:59 +00:00
def artists(self, artists):
''' returns a list of artists given the artist IDs, URNs, or URLs
'''
tlist = [self._get_id('artist', a) for a in artists]
return self.get('artists/?ids=' + ','.join(tlist))
def artist_albums(self, artist_id, album_type=None, country=None, limit=20, offset=0):
2014-04-07 17:10:25 +00:00
''' Get Spotify catalog information about an artists albums
'''
2014-05-16 11:56:59 +00:00
2014-04-07 17:10:25 +00:00
trid = self._get_id('artist', artist_id)
return self.get('artists/' + trid + '/albums', album_type=album_type, country=country, limit=limit, offset=offset)
2014-04-07 17:10:25 +00:00
2014-05-16 11:56:59 +00:00
def artist_top_tracks(self, artist_id, country='US'):
''' Get Spotify catalog information about an artists top 10 tracks by country.
2014-04-05 13:12:01 +00:00
'''
2014-05-16 11:56:59 +00:00
trid = self._get_id('artist', artist_id)
return self.get('artists/' + trid + '/top-tracks', country=country)
2014-04-05 13:12:01 +00:00
def album(self, album_id):
''' returns a single album given the album's ID, URN or URL
'''
trid = self._get_id('album', album_id)
return self.get('albums/' + trid)
2014-05-16 11:56:59 +00:00
def album_tracks(self, album_id):
''' Get Spotify catalog information about an albums tracks
'''
trid = self._get_id('album', album_id)
return self.get('albums/' + trid + '/tracks/')
2014-04-05 13:12:01 +00:00
def albums(self, albums):
''' returns a list of albums given the album IDs, URNs, or URLs
'''
tlist = [self._get_id('album', a) for a in albums]
return self.get('albums/?ids=' + ','.join(tlist))
def search(self, q, limit=10, offset=0, type='track'):
''' searches for an item
'''
return self.get('search', q=q, limit=limit, offset=offset, type=type)
def user(self, user_id):
''' Gets basic profile information about a Spotify User
'''
return self.get('users/' + user_id)
2014-05-16 02:51:42 +00:00
def user_playlists(self, user):
''' Gets playlists of a user
'''
return self.get("users/%s/playlists" % user)
2014-05-23 11:19:16 +00:00
def user_playlist(self, user, playlist_id, fields=None):
2014-05-16 02:51:42 +00:00
''' Gets playlist of a user
'''
2014-05-23 11:19:16 +00:00
return self.get("users/%s/playlists/%s" % (user, playlist_id), fields=fields)
2014-06-16 17:30:57 +00:00
def user_playlist_create(self, user, name, public=True):
''' Creates a playlist for a user
'''
data = {'name':name, 'public':True }
return self.post("users/%s/playlists" % (user,), payload = data)
def user_playlist_add_tracks(self, user, playlist_id, uris, position=None):
''' Adds tracks to a playlist
'''
data = {'uris':uris}
uri_param = ','.join(uris)
#return self.post("users/%s/playlists/%s/tracks" % (user,playlist_id), payload = data)
#return self.post("users/%s/playlists/%s/tracks" % (user,playlist_id), payload = data, position=position)
#return self.post("users/%s/playlists/%s/tracks" % (user,playlist_id), uris=uri_param, position=position)
return self.post("users/%s/playlists/%s/tracks" % (user,playlist_id), uris=uri_param)
2014-05-16 02:51:42 +00:00
def me(self):
''' returns info about me
'''
return self.get('me/')
2014-04-05 13:12:01 +00:00
def _get_id(self, type, id):
fields = id.split(':')
if len(fields) == 3:
if type != fields[1]:
self._warn('expected id of type ' + type + ' but found type ' + fields[2] + " " + id)
return fields[2]
fields = id.split('/')
if len(fields) >= 3:
itype = fields[-2]
if type != itype:
self._warn('expected id of type ' + type + ' but found type ' + itype + " " + id)
return fields[-1]
return id