Print -> Logging, fixes #84 (#461)

This commit is contained in:
Dj 2020-04-03 15:03:09 -07:00 committed by GitHub
parent ccfda079c8
commit b01adba826
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 297 additions and 282 deletions

View File

@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- backoff_factor - backoff_factor
- Spin up a local webserver to auto-fill authentication URL - Spin up a local webserver to auto-fill authentication URL
- Use session in SpotifyAuthBase - Use session in SpotifyAuthBase
- Logging used instead of print statements
### Fixed ### Fixed

View File

@ -8,7 +8,7 @@ If you would like to contribute to spotipy follow these steps:
export SPOTIPY_CLIENT_ID=client_id_here export SPOTIPY_CLIENT_ID=client_id_here
export SPOTIPY_CLIENT_SECRET=client_secret_here export SPOTIPY_CLIENT_SECRET=client_secret_here
export SPOTIPY_CLIENT_USERNAME=client_username_here # This is actually an id not spotify display name export SPOTIPY_CLIENT_USERNAME=client_username_here # This is actually an id not spotify display name
export SPOTIPY_REDIRECT_URI=http://localhost/ # Make url is set in app you created to get your ID and SECRET export SPOTIPY_REDIRECT_URI=http://localhost:8080 # Make url is set in app you created to get your ID and SECRET
``` ```
### Create virtual environment, install dependencies, run tests: ### Create virtual environment, install dependencies, run tests:
@ -33,4 +33,4 @@ To verify the code style:
### README ### README
Don't forget to add a short description of your change in the [CHANGELOG](CHANGELOG.md) Don't forget to add a short description of your change in the [CHANGELOG](CHANGELOG.md)

View File

@ -1,27 +1,36 @@
import argparse
# Add tracks to 'Your Collection' of saved tracks import logging
import os
import pprint
import sys
import spotipy import spotipy
import spotipy.util as util import spotipy.util as util
logger = logging.getLogger('examples.add_a_saved_album')
logging.basicConfig(level='DEBUG')
scope = 'user-library-modify' scope = 'user-library-modify'
if len(sys.argv) > 2:
username = sys.argv[1]
aids = sys.argv[2:]
else:
print("Usage: %s username album-id ..." % (sys.argv[0],))
sys.exit()
token = util.prompt_for_user_token(username, scope) def get_args():
parser = argparse.ArgumentParser(description='Creates a playlist for user')
parser.add_argument('-u', '--username', required=False,
default=os.environ.get('SPOTIPY_CLIENT_USERNAME'),
help='Username id. Defaults to environment var')
parser.add_argument('-a', '--aids', action='append',
required=True, help='Album ids')
return parser.parse_args()
if token:
sp = spotipy.Spotify(auth=token) def main():
sp.trace = False args = get_args()
results = sp.current_user_saved_albums_add(albums=aids) token = util.prompt_for_user_token(args.username, scope)
pprint.pprint(results)
else: if token:
print("Can't get token for", username) sp = spotipy.Spotify(auth=token)
sp.current_user_saved_albums_add(albums=args.aids)
else:
logger.error("Can't get token for %s", args.username)
if __name__ == '__main__':
main()

View File

