From b01adba826e22b3618d2cb051a44b92ebec13f3f Mon Sep 17 00:00:00 2001 From: Dj Date: Fri, 3 Apr 2020 15:03:09 -0700 Subject: [PATCH] Print -> Logging, fixes #84 (#461) --- CHANGELOG.md | 1 + CONTRIBUTING.md | 4 +- examples/add_a_saved_album.py | 47 ++++++++++------- examples/add_a_saved_track.py | 48 ++++++++++------- examples/add_tracks_to_playlist.py | 51 +++++++++++------- examples/artist_albums.py | 40 ++++++++------ examples/artist_discography.py | 50 ++++++++++-------- examples/artist_recommendations.py | 43 +++++++++------ examples/change_playlist_details.py | 82 +++++++++++++++++------------ examples/create_playlist.py | 53 +++++++++++-------- examples/errors.py | 19 ------- examples/test_request_timeout.py | 14 ----- spotipy/client.py | 65 ++++++++--------------- spotipy/oauth2.py | 53 ++++++++----------- spotipy/util.py | 9 ++-- 15 files changed, 297 insertions(+), 282 deletions(-) delete mode 100644 examples/errors.py delete mode 100644 examples/test_request_timeout.py diff --git a/CHANGELOG.md b/CHANGELOG.md index ffbcd77..5dea9b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - backoff_factor - Spin up a local webserver to auto-fill authentication URL - Use session in SpotifyAuthBase + - Logging used instead of print statements ### Fixed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c40d756..67ff7f5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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_SECRET=client_secret_here 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: @@ -33,4 +33,4 @@ To verify the code style: ### README -Don't forget to add a short description of your change in the [CHANGELOG](CHANGELOG.md) \ No newline at end of file +Don't forget to add a short description of your change in the [CHANGELOG](CHANGELOG.md) diff --git a/examples/add_a_saved_album.py b/examples/add_a_saved_album.py index b98abcd..b72c6db 100644 --- a/examples/add_a_saved_album.py +++ b/examples/add_a_saved_album.py @@ -1,27 +1,36 @@ - -# Add tracks to 'Your Collection' of saved tracks - -import pprint -import sys +import argparse +import logging +import os import spotipy import spotipy.util as util +logger = logging.getLogger('examples.add_a_saved_album') +logging.basicConfig(level='DEBUG') + 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) - sp.trace = False - results = sp.current_user_saved_albums_add(albums=aids) - pprint.pprint(results) -else: - print("Can't get token for", username) + +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_albums_add(albums=args.aids) + else: + logger.error("Can't get token for %s", args.username) + + +if __name__ == '__main__': + main() diff --git a/examples/add_a_saved_track.py b/examples/add_a_saved_track.py index fd8ec1e..781be01 100644 --- a/examples/add_a_saved_track.py +++ b/examples/add_a_saved_track.py @@ -1,27 +1,37 @@ - -# Add tracks to 'Your Collection' of saved tracks - -import pprint -import sys +import argparse +import logging +import os import spotipy import spotipy.util as util scope = 'user-library-modify' -if len(sys.argv) > 2: - username = sys.argv[1] - tids = sys.argv[2:] -else: - print("Usage: %s username track-id ..." % (sys.argv[0],)) - sys.exit() +logger = logging.getLogger('examples.add_a_saved_track') +logging.basicConfig(level='DEBUG') -token = util.prompt_for_user_token(username, scope) -if token: - sp = spotipy.Spotify(auth=token) - sp.trace = False - results = sp.current_user_saved_tracks_add(tracks=tids) - pprint.pprint(results) -else: - print("Can't get token for", username) +def get_args(): + parser = argparse.ArgumentParser(description='Add tracks to Your ' + 'Collection of saved tracks') + parser.add_argument('-u', '--username', required=False, + default=os.environ.get('SPOTIPY_CLIENT_USERNAME'), + help='Username id. Defaults to environment var') + 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() diff --git a/examples/add_tracks_to_playlist.py b/examples/add_tracks_to_playlist.py index d0df161..ae61d81 100644 --- a/examples/add_tracks_to_playlist.py +++ b/examples/add_tracks_to_playlist.py @@ -1,26 +1,37 @@ - -# Adds tracks to a playlist - -import sys +import argparse +import logging +import os import spotipy import spotipy.util as util -if len(sys.argv) > 3: - username = sys.argv[1] - playlist_id = sys.argv[2] - track_ids = sys.argv[3:] -else: - print("Usage: %s username playlist_id track_id ..." % (sys.argv[0],)) - sys.exit() - +logger = logging.getLogger('examples.add_tracks_to_playlist') +logging.basicConfig(level='DEBUG') scope = 'playlist-modify-public' -token = util.prompt_for_user_token(username, scope) -if token: - sp = spotipy.Spotify(auth=token) - sp.trace = False - results = sp.user_playlist_add_tracks(username, playlist_id, track_ids) - print(results) -else: - print("Can't get token for", username) + +def get_args(): + parser = argparse.ArgumentParser(description='Adds track to user playlist') + parser.add_argument('-u', '--username', required=False, + default=os.environ.get('SPOTIPY_CLIENT_USERNAME'), + help='Username id. Defaults to environment var') + 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() diff --git a/examples/artist_albums.py b/examples/artist_albums.py index d426c9a..c5cc7a6 100644 --- a/examples/artist_albums.py +++ b/examples/artist_albums.py @@ -1,9 +1,20 @@ +import argparse +import logging + from spotipy.oauth2 import SpotifyClientCredentials -import sys 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): @@ -27,19 +38,18 @@ def show_artist_albums(artist): for album in albums: name = album['name'] if name not in seen: - print((' ' + name)) + logger.info('ALBUM: %s', name) seen.add(name) -if __name__ == '__main__': - sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials()) - - if len(sys.argv) < 2: - print(('Usage: {0} artist name'.format(sys.argv[0]))) +def main(): + args = get_args() + artist = get_artist(args.artist) + if artist: + show_artist_albums(artist) else: - name = ' '.join(sys.argv[1:]) - artist = get_artist(name) - if artist: - show_artist_albums(artist) - else: - print("Can't find that artist") + logger.error("Can't find artist: %s", artist) + + +if __name__ == '__main__': + main() diff --git a/examples/artist_discography.py b/examples/artist_discography.py index 75647f1..d3a39ad 100644 --- a/examples/artist_discography.py +++ b/examples/artist_discography.py @@ -1,9 +1,19 @@ +import argparse +import logging + from spotipy.oauth2 import SpotifyClientCredentials -import sys 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): @@ -22,45 +32,41 @@ def show_album_tracks(album): while results['next']: results = sp.next(results) tracks.extend(results['items']) - for track in tracks: - print(' ', track['name']) - print() - print(track) + for i, track in enumerate(tracks): + logger.info('%s. %s', i+1, track['name']) -def show_artist_albums(id): +def show_artist_albums(artist): albums = [] results = sp.artist_albums(artist['id'], album_type='album') albums.extend(results['items']) while results['next']: results = sp.next(results) albums.extend(results['items']) - print('Total albums:', len(albums)) + logger.info('Total albums: %s', len(albums)) unique = set() # skip duplicate albums for album in albums: name = album['name'].lower() if name not in unique: - print(name) + logger.info('ALBUM: %s', name) unique.add(name) show_album_tracks(album) def show_artist(artist): - print('====', artist['name'], '====') - print('Popularity: ', artist['popularity']) + logger.info('====%s====', artist['name']) + logger.info('Popularity: %s', artist['popularity']) 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__': client_credentials_manager = SpotifyClientCredentials() sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager) - sp.trace = False - - 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) + main() diff --git a/examples/artist_recommendations.py b/examples/artist_recommendations.py index ad0355c..40a95a2 100644 --- a/examples/artist_recommendations.py +++ b/examples/artist_recommendations.py @@ -1,13 +1,22 @@ -import sys +import argparse +import logging + import spotipy - -''' shows recommendations for the given artist -''' - from spotipy.oauth2 import SpotifyClientCredentials + + +logger = logging.getLogger('examples.artist_recommendations') +logging.basicConfig(level='INFO') + client_credentials_manager = SpotifyClientCredentials() 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): @@ -22,16 +31,18 @@ def get_artist(name): def show_recommendations_for_artist(artist): results = sp.recommendations(seed_artists=[artist['id']]) 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 len(sys.argv) < 2: - 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) + main() diff --git a/examples/change_playlist_details.py b/examples/change_playlist_details.py index b150213..62432c8 100644 --- a/examples/change_playlist_details.py +++ b/examples/change_playlist_details.py @@ -1,42 +1,54 @@ - -# Modify the details of a playlist (name, public, collaborative) - -import sys +import argparse +import logging +import os import spotipy import spotipy.util as util -if len(sys.argv) > 3: - username = sys.argv[1] - 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() +logger = logging.getLogger('examples.change_playlist_details') +logging.basicConfig(level='DEBUG') scope = 'playlist-modify-public playlist-modify-private' -token = util.prompt_for_user_token(username, scope) -if token: - sp = spotipy.Spotify(auth=token) - sp.trace = False - results = sp.user_playlist_change_details( - username, playlist_id, name=name, public=public, - collaborative=collaborative, description=description) - print(results) -else: - print("Can't get token for"), username + +def get_args(): + parser = argparse.ArgumentParser(description='Modify details of playlist') + 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='Playlist id to alter details') + 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() diff --git a/examples/create_playlist.py b/examples/create_playlist.py index 0c4caf8..dd60432 100644 --- a/examples/create_playlist.py +++ b/examples/create_playlist.py @@ -1,30 +1,39 @@ # Creates a playlist for a user - -import pprint -import sys +import argparse +import logging +import os import spotipy 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" -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('-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) - sp.trace = False - playlists = sp.user_playlist_create(username, playlist_name, - description=playlist_description) - pprint.pprint(playlists) -else: - print("Can't get token for", username) + +def main(): + args = get_args() + scope = "playlist-modify-public" + token = util.prompt_for_user_token(args.username, scope) + + if token: + 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() diff --git a/examples/errors.py b/examples/errors.py deleted file mode 100644 index 217c4e7..0000000 --- a/examples/errors.py +++ /dev/null @@ -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) diff --git a/examples/test_request_timeout.py b/examples/test_request_timeout.py deleted file mode 100644 index 167e4f1..0000000 --- a/examples/test_request_timeout.py +++ /dev/null @@ -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) diff --git a/spotipy/client.py b/spotipy/client.py index cb3cca6..961afca 100644 --- a/spotipy/client.py +++ b/spotipy/client.py @@ -2,10 +2,10 @@ """ A simple and thin Python library for the Spotify Web API """ -from __future__ import print_function +__all__ = ["Spotify", "SpotifyException"] import json -import sys +import logging import warnings import requests @@ -14,6 +14,8 @@ import six from spotipy.exceptions import SpotifyException +logger = logging.getLogger(__name__) + class Spotify(object): """ @@ -24,18 +26,12 @@ class Spotify(object): urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu' sp = spotipy.Spotify() - sp.trace = True # turn on tracing - sp.trace_out = True # turn on trace out - artist = sp.artist(urn) print(artist) user = sp.user('plamere') print(user) """ - - trace = False # Enable tracing? - trace_out = False max_retries = 3 default_retry_codes = (429, 500, 502, 503, 504) @@ -161,8 +157,8 @@ class Spotify(object): if payload: args["data"] = json.dumps(payload) - if self.trace_out: - print(url) + logger.debug('Sending %s to %s with Headers: %s and Body: %r ', + method, url, headers, args.get('data')) try: response = self._session.request( @@ -170,15 +166,6 @@ class Spotify(object): 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() results = response.json() except requests.exceptions.HTTPError: @@ -187,6 +174,9 @@ class Spotify(object): except (ValueError, KeyError): msg = "error" + logger.error('HTTP Error for %s to %s returned %s due to %s', + method, url, response.status_code, msg) + raise SpotifyException( response.status_code, -1, @@ -194,6 +184,7 @@ class Spotify(object): headers=response.headers, ) except requests.exceptions.RetryError: + logger.error('Max Retries reached') raise SpotifyException( 599, -1, @@ -203,9 +194,7 @@ class Spotify(object): except ValueError: results = None - if self.trace: # pragma: no cover - print("Response:", results) - print() + logger.debug('RESULTS: %s', results) return results def _get(self, url, args=None, payload=None, **kwargs): @@ -251,12 +240,6 @@ class Spotify(object): else: 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): """ returns a single track given the track's ID, URI or URL @@ -1322,10 +1305,10 @@ class Spotify(object): start playing the next song. """ 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 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 data = {} if context_uri is not None: @@ -1374,7 +1357,7 @@ class Spotify(object): - device_id - device target for playback """ if not isinstance(position_ms, int): - self._warn("position_ms must be an integer") + logger.warning("Position_ms must be an integer") return return self._put( self._append_device_id( @@ -1390,7 +1373,7 @@ class Spotify(object): - device_id - device target for playback """ if state not in ["track", "context", "off"]: - self._warn("invalid state") + logger.warning("Invalid state") return self._put( self._append_device_id( @@ -1406,10 +1389,10 @@ class Spotify(object): - device_id - device target for playback """ if not isinstance(volume_percent, int): - self._warn("volume must be an integer") + logger.warning("Volume must be an integer") return 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 self._put( self._append_device_id( @@ -1426,7 +1409,7 @@ class Spotify(object): - device_id - device target for playback """ if not isinstance(state, bool): - self._warn("state must be a boolean") + logger.warning("state must be a boolean") return state = str(state).lower() self._put( @@ -1476,19 +1459,15 @@ class Spotify(object): fields = id.split(":") if len(fields) >= 3: if type != fields[-2]: - self._warn( - "expected id of type %s but found type %s %s" - % (type, fields[-2], id) - ) + logger.warning('Expected id of type %s but found type %s %s', + type, fields[-2], id) return fields[-1] fields = id.split("/") if len(fields) >= 3: itype = fields[-2] if type != itype: - self._warn( - "expected id of type %s but found type %s %s" - % (type, itype, id) - ) + logger.warning('Expected id of type %s but found type %s %s', + type, itype, id) return fields[-1].split("?")[0] return id diff --git a/spotipy/oauth2.py b/spotipy/oauth2.py index 3471180..5c359f4 100644 --- a/spotipy/oauth2.py +++ b/spotipy/oauth2.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import print_function - __all__ = [ "is_token_expired", "SpotifyClientCredentials", @@ -11,10 +9,11 @@ __all__ = [ import base64 import json +import logging import os -import sys import time import warnings +import webbrowser import requests 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.urllib_parse import urlparse, parse_qsl +logger = logging.getLogger(__name__) + class SpotifyOauthError(Exception): pass @@ -273,7 +274,8 @@ class SpotifyOAuth(SpotifyAuthBase): f.write(json.dumps(token_info)) f.close() 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): needle_scope = set(needle_scope.split()) if needle_scope else set() @@ -323,25 +325,19 @@ class SpotifyOAuth(SpotifyAuthBase): def _open_auth_url(self): auth_url = self.get_authorize_url() - try: - import webbrowser webbrowser.open(auth_url) - print("Opened %s in your browser" % auth_url) + logger.info("Opened %s in your browser", auth_url) except webbrowser.Error: - print("Please navigate here: %s" % auth_url) + logger.error("Please navigate here: %s", auth_url) def _get_auth_response_interactive(self): self._open_auth_url() - print("") - print("") - try: response = raw_input("Enter the URL you were redirected to: ") except NameError: response = input("Enter the URL you were redirected to: ") - print("") - print("") + return self.parse_response_code(response) 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") def get_auth_response(self): - print( - """ - - User authentication requires interaction with your - web browser. Once you enter your credentials and - give authorization, you will be redirected to - a url. - - """ - ) + logger.info('User authentication requires interaction with your ' + 'web browser. Once you enter your credentials and ' + 'give authorization, you will be redirected to ' + 'a url. Paste that url you were directed to to ' + 'complete the authorization.') redirect_info = urlparse(self.redirect_uri) 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": return self._get_auth_response_local_server(redirect_port) else: - print(""" - Paste that url you were directed to to - complete the authorization. -""") + logger.info('Paste that url you were directed to in order to ' + 'complete the authorization') return self._get_auth_response_interactive() def get_authorization_code(self, response=None): @@ -393,7 +382,6 @@ class SpotifyOAuth(SpotifyAuthBase): as a string. """ if as_dict: - print("") warnings.warn( "You're using 'as_dict = True'." "get_access_token will return the token string directly in future " @@ -402,7 +390,6 @@ class SpotifyOAuth(SpotifyAuthBase): DeprecationWarning, stacklevel=2, ) - print("") if check_cache: token_info = self.get_cached_token() if token_info is not None: @@ -461,9 +448,13 @@ class SpotifyOAuth(SpotifyAuthBase): proxies=self.proxies, timeout=self.requests_timeout, ) + try: response.raise_for_status() 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" % ( response.status_code, response.reason, @@ -472,6 +463,7 @@ class SpotifyOAuth(SpotifyAuthBase): -1, message, headers) + token_info = response.json() token_info = self._add_custom_values_to_token_info(token_info) if "refresh_token" not in token_info: @@ -488,9 +480,6 @@ class SpotifyOAuth(SpotifyAuthBase): token_info["scope"] = self.scope return token_info - def _warn(self, msg): - print("warning:" + msg, file=sys.stderr) - class RequestHandler(BaseHTTPRequestHandler): def do_GET(self): diff --git a/spotipy/util.py b/spotipy/util.py index 445c5e5..5159330 100644 --- a/spotipy/util.py +++ b/spotipy/util.py @@ -2,14 +2,15 @@ """ 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"] +import logging import os import spotipy +LOGGER = logging.getLogger(__name__) + CLIENT_CREDS_ENV_VARS = { "client_id": "SPOTIPY_CLIENT_ID", "client_secret": "SPOTIPY_CLIENT_SECRET", @@ -54,7 +55,7 @@ def prompt_for_user_token( redirect_uri = os.getenv("SPOTIPY_REDIRECT_URI") if not client_id: - print( + LOGGER.warning( """ You need to set your Spotify API credentials. You can do this by setting environment variables like so: @@ -99,7 +100,7 @@ def prompt_for_user_token( return None -def get_host_port(netloc, default_port=80): +def get_host_port(netloc, default_port=8080): if ":" in netloc: host, port = netloc.split(":", 1) port = int(port)