diff --git a/examples/user_playlists.py b/examples/user_playlists.py new file mode 100644 index 0000000..bfdad1a --- /dev/null +++ b/examples/user_playlists.py @@ -0,0 +1,34 @@ +# shows a user's playlists (need to be authenticated via oauth) + +import pprint +import sys + +import spotipy +import oauth2 + +if len(sys.argv) > 1: + username = sys.argv[1] +else: + print "Whoops, need your username!" + print "usage: python user_playlists.py [username]" + sys.exit() + +# Create these via developer.spotify.com/my-applications + +client_id = '' +client_secret = '' +redirect_uri = '' + +# Oauth flow +sp_oauth = oauth2.SpotifyOAuth(client_id, client_secret, redirect_uri) +auth_url = sp_oauth.get_authorize_url() +print "Please navigate here: %s" % auth_url +response = raw_input("The URL you were redirected to: ") +code = sp_oauth.parse_response_code(response) +access_token = sp_oauth.get_access_token(code) + +# Auth'ed API request + +sp = spotipy.Spotify(auth=access_token) +playlists = sp.user_playlists(username) +pprint.pprint(playlists) \ No newline at end of file diff --git a/oauth2.py b/oauth2.py new file mode 100644 index 0000000..5d15ed8 --- /dev/null +++ b/oauth2.py @@ -0,0 +1,56 @@ +import base64 +import urllib +import requests + + +class SpotifyOauthError(Exception): + pass + +class SpotifyOAuth(object): + ''' + Implements Authorization Code Flow for Spotify's OAuth implementation. + Docs: https://developer.spotify.com/spotify-web-api/authorization-guide/#authorization_code_flow + ''' + + OAUTH_AUTHORIZE_URL = 'https://accounts.spotify.com/authorize' + OAUTH_TOKEN_URL = 'https://accounts.spotify.com/api/token' + def __init__(self, client_id, client_secret, redirect_uri, state=None, scope=None): + self.client_id = client_id + self.client_secret = client_secret + self.redirect_uri = redirect_uri + self.state=state + self.scope=scope + + def get_authorize_url(self): + payload = {'client_id': self.client_id, + 'response_type': 'code', + 'redirect_uri': self.redirect_uri} + if self.scope: + payload['scope'] = self.scope + if self.state: + payload['state'] = self.state + + urlparams = urllib.urlencode(payload) + + return "%s?%s" % (self.OAUTH_AUTHORIZE_URL, urlparams) + + def parse_response_code(self, response): + return response.split("?code=")[1].split("&")[0] + + def get_access_token(self, code): + payload = {'redirect_uri': self.redirect_uri, + 'code': code, + 'grant_type': 'authorization_code'} + if self.scope: + payload['scope'] = self.scope + if self.state: + payload['state'] = self.state + + auth_header = base64.b64encode(self.client_id + ':' + self.client_secret) + headers = {'Authorization': 'Basic %s' % auth_header} + + + response = requests.post(self.OAUTH_TOKEN_URL, data=payload, headers=headers, verify=True) + if response.status_code is not 200: + raise SpotifyOauthError(response.reason) + return response.json()['access_token'] \ No newline at end of file