@ -1,27 +1,37 @@
import argparse
# Add tracks to 'Your Collection' of saved tracks import logging
import os
import pprint
import sys
import spotipy import spotipy
import spotipy.util as util import spotipy.util as util
scope = 'user-library-modify' scope = 'user-library-modify'
if len(sys.argv) > 2: logger = logging.getLogger('examples.add_a_saved_track')
username = sys.argv[1] logging.basicConfig(level='DEBUG')
tids = sys.argv[2:]
else:
print("Usage: %s username track-id ..." % (sys.argv[0],))
sys.exit()
token = util.prompt_for_user_token(username, scope)
if token: def get_args():
sp = spotipy.Spotify(auth=token) parser = argparse.ArgumentParser(description='Add tracks to Your '
sp.trace = False 'Collection of saved tracks')
results = sp.current_user_saved_tracks_add(tracks=tids) parser.add_argument('-u', '--username', required=False,
pprint.pprint(results) default=os.environ.get('SPOTIPY_CLIENT_USERNAME'),
else: help='Username id. Defaults to environment var')
print("Can't get token for", username) parser.add_argument('-t', '--tids', action='append',
required=True, help='Track ids')
return parser.parse_args()
def main():
args = get_args()
token = util.prompt_for_user_token(args.username, scope)
if token:
sp = spotipy.Spotify(auth=token)
sp.current_user_saved_tracks_add(tracks=args.tids)
else:
logger.error("Can't get token for %s", args.username)
if __name__ == '__main__':
main()

View File

@ -1,26 +1,37 @@
import argparse
# Adds tracks to a playlist import logging
import os
import sys
import spotipy import spotipy
import spotipy.util as util import spotipy.util as util
if len(sys.argv) > 3: logger = logging.getLogger('examples.add_tracks_to_playlist')
username = sys.argv[1] logging.basicConfig(level='DEBUG')
playlist_id = sys.argv[2]
track_ids = sys.argv[3:]
else:
print("Usage: %s username playlist_id track_id ..." % (sys.argv[0],))
sys.exit()
scope = 'playlist-modify-public' scope = 'playlist-modify-public'
token = util.prompt_for_user_token(username, scope)
if token:
sp = spotipy.Spotify(auth=token) def get_args():
sp.trace = False parser = argparse.ArgumentParser(description='Adds track to user playlist')
results = sp.user_playlist_add_tracks(username, playlist_id, track_ids) parser.add_argument('-u', '--username', required=False,
print(results) default=os.environ.get('SPOTIPY_CLIENT_USERNAME'),
else: help='Username id. Defaults to environment var')
print("Can't get token for", username) parser.add_argument('-t', '--tids', action='append',
required=True, help='Track ids')
parser.add_argument('-p', '--playlist', required=True,
help='Playlist to add track to')
return parser.parse_args()
def main():
args = get_args()
token = util.prompt_for_user_token(args.username, scope)
if token:
sp = spotipy.Spotify(auth=token)
sp.user_playlist_add_tracks(args.username, args.playlist, args.tids)
else:
logger.error("Can't get token for %s", args.username)
if __name__ == '__main__':
main()

View File

@ -1,9 +1,20 @@
import argparse
import logging
from spotipy.oauth2 import SpotifyClientCredentials from spotipy.oauth2 import SpotifyClientCredentials
import sys
import spotipy import spotipy
''' shows the albums and tracks for a given artist. logger = logging.getLogger('examples.artist_albums')
''' logging.basicConfig(level='INFO')
sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials())
def get_args():
parser = argparse.ArgumentParser(description='Gets albums from artist')
parser.add_argument('-a', '--artist', required=True,
help='Name of Artist')
return parser.parse_args()
def get_artist(name): def get_artist(name):
@ -27,19 +38,18 @@ def show_artist_albums(artist):
for album in albums: for album in albums:
name = album['name'] name = album['name']
if name not in seen: if name not in seen:
print((' ' + name)) logger.info('ALBUM: %s', name)
seen.add(name) seen.add(name)
if __name__ == '__main__': def main():
sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials()) args = get_args()
artist = get_artist(args.artist)
if len(sys.argv) < 2: if artist:
print(('Usage: {0} artist name'.format(sys.argv[0]))) show_artist_albums(artist)
else: else:
name = ' '.join(sys.argv[1:]) logger.error("Can't find artist: %s", artist)
artist = get_artist(name)
if artist:
show_artist_albums(artist) if __name__ == '__main__':
else: main()
print("Can't find that artist")

View File

