From d092683be34123a56b77b4496a2540b240054d6b Mon Sep 17 00:00:00 2001 From: Michael Birtwell Date: Sat, 7 Jan 2017 13:17:57 +0000 Subject: [PATCH 1/2] Make is_token_expired public Make is_token_expired_public on SpotifyClientCredentials and SpotifyOAuth. This method is useful for checking whether tokens that have been stored in cookies etc have timed out. So it's useful for library users to have access to it. Refactor common implementation of is_token_expired --- spotipy/oauth2.py | 19 +++++++++++-------- tests/test_oauth.py | 18 +++++++++--------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/spotipy/oauth2.py b/spotipy/oauth2.py index 7574f88..3e79e5a 100644 --- a/spotipy/oauth2.py +++ b/spotipy/oauth2.py @@ -21,6 +21,11 @@ def _make_authorization_headers(client_id, client_secret): return {'Authorization': 'Basic %s' % auth_header.decode('ascii')} +def is_token_expired(token_info): + now = int(time.time()) + return token_info['expires_at'] - now < 60 + + class SpotifyClientCredentials(object): OAUTH_TOKEN_URL = 'https://accounts.spotify.com/api/token' @@ -52,7 +57,7 @@ class SpotifyClientCredentials(object): If a valid access token is in memory, returns it Else feches a new token and returns it """ - if self.token_info and not self._is_token_expired(self.token_info): + if self.token_info and not self.is_token_expired(self.token_info): return self.token_info['access_token'] token_info = self._request_access_token() @@ -73,9 +78,8 @@ class SpotifyClientCredentials(object): token_info = response.json() return token_info - def _is_token_expired(self, token_info): - now = int(time.time()) - return token_info['expires_at'] - now < 60 + def is_token_expired(self, token_info): + return is_token_expired(token_info) def _add_custom_values_to_token_info(self, token_info): """ @@ -131,7 +135,7 @@ class SpotifyOAuth(object): if 'scope' not in token_info or not self._is_scope_subset(self.scope, token_info['scope']): return None - if self._is_token_expired(token_info): + if self.is_token_expired(token_info): token_info = self.refresh_access_token(token_info['refresh_token']) except IOError: @@ -154,9 +158,8 @@ class SpotifyOAuth(object): return needle_scope <= haystack_scope - def _is_token_expired(self, token_info): - now = int(time.time()) - return token_info['expires_at'] < now + def is_token_expired(self, token_info): + return is_token_expired(token_info) def get_authorize_url(self, state=None): """ Gets the URL to use to authorize this app diff --git a/tests/test_oauth.py b/tests/test_oauth.py index 98f7548..76ff8f5 100644 --- a/tests/test_oauth.py +++ b/tests/test_oauth.py @@ -39,16 +39,16 @@ def _make_oauth(*args, **kwargs): class OAuthCacheTest(unittest.TestCase): @patch.multiple(SpotifyOAuth, - _is_token_expired=DEFAULT, refresh_access_token=DEFAULT) + is_token_expired=DEFAULT, refresh_access_token=DEFAULT) @patch('spotipy.oauth2.open', create=True) def test_gets_from_cache_path(self, opener, - _is_token_expired, refresh_access_token): + is_token_expired, refresh_access_token): scope = "playlist-modify-private" path = ".cache-username" tok = _make_fake_token(1, 1, scope) opener.return_value = _token_file(json.dumps(tok, ensure_ascii=False)) - _is_token_expired.return_value = False + is_token_expired.return_value = False spot = _make_oauth(scope, path) cached_tok = spot.get_cached_token() @@ -58,10 +58,10 @@ class OAuthCacheTest(unittest.TestCase): self.assertEqual(refresh_access_token.call_count, 0) @patch.multiple(SpotifyOAuth, - _is_token_expired=DEFAULT, refresh_access_token=DEFAULT) + is_token_expired=DEFAULT, refresh_access_token=DEFAULT) @patch('spotipy.oauth2.open', create=True) def test_expired_token_refreshes(self, opener, - _is_token_expired, refresh_access_token): + is_token_expired, refresh_access_token): scope = "playlist-modify-private" path = ".cache-username" expired_tok = _make_fake_token(0, None, scope) @@ -74,22 +74,22 @@ class OAuthCacheTest(unittest.TestCase): spot = _make_oauth(scope, path) spot.get_cached_token() - _is_token_expired.assert_called_with(expired_tok) + is_token_expired.assert_called_with(expired_tok) refresh_access_token.assert_called_with(expired_tok['refresh_token']) opener.assert_any_call(path) @patch.multiple(SpotifyOAuth, - _is_token_expired=DEFAULT, refresh_access_token=DEFAULT) + is_token_expired=DEFAULT, refresh_access_token=DEFAULT) @patch('spotipy.oauth2.open', create=True) def test_badly_scoped_token_bails(self, opener, - _is_token_expired, refresh_access_token): + is_token_expired, refresh_access_token): token_scope = "playlist-modify-public" requested_scope = "playlist-modify-private" path = ".cache-username" tok = _make_fake_token(1, 1, token_scope) opener.return_value = _token_file(json.dumps(tok, ensure_ascii=False)) - _is_token_expired.return_value = False + is_token_expired.return_value = False spot = _make_oauth(requested_scope, path) cached_tok = spot.get_cached_token() From 8dc90d2687392364b07c49bdca5712fcbfea461a Mon Sep 17 00:00:00 2001 From: Michael Birtwell Date: Sat, 7 Jan 2017 16:19:18 +0000 Subject: [PATCH 2/2] Add me to the contributors list --- docs/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.rst b/docs/index.rst index c77a4f1..6a0db95 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -352,6 +352,7 @@ Spotipy authored by Paul Lamere (plamere) with contributions by: - Tim Balzer // timbalzer - corycorycory // corycorycory - Nathan Coleman // nathancoleman + - Michael Birtwell // mbirtwell License =======