@ -1,9 +1,19 @@
import argparse
import logging
from spotipy.oauth2 import SpotifyClientCredentials from spotipy.oauth2 import SpotifyClientCredentials
import sys
import spotipy import spotipy
''' shows the albums and tracks for a given artist. logger = logging.getLogger('examples.artist_discography')
''' logging.basicConfig(level='INFO')
def get_args():
parser = argparse.ArgumentParser(description='Shows albums and tracks for '
'given artist')
parser.add_argument('-a', '--artist', required=True,
help='Name of Artist')
return parser.parse_args()
def get_artist(name): def get_artist(name):
@ -22,45 +32,41 @@ def show_album_tracks(album):
while results['next']: while results['next']:
results = sp.next(results) results = sp.next(results)
tracks.extend(results['items']) tracks.extend(results['items'])
for track in tracks: for i, track in enumerate(tracks):
print(' ', track['name']) logger.info('%s. %s', i+1, track['name'])
print()
print(track)
def show_artist_albums(id): def show_artist_albums(artist):
albums = [] albums = []
results = sp.artist_albums(artist['id'], album_type='album') results = sp.artist_albums(artist['id'], album_type='album')
albums.extend(results['items']) albums.extend(results['items'])
while results['next']: while results['next']:
results = sp.next(results) results = sp.next(results)
albums.extend(results['items']) albums.extend(results['items'])
print('Total albums:', len(albums)) logger.info('Total albums: %s', len(albums))
unique = set() # skip duplicate albums unique = set() # skip duplicate albums
for album in albums: for album in albums:
name = album['name'].lower() name = album['name'].lower()
if name not in unique: if name not in unique:
print(name) logger.info('ALBUM: %s', name)
unique.add(name) unique.add(name)
show_album_tracks(album) show_album_tracks(album)
def show_artist(artist): def show_artist(artist):
print('====', artist['name'], '====') logger.info('====%s====', artist['name'])
print('Popularity: ', artist['popularity']) logger.info('Popularity: %s', artist['popularity'])
if len(artist['genres']) > 0: if len(artist['genres']) > 0:
print('Genres: ', ','.join(artist['genres'])) logger.info('Genres: %s', ','.join(artist['genres']))
def main():
args = get_args()
artist = get_artist(args.artist)
show_artist(artist)
show_artist_albums(artist)
if __name__ == '__main__': if __name__ == '__main__':
client_credentials_manager = SpotifyClientCredentials() client_credentials_manager = SpotifyClientCredentials()
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
sp.trace = False main()
if len(sys.argv) < 2:
print(('Usage: {0} artist name'.format(sys.argv[0])))
else:
name = ' '.join(sys.argv[1:])
artist = get_artist(name)
show_artist(artist)
show_artist_albums(artist)

View File

@ -1,13 +1,22 @@
import sys import argparse
import logging
import spotipy import spotipy
''' shows recommendations for the given artist
'''
from spotipy.oauth2 import SpotifyClientCredentials from spotipy.oauth2 import SpotifyClientCredentials
logger = logging.getLogger('examples.artist_recommendations')
logging.basicConfig(level='INFO')
client_credentials_manager = SpotifyClientCredentials() client_credentials_manager = SpotifyClientCredentials()
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
sp.trace = False
def get_args():
parser = argparse.ArgumentParser(description='Recommendations for the '
'given artist')
parser.add_argument('-a', '--artist', required=True, help='Name of Artist')
return parser.parse_args()
def get_artist(name): def get_artist(name):
@ -22,16 +31,18 @@ def get_artist(name):
def show_recommendations_for_artist(artist): def show_recommendations_for_artist(artist):
results = sp.recommendations(seed_artists=[artist['id']]) results = sp.recommendations(seed_artists=[artist['id']])
for track in results['tracks']: for track in results['tracks']:
print(track['name'], '-', track['artists'][0]['name']) logger.info('Recommendation: %s - %s', track['name'],
track['artists'][0]['name'])
def main():
args = get_args()
artist = get_artist(args.artist)
if artist:
show_recommendations_for_artist(artist)
else:
logger.error("Can't find that artist", args.artist)
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) < 2: main()
print(('Usage: {0} artist name'.format(sys.argv[0])))
else:
name = ' '.join(sys.argv[1:])
artist = get_artist(name)
if artist:
show_recommendations_for_artist(artist)
else:
print("Can't find that artist", name)

View File

@ -1,42 +1,54 @@
import argparse
# Modify the details of a playlist (name, public, collaborative) import logging
import os
import sys
import spotipy import spotipy
import spotipy.util as util import spotipy.util as util
if len(sys.argv) > 3: logger = logging.getLogger('examples.change_playlist_details')
username = sys.argv[1] logging.basicConfig(level='DEBUG')
playlist_id = sys.argv[2]
name = sys.argv[3]
public = None
if len(sys.argv) > 4:
public = sys.argv[4].lower() == 'true'
collaborative = None
if len(sys.argv) > 5:
collaborative = sys.argv[5].lower() == 'true'
description = None
if len(sys.argv) > 6:
description = sys.argv[6]
else:
print("Usage: %s username playlist_id name [public collaborative "
"description]" % (sys.argv[0]))
sys.exit()
scope = 'playlist-modify-public playlist-modify-private' scope = 'playlist-modify-public playlist-modify-private'
token = util.prompt_for_user_token(username, scope)
if token:
sp = spotipy.Spotify(auth=token) def get_args():
sp.trace = False parser = argparse.ArgumentParser(description='Modify details of playlist')
results = sp.user_playlist_change_details( parser.add_argument('-u', '--username', required=False,
username, playlist_id, name=name, public=public, default=os.environ.get('SPOTIPY_CLIENT_USERNAME'),
collaborative=collaborative, description=description) help='Username id. Defaults to environment var')
print(results) parser.add_argument('-p', '--playlist', required=True,
else: help='Playlist id to alter details')
print("Can't get token for"), username parser.add_argument('-n', '--name', required=False,
help='Name of playlist')
parser.add_argument('--public', action='store_true', required=False,
help='Include param if playlist is public')
parser.add_argument('--private', action='store_false', required=False,
default=None,
help='Include param to make playlist is private')
parser.add_argument('-c', '--collaborative', action='store_true',
required=False, default=None,
help='Include param if playlist is collaborative')
parser.add_argument('-i', '--independent', action='store_false',
required=False, default=None,
help='Include param to make playlist non collaborative')
parser.add_argument('-d', '--description', default=None, required=False,
help='Description of playlist')
return parser.parse_args()
def main():
args = get_args()
token = util.prompt_for_user_token(args.username, scope)
if token:
sp = spotipy.Spotify(auth=token)
sp.user_playlist_change_details(
args.username, args.playlist, name=args.name,
public=args.public or args.private,
collaborative=args.collaborative or args.independent,
description=args.description)
else:
logger.error("Can't get token for %s", args.username)
if __name__ == '__main__':
main()

View File

@ -1,30 +1,39 @@
# Creates a playlist for a user # Creates a playlist for a user
import argparse
import pprint import logging
import sys import os
import spotipy import spotipy
import spotipy.util as util import spotipy.util as util
logger = logging.getLogger('examples.create_playlist')
logging.basicConfig(level='DEBUG')
if len(sys.argv) > 2:
username = sys.argv[1]
playlist_name = sys.argv[2]
playlist_description = sys.argv[3]
else:
print(
"Usage: %s username playlist-name playlist-description" %
(sys.argv[0],))
sys.exit()
scope = "playlist-modify-public" def get_args():
token = util.prompt_for_user_token(username, scope) parser = argparse.ArgumentParser(description='Creates a playlist for user')
parser.add_argument('-u', '--username', required=False,
default=os.environ.get('SPOTIPY_CLIENT_USERNAME'),
help='Username id. Defaults to environment var')
parser.add_argument('-p', '--playlist', required=True,
help='Name of Playlist')
parser.add_argument('-d', '--description', required=False, default='',
help='Description of Playlist')
return parser.parse_args()
if token:
sp = spotipy.Spotify(auth=token) def main():
sp.trace = False args = get_args()
playlists = sp.user_playlist_create(username, playlist_name, scope = "playlist-modify-public"
description=playlist_description) token = util.prompt_for_user_token(args.username, scope)
pprint.pprint(playlists)
else: if token:
print("Can't get token for", username) logger.info('USERNAME: %s, PLAYLIST: %s', args.username, args.playlist)
sp = spotipy.Spotify(auth=token)
sp.user_playlist_create(args.username, args.playlist)
else:
logger.error("Can't get token for: %s", args.username)
if __name__ == '__main__':
main()

View File

@ -1,19 +0,0 @@
# shows acoustic features for tracks for the given artist
from __future__ import print_function # (at top of module)
from spotipy.oauth2 import SpotifyClientCredentials
import spotipy
client_credentials_manager = SpotifyClientCredentials()
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
sp.trace = True
try:
print('bad call 0')
bad_artist_call = sp.artist('spotify:artist:12341234')
except spotipy.client.SpotifyException:
print('bad call 0 exception')
print('bad call 1')
bad_artist_call = sp.artist('spotify:artist:12341234')
print('bad artist', bad_artist_call)

View File

@ -1,14 +0,0 @@
# shows artist info for a URN or URL
import spotipy
import sys
import pprint
if len(sys.argv) > 1:
search_str = sys.argv[1]
else:
search_str = 'Radiohead'
sp = spotipy.Spotify(requests_timeout=.1)
result = sp.search(search_str)
pprint.pprint(result)

View File

@ -2,10 +2,10 @@
""" A simple and thin Python library for the Spotify Web API """ """ A simple and thin Python library for the Spotify Web API """
from __future__ import print_function __all__ = ["Spotify", "SpotifyException"]
import json import json
import sys import logging
import warnings import warnings
import requests import requests
@ -14,6 +14,8 @@ import six
from spotipy.exceptions import SpotifyException from spotipy.exceptions import SpotifyException
logger = logging.getLogger(__name__)
class Spotify(object): class Spotify(object):
""" """
@ -24,18 +26,12 @@ class Spotify(object):
urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu' urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu'
sp = spotipy.Spotify() sp = spotipy.Spotify()
sp.trace = True # turn on tracing
sp.trace_out = True # turn on trace out
artist = sp.artist(urn) artist = sp.artist(urn)
print(artist) print(artist)
user = sp.user('plamere') user = sp.user('plamere')
print(user) print(user)
""" """
trace = False # Enable tracing?
trace_out = False
max_retries = 3 max_retries = 3
default_retry_codes = (429, 500, 502, 503, 504) default_retry_codes = (429, 500, 502, 503, 504)
@ -161,8 +157,8 @@ class Spotify(object):
if payload: if payload:
args["data"] = json.dumps(payload) args["data"] = json.dumps(payload)
if self.trace_out: logger.debug('Sending %s to %s with Headers: %s and Body: %r ',
print(url) method, url, headers, args.get('data'))
try: try:
response = self._session.request( response = self._session.request(
@ -170,15 +166,6 @@ class Spotify(object):
timeout=self.requests_timeout, **args timeout=self.requests_timeout, **args
) )
if self.trace: # pragma: no cover
print()
print("Request headers:", headers)
print("Response headers:", response.headers)
print("HTTP status", response.status_code)
print(method, response.url)
if payload:
print("Data", json.dumps(payload))
response.raise_for_status() response.raise_for_status()
results = response.json() results = response.json()
except requests.exceptions.HTTPError: except requests.exceptions.HTTPError:
@ -187,6 +174,9 @@ class Spotify(object):
except (ValueError, KeyError): except (ValueError, KeyError):
msg = "error" msg = "error"
logger.error('HTTP Error for %s to %s returned %s due to %s',
method, url, response.status_code, msg)
raise SpotifyException( raise SpotifyException(
response.status_code, response.status_code,
-1, -1,
@ -194,6 +184,7 @@ class Spotify(object):
headers=response.headers, headers=response.headers,
) )
except requests.exceptions.RetryError: except requests.exceptions.RetryError:
logger.error('Max Retries reached')
raise SpotifyException( raise SpotifyException(
599, 599,
-1, -1,
@ -203,9 +194,7 @@ class Spotify(object):
except ValueError: except ValueError:
results = None results = None
if self.trace: # pragma: no cover logger.debug('RESULTS: %s', results)
print("Response:", results)
print()
return results return results
def _get(self, url, args=None, payload=None, **kwargs): def _get(self, url, args=None, payload=None, **kwargs):
@ -251,12 +240,6 @@ class Spotify(object):
else: else:
return None return None
def _warn_old(self, msg):
print("warning:" + msg, file=sys.stderr)
def _warn(self, msg, *args):
print("warning:" + msg.format(*args), file=sys.stderr)
def track(self, track_id): def track(self, track_id):
""" returns a single track given the track's ID, URI or URL """ returns a single track given the track's ID, URI or URL
@ -1322,10 +1305,10 @@ class Spotify(object):
start playing the next song. start playing the next song.
""" """
if context_uri is not None and uris is not None: if context_uri is not None and uris is not None:
self._warn("specify either context uri or uris, not both") logger.warning("Specify either context uri or uris, not both")
return return
if uris is not None and not isinstance(uris, list): if uris is not None and not isinstance(uris, list):
self._warn("uris must be a list") logger.warning("URIs must be a list")
return return
data = {} data = {}
if context_uri is not None: if context_uri is not None:
@ -1374,7 +1357,7 @@ class Spotify(object):
- device_id - device target for playback - device_id - device target for playback
""" """
if not isinstance(position_ms, int): if not isinstance(position_ms, int):
self._warn("position_ms must be an integer") logger.warning("Position_ms must be an integer")
return return
return self._put( return self._put(
self._append_device_id( self._append_device_id(
@ -1390,7 +1373,7 @@ class Spotify(object):
- device_id - device target for playback - device_id - device target for playback
""" """
if state not in ["track", "context", "off"]: if state not in ["track", "context", "off"]:
self._warn("invalid state") logger.warning("Invalid state")
return return
self._put( self._put(
self._append_device_id( self._append_device_id(
@ -1406,10 +1389,10 @@ class Spotify(object):
- device_id - device target for playback - device_id - device target for playback
""" """
if not isinstance(volume_percent, int): if not isinstance(volume_percent, int):
self._warn("volume must be an integer") logger.warning("Volume must be an integer")
return return
if volume_percent < 0 or volume_percent > 100: if volume_percent < 0 or volume_percent > 100:
self._warn("volume must be between 0 and 100, inclusive") logger.warning("Volume must be between 0 and 100, inclusive")
return return
self._put( self._put(
self._append_device_id( self._append_device_id(
@ -1426,7 +1409,7 @@ class Spotify(object):
- device_id - device target for playback - device_id - device target for playback
""" """
if not isinstance(state, bool): if not isinstance(state, bool):
self._warn("state must be a boolean") logger.warning("state must be a boolean")
return return
state = str(state).lower() state = str(state).lower()
self._put( self._put(
@ -1476,19 +1459,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( logger.warning('Expected id of type %s but found type %s %s',
"expected id of type %s but found type %s %s" type, 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( logger.warning('Expected id of type %s but found type %s %s',
"expected id of type %s but found type %s %s" type, itype, id)
% (type, itype, id)
)
return fields[-1].split("?")[0] return fields[-1].split("?")[0]
return id return id

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import print_function
__all__ = [ __all__ = [
"is_token_expired", "is_token_expired",
"SpotifyClientCredentials", "SpotifyClientCredentials",
@ -11,10 +9,11 @@ __all__ = [
import base64 import base64
import json import json
import logging
import os import os
import sys
import time import time
import warnings import warnings
import webbrowser
import requests import requests
from spotipy.util import CLIENT_CREDS_ENV_VARS, get_host_port from spotipy.util import CLIENT_CREDS_ENV_VARS, get_host_port
@ -26,6 +25,8 @@ import six.moves.urllib.parse as urllibparse
from six.moves.BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler from six.moves.BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from six.moves.urllib_parse import urlparse, parse_qsl from six.moves.urllib_parse import urlparse, parse_qsl
logger = logging.getLogger(__name__)
class SpotifyOauthError(Exception): class SpotifyOauthError(Exception):
pass pass
@ -273,7 +274,8 @@ class SpotifyOAuth(SpotifyAuthBase):
f.write(json.dumps(token_info)) f.write(json.dumps(token_info))
f.close() f.close()
except IOError: except IOError:
self._warn("couldn't write token cache to " + self.cache_path) logger.warning('Couldn\'t write token to cache at: %s',
self.cache_path)
def _is_scope_subset(self, needle_scope, haystack_scope): def _is_scope_subset(self, needle_scope, haystack_scope):
needle_scope = set(needle_scope.split()) if needle_scope else set() needle_scope = set(needle_scope.split()) if needle_scope else set()
@ -323,25 +325,19 @@ class SpotifyOAuth(SpotifyAuthBase):
def _open_auth_url(self): def _open_auth_url(self):
auth_url = self.get_authorize_url() auth_url = self.get_authorize_url()
try: try:
import webbrowser
webbrowser.open(auth_url) webbrowser.open(auth_url)
print("Opened %s in your browser" % auth_url) logger.info("Opened %s in your browser", auth_url)
except webbrowser.Error: except webbrowser.Error:
print("Please navigate here: %s" % auth_url) logger.error("Please navigate here: %s", auth_url)
def _get_auth_response_interactive(self): def _get_auth_response_interactive(self):
self._open_auth_url() self._open_auth_url()
print("")
print("")
try: try:
response = raw_input("Enter the URL you were redirected to: ") response = raw_input("Enter the URL you were redirected to: ")
except NameError: except NameError:
response = input("Enter the URL you were redirected to: ") response = input("Enter the URL you were redirected to: ")
print("")
print("")
return self.parse_response_code(response) return self.parse_response_code(response)
def _get_auth_response_local_server(self, redirect_port): def _get_auth_response_local_server(self, redirect_port):
@ -357,16 +353,11 @@ class SpotifyOAuth(SpotifyAuthBase):
raise SpotifyOauthError("Server listening on localhost has not been accessed") raise SpotifyOauthError("Server listening on localhost has not been accessed")
def get_auth_response(self): def get_auth_response(self):
print( logger.info('User authentication requires interaction with your '
""" 'web browser. Once you enter your credentials and '
'give authorization, you will be redirected to '
User authentication requires interaction with your 'a url. Paste that url you were directed to to '
web browser. Once you enter your credentials and 'complete the authorization.')
give authorization, you will be redirected to
a url.
"""
)
redirect_info = urlparse(self.redirect_uri) redirect_info = urlparse(self.redirect_uri)
redirect_host, redirect_port = get_host_port(redirect_info.netloc) redirect_host, redirect_port = get_host_port(redirect_info.netloc)
@ -374,10 +365,8 @@ class SpotifyOAuth(SpotifyAuthBase):
if redirect_host in ("127.0.0.1", "localhost") and redirect_info.scheme == "http": if redirect_host in ("127.0.0.1", "localhost") and redirect_info.scheme == "http":
return self._get_auth_response_local_server(redirect_port) return self._get_auth_response_local_server(redirect_port)
else: else:
print(""" logger.info('Paste that url you were directed to in order to '
Paste that url you were directed to to 'complete the authorization')
complete the authorization.
""")
return self._get_auth_response_interactive() return self._get_auth_response_interactive()
def get_authorization_code(self, response=None): def get_authorization_code(self, response=None):
@ -393,7 +382,6 @@ class SpotifyOAuth(SpotifyAuthBase):
as a string. as a string.
""" """
if as_dict: if as_dict:
print("")
warnings.warn( warnings.warn(
"You're using 'as_dict = True'." "You're using 'as_dict = True'."
"get_access_token will return the token string directly in future " "get_access_token will return the token string directly in future "
@ -402,7 +390,6 @@ class SpotifyOAuth(SpotifyAuthBase):
DeprecationWarning, DeprecationWarning,
stacklevel=2, stacklevel=2,
) )
print("")
if check_cache: if check_cache:
token_info = self.get_cached_token() token_info = self.get_cached_token()
if token_info is not None: if token_info is not None:
@ -461,9 +448,13 @@ class SpotifyOAuth(SpotifyAuthBase):
proxies=self.proxies, proxies=self.proxies,
timeout=self.requests_timeout, timeout=self.requests_timeout,
) )
try: try:
response.raise_for_status() response.raise_for_status()
except BaseException: except BaseException:
logger.error('Couldn\'t refresh token. Response Status Code: %s '
'Reason: %s', response.status_code, response.reason)
message = "Couldn't refresh token: code:%d reason:%s" % ( message = "Couldn't refresh token: code:%d reason:%s" % (
response.status_code, response.status_code,
response.reason, response.reason,
@ -472,6 +463,7 @@ class SpotifyOAuth(SpotifyAuthBase):
-1, -1,
message, message,
headers) headers)
token_info = response.json() token_info = response.json()
token_info = self._add_custom_values_to_token_info(token_info) token_info = self._add_custom_values_to_token_info(token_info)
if "refresh_token" not in token_info: if "refresh_token" not in token_info:
@ -488,9 +480,6 @@ class SpotifyOAuth(SpotifyAuthBase):
token_info["scope"] = self.scope token_info["scope"] = self.scope
return token_info return token_info
def _warn(self, msg):
print("warning:" + msg, file=sys.stderr)
class RequestHandler(BaseHTTPRequestHandler): class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self): def do_GET(self):

View File

@ -2,14 +2,15 @@
""" Shows a user's playlists (need to be authenticated via oauth) """ """ Shows a user's playlists (need to be authenticated via oauth) """
from __future__ import print_function
__all__ = ["CLIENT_CREDS_ENV_VARS", "prompt_for_user_token"] __all__ = ["CLIENT_CREDS_ENV_VARS", "prompt_for_user_token"]
import logging
import os import os
import spotipy import spotipy
LOGGER = logging.getLogger(__name__)
CLIENT_CREDS_ENV_VARS = { CLIENT_CREDS_ENV_VARS = {
"client_id": "SPOTIPY_CLIENT_ID", "client_id": "SPOTIPY_CLIENT_ID",
"client_secret": "SPOTIPY_CLIENT_SECRET", "client_secret": "SPOTIPY_CLIENT_SECRET",
@ -54,7 +55,7 @@ def prompt_for_user_token(
redirect_uri = os.getenv("SPOTIPY_REDIRECT_URI") redirect_uri = os.getenv("SPOTIPY_REDIRECT_URI")
if not client_id: if not client_id:
print( LOGGER.warning(
""" """
You need to set your Spotify API credentials. You need to set your Spotify API credentials.
You can do this by setting environment variables like so: You can do this by setting environment variables like so:
@ -99,7 +100,7 @@ def prompt_for_user_token(
return None return None
def get_host_port(netloc, default_port=80): def get_host_port(netloc, default_port=8080):
if ":" in netloc: if ":" in netloc:
host, port = netloc.split(":", 1) host, port = netloc.split(":", 1)
port = int(port) port = int(port)