diff --git a/.gitignore b/.gitignore
index 286ddd2..137335b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,6 +52,5 @@ coverage.xml
# Sphinx documentation
docs/_build/
-
.*
-archive
+archive
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..9a2fd91
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,37 @@
+- 1.0 - 04/05/2014 - Initial release
+- 1.1 - 05/18/2014 - Repackaged for saner imports
+- 1.4.1 - 06/17/2014 - Updates to match released API
+- 1.4.2 - 06/21/2014 - Added support for retrieving starred playlists
+- v1.40, June 12, 2014 -- Initial public release.
+- v1.42, June 19, 2014 -- Removed dependency on simplejson
+- v1.43, June 27, 2014 -- Fixed JSON handling issue
+- v1.44, July 3, 2014 -- Added show tracks.py example
+- v1.45, July 7, 2014 -- Support for related artists endpoint. Don't use cache auth codes when scope changes
+- v1.49, July 23, 2014 -- Support for "Your Music" tracks (add, delete, get), with examples
+- v1.50, August 14, 2014 -- Refactored util out of examples and into the main package
+- v1.301, August 19, 2014 -- Upgraded version number to take precedence over previously botched release (sigh)
+- v1.310, August 20, 2014 -- Added playlist replace and remove methods. Added auth tests. Improved API docs
+- v2.0 - August 22, 2014 -- Upgraded APIs and docs to make it be a real library
+- v2.0.2 - August 25, 2014 -- Moved to spotipy at pypi
+- v2.1.0 - October 25, 2014 -- Added support for new_releases and featured_playlists
+- v2.2.0 - November 15, 2014 -- Added support for user_playlist_tracks
+- v2.3.0 - January 5, 2015 -- Added session support added by akx.
+- v2.3.2 - March 31, 2015 -- Added auto retry logic
+- v2.3.3 - April 1, 2015 -- added client credential flow
+- v2.3.5 - April 28, 2015 -- Fixed bug in auto retry logic
+- v2.3.6 - June 3, 2015 -- Support for offset/limit with album_tracks API
+- v2.3.7 - August 10, 2015 -- Added current_user_followed_artists
+- v2.3.8 - March 30, 2016 -- Added recs, audio features, user top lists
+- v2.4.0 - December 31, 2016 -- Incorporated a number of PRs
+- v2.4.1 - January 2, 2017 -- Incorporated proxy support
+- v2.4.2 - January 2, 2017 -- support getting audio features for a single track
+- v2.4.3 - January 2, 2017 -- fixed proxy issue in standard auth flow
+- v2.4.4 - January 4, 2017 -- python 3 fix
+- v2.5.0 - January 11, 2020 -- Added follow and player endpoints
+- Unreleased
+ - Added:
+ - support for `playlist()`
+ - support for `current_user_saved_albums_delete()`
+ - support for `current_user_saved_albums_contains()`
+ - support for `user_unfollow_artists()`
+ - support for `user_unfollow_users()`
diff --git a/CHANGES.txt b/CHANGES.txt
deleted file mode 100644
index b46e2c9..0000000
--- a/CHANGES.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-v1.40, June 12, 2014 -- Initial public release.
-v1.42, June 19, 2014 -- Removed dependency on simplejson
-v1.43, June 27, 2014 -- Fixed JSON handling issue
-v1.44, July 3, 2014 -- Added show_tracks.py exampole
-v1.45, July 7, 2014 -- Support for related artists endpoint. Don't use
- cache auth codes when scope changes
-v1.50, August 14, 2014 -- Refactored util out of examples and into the main
- package
-v2.301, August 19, 2014 -- Upgraded version number to take precedence over
- previously botched release (sigh)
-v2.310, August 20, 2014 -- Added playlist replace and remove methods. Added auth
- tests. Improved API docs
-v2.310, January 5, 2015 -- Added session support
-v2.3.1, March 28, 2015 -- Auto retry support
-v2.3.5, April 28, 2015 -- Fixed bug in auto retry support
-v2.3.6, June 3, 2015 -- Support for offset/limit with album_tracks API
diff --git a/README.md b/README.md
index 09d3a1f..9c3151f 100644
--- a/README.md
+++ b/README.md
@@ -51,36 +51,4 @@ A full set of examples can be found in the [online documentation](http://spotipy
## Reporting Issues
-If you have suggestions, bugs or other issues specific to this library, file them [here](https://github.com/plamere/spotipy/issues). Or just send me a pull request.
-
-## Version
-
-- 1.0 - 04/05/2014 - Initial release
-- 1.1 - 05/18/2014 - Repackaged for saner imports
-- 1.4.1 - 06/17/2014 - Updates to match released API
-- 1.4.2 - 06/21/2014 - Added support for retrieving starred playlists
-- v1.40, June 12, 2014 -- Initial public release.
-- v1.42, June 19, 2014 -- Removed dependency on simplejson
-- v1.43, June 27, 2014 -- Fixed JSON handling issue
-- v1.44, July 3, 2014 -- Added show tracks.py example
-- v1.45, July 7, 2014 -- Support for related artists endpoint. Don't use cache auth codes when scope changes
-- v1.49, July 23, 2014 -- Support for "Your Music" tracks (add, delete, get), with examples
-- v1.50, August 14, 2014 -- Refactored util out of examples and into the main package
-- v1.301, August 19, 2014 -- Upgraded version number to take precedence over previously botched release (sigh)
-- v1.310, August 20, 2014 -- Added playlist replace and remove methods. Added auth tests. Improved API docs
-- v2.0 - August 22, 2014 -- Upgraded APIs and docs to make it be a real library
-- v2.0.2 - August 25, 2014 -- Moved to spotipy at pypi
-- v2.1.0 - October 25, 2014 -- Added support for new_releases and featured_playlists
-- v2.2.0 - November 15, 2014 -- Added support for user_playlist_tracks
-- v2.3.0 - January 5, 2015 -- Added session support added by akx.
-- v2.3.2 - March 31, 2015 -- Added auto retry logic
-- v2.3.3 - April 1, 2015 -- added client credential flow
-- v2.3.5 - April 28, 2015 -- Fixed bug in auto retry logic
-- v2.3.6 - June 3, 2015 -- Support for offset/limit with album_tracks API
-- v2.3.7 - August 10, 2015 -- Added current_user_followed_artists
-- v2.3.8 - March 30, 2016 -- Added recs, audio features, user top lists
-- v2.4.0 - December 31, 2016 -- Incorporated a number of PRs
-- v2.4.1 - January 2, 2017 -- Incorporated proxy support
-- v2.4.2 - January 2, 2017 -- support getting audio features for a single track
-- v2.4.3 - January 2, 2017 -- fixed proxy issue in standard auth flow
-- v2.4.4 - January 4, 2017 -- python 3 fix
+If you have suggestions, bugs or other issues specific to this library, file them [here](https://github.com/plamere/spotipy/issues). Or just send me a pull request.
\ No newline at end of file
diff --git a/deploy b/deploy
index f18302a..36d5c3f 100755
--- a/deploy
+++ b/deploy
@@ -1,6 +1,6 @@
#
# sudo python setup.py develop --uninstall
-# sudo python setup.py install
+# sudo python setup.py install
# How do deploy
# - run tests
@@ -9,11 +9,10 @@
# - Update README.md with updated version info
# - leave development mode
# sudo python setup.py develop --uninstall
-# sudo python setup.py install
+# sudo python setup.py install
# - upload dist
# sudo python setup.py sdist upload
# docs should automatically be updated. verify them at
# http://spotipy.readthedocs.org/en/latest/
-sudo python setup.py sdist upload
-
+sudo python setup.py sdist upload
\ No newline at end of file
diff --git a/docs/index.rst b/docs/index.rst
index 91fd31e..3e2e9ea 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -5,7 +5,7 @@ Welcome to Spotipy!
===================================
*Spotipy* is a lightweight Python library for the `Spotify Web API
`_. With *Spotipy*
-you get full access to all of the music data provided by the Spotify platform.
+you get full access to all of the music data provided by the Spotify platform.
Here's a quick example of using *Spotipy* to list the names of all the albums
released by the artist 'Birdy'::
@@ -27,6 +27,7 @@ released by the artist 'Birdy'::
Here's another example showing how to get 30 second samples and cover art
for the top 10 tracks for Led Zeppelin::
+ from __future__ import print_function
import spotipy
lz_uri = 'spotify:artist:36QJpDe2go2KgaRleHCDTp'
@@ -35,14 +36,15 @@ for the top 10 tracks for Led Zeppelin::
results = spotify.artist_top_tracks(lz_uri)
for track in results['tracks'][:10]:
- print 'track : ' + track['name']
- print 'audio : ' + track['preview_url']
- print 'cover art: ' + track['album']['images'][0]['url']
- print
+ print('track : ' + track['name'])
+ print('audio : ' + track['preview_url'])
+ print('cover art: ' + track['album']['images'][0]['url'])
+ print()
Finally, here's an example that will get the URL for an artist image given the
artist's name::
+ from __future__ import print_function
import spotipy
import sys
@@ -57,7 +59,7 @@ artist's name::
items = results['artists']['items']
if len(items) > 0:
artist = items[0]
- print artist['name'], artist['images'][0]['url']
+ print(artist['name'], artist['images'][0]['url'])
Features
@@ -87,10 +89,11 @@ Non-Authorized requests
For methods that do not require authorization, simply create a Spotify object
and start making method calls like so::
+ from __future__ import print_function
import spotipy
spotify = spotipy.Spotify()
results = spotify.search(q='artist:' + name, type='artist')
- print results
+ print(results)
Authorized requests
=======================
@@ -107,7 +110,7 @@ authenticating your app, you can simply copy the
"http://localhost/?code=..." URL from your browser and paste it to the
console where your script is running.
-Register your app at
+Register your app at
`My Applications
`_ and register the
redirect URI mentioned in the above paragragh.
@@ -115,7 +118,7 @@ redirect URI mentioned in the above paragragh.
*spotipy* supports two authorization flows:
- - The **Authorization Code flow** This method is suitable for long-running applications
+ - The **Authorization Code flow** This method is suitable for long-running applications
which the user logs into once. It provides an access token that can be refreshed.
- The **Client Credentials flow** The method makes it possible
@@ -129,15 +132,16 @@ To support the **Authorization Code Flow** *Spotipy* provides a
utility method ``util.prompt_for_user_token`` that will attempt to authorize the
user. You can pass your app credentials directly into the method as arguments::
+ util.prompt_for_user_token(username,scope,client_id='your-spotify-client-id',client_secret='your-spotify-client-secret',redirect_uri='your-app-redirect-url')
-or if you are reluctant to immortalize your app credentials in your source code,
+or if you are reluctant to immortalize your app credentials in your source code,
you can set environment variables like so::
export SPOTIPY_CLIENT_ID='your-spotify-client-id'
export SPOTIPY_CLIENT_SECRET='your-spotify-client-secret'
export SPOTIPY_REDIRECT_URI='your-app-redirect-url'
-Call ``util.prompt_for_user_token`` method with the username and the
+Call ``util.prompt_for_user_token`` method with the username and the
desired scope (see `Using
Scopes `_ for information
about scopes) and credentials. This will coordinate the user authorization via
@@ -147,6 +151,7 @@ are used to automatically re-authorized expired tokens.
Here's an example of getting user authorization to read a user's saved tracks::
+ from __future__ import print_function
import sys
import spotipy
import spotipy.util as util
@@ -156,7 +161,7 @@ Here's an example of getting user authorization to read a user's saved tracks::
if len(sys.argv) > 1:
username = sys.argv[1]
else:
- print "Usage: %s username" % (sys.argv[0],)
+ print("Usage: %s username" % (sys.argv[0],))
sys.exit()
token = util.prompt_for_user_token(username, scope)
@@ -166,9 +171,9 @@ Here's an example of getting user authorization to read a user's saved tracks::
results = sp.current_user_saved_tracks()
for item in results['items']:
track = item['track']
- print track['name'] + ' - ' + track['artists'][0]['name']
+ print(track['name'] + ' - ' + track['artists'][0]['name'])
else:
- print "Can't get token for", username
+ print("Can't get token for", username)
Client Credentials Flow
=======================
@@ -192,8 +197,8 @@ class SpotifyClientCredentials that can be used to authenticate requests like so
playlists = None
Client credentials flow is appropriate for requests that do not require access to a
-user's private data. Even if you are only making calls that do not require
-authorization, using this flow yields the benefit of a higher rate limit
+user's private data. Even if you are only making calls that do not require
+authorization, using this flow yields the benefit of a higher rate limit
IDs URIs and URLs
=======================
@@ -218,6 +223,7 @@ Here are a few more examples of using *Spotipy*.
Add tracks to a playlist::
+ from __future__ import print_function
import pprint
import sys
@@ -229,7 +235,7 @@ Add tracks to a playlist::
playlist_id = sys.argv[2]
track_ids = sys.argv[3:]
else:
- print "Usage: %s username playlist_id track_id ..." % (sys.argv[0],)
+ print("Usage: %s username playlist_id track_id ..." % (sys.argv[0],))
sys.exit()
scope = 'playlist-modify-public'
@@ -239,15 +245,16 @@ Add tracks to a playlist::
sp = spotipy.Spotify(auth=token)
sp.trace = False
results = sp.user_playlist_add_tracks(username, playlist_id, track_ids)
- print results
+ print(results)
else:
- print "Can't get token for", username
+ print("Can't get token for", username)
Shows the contents of every playlist owned by a user::
# shows a user's playlists (need to be authenticated via oauth)
+ from __future__ import print_function
import sys
import spotipy
import spotipy.util as util
@@ -255,16 +262,16 @@ Shows the contents of every playlist owned by a user::
def show_tracks(tracks):
for i, item in enumerate(tracks['items']):
track = item['track']
- print " %d %32.32s %s" % (i, track['artists'][0]['name'],
- track['name'])
+ print(" %d %32.32s %s" % (i, track['artists'][0]['name'],
+ track['name']))
if __name__ == '__main__':
if len(sys.argv) > 1:
username = sys.argv[1]
else:
- print "Whoops, need your username!"
- print "usage: python user_playlists.py [username]"
+ print("Whoops, need your username!")
+ print("usage: python user_playlists.py [username]")
sys.exit()
token = util.prompt_for_user_token(username)
@@ -274,10 +281,10 @@ Shows the contents of every playlist owned by a user::
playlists = sp.user_playlists(username)
for playlist in playlists['items']:
if playlist['owner']['id'] == username:
- print
- print playlist['name']
- print ' total tracks', playlist['tracks']['total']
- results = sp.user_playlist(username, playlist['id'],
+ print()
+ print(playlist['name'])
+ print (' total tracks', playlist['tracks']['total'])
+ results = sp.user_playlist(username, playlist['id'],
fields="tracks,next")
tracks = results['tracks']
show_tracks(tracks)
@@ -285,7 +292,7 @@ Shows the contents of every playlist owned by a user::
tracks = sp.next(tracks)
show_tracks(tracks)
else:
- print "Can't get token for", username
+ print("Can't get token for", username)
More Examples
@@ -293,7 +300,7 @@ More Examples
There are many more examples of how to use *Spotipy* in the `Examples
Directory `_ on Github
-API Reference
+API Reference
==============
:mod:`client` Module
@@ -331,7 +338,7 @@ You can ask questions about Spotipy on Stack Overflow. Don’t forget to add t
http://stackoverflow.com/questions/ask
-If you think you've found a bug, let us know at
+If you think you've found a bug, let us know at
`Spotify Issues `_
@@ -339,24 +346,25 @@ Contribute
==========
Spotipy authored by Paul Lamere (plamere) with contributions by:
- - Daniel Beaudry // danbeaudry
- - Faruk Emre Sahin // fsahin
- - George // rogueleaderr
- - Henry Greville // sethaurus
- - Hugo // hugovk
- - José Manuel Pérez // JMPerez
- - Lucas Nunno // lnunno
- - Lynn Root // econchick
- - Matt Dennewitz // mattdennewitz
- - Matthew Duck // mattduck
- - Michael Thelin // thelinmichael
- - Ryan Choi // ryankicks
- - Simon Metson // drsm79
+ - Daniel Beaudry // danbeaudry
+ - Faruk Emre Sahin // fsahin
+ - George // rogueleaderr
+ - Henry Greville // sethaurus
+ - Hugo // hugovk
+ - José Manuel Pérez // JMPerez
+ - Lucas Nunno // lnunno
+ - Lynn Root // econchick
+ - Matt Dennewitz // mattdennewitz
+ - Matthew Duck // mattduck
+ - Michael Thelin // thelinmichael
+ - Ryan Choi // ryankicks
+ - Simon Metson // drsm79
- Steve Winton // swinton
- - Tim Balzer // timbalzer
- - corycorycory // corycorycory
+ - Tim Balzer // timbalzer
+ - corycorycory // corycorycory
- Nathan Coleman // nathancoleman
- Michael Birtwell // mbirtwell
+ - Harrison Hayes // Harrison97
License
=======
diff --git a/examples/artist_discography.py b/examples/artist_discography.py
index 34114bb..3cd44f0 100644
--- a/examples/artist_discography.py
+++ b/examples/artist_discography.py
@@ -35,7 +35,7 @@ def show_artist_albums(id):
unique = set() # skip duplicate albums
for album in albums:
name = album['name'].lower()
- if not name in unique:
+ if not name in unique:
print(name)
unique.add(name)
show_album_tracks(album)
diff --git a/examples/contains_a_saved_track.py b/examples/contains_a_saved_track.py
index 2dac2f5..bd130b4 100644
--- a/examples/contains_a_saved_track.py
+++ b/examples/contains_a_saved_track.py
@@ -10,7 +10,7 @@ if len(sys.argv) > 2:
username = sys.argv[1]
tids = sys.argv[2:]
else:
- print("Usage: %s username track-id ..." % (sys.argv[0],))
+ print("Usage: %s username track-id ..." % (sys.argv[0],))
sys.exit()
token = util.prompt_for_user_token(username, scope)
diff --git a/examples/my_playlists.py b/examples/my_playlists.py
index 58e02df..50d3b2a 100644
--- a/examples/my_playlists.py
+++ b/examples/my_playlists.py
@@ -1,4 +1,4 @@
-# Shows the top artists for a user
+# Shows a user's playlists
import pprint
import sys
diff --git a/examples/my_top_artists.py b/examples/my_top_artists.py
index 91cbfe2..b4145ef 100644
--- a/examples/my_top_artists.py
+++ b/examples/my_top_artists.py
@@ -21,10 +21,10 @@ if token:
sp.trace = False
ranges = ['short_term', 'medium_term', 'long_term']
for range in ranges:
- print "range:", range
+ print ("range:", range)
results = sp.current_user_top_artists(time_range=range, limit=50)
for i, item in enumerate(results['items']):
- print i, item['name']
- print
+ print (i, item['name'])
+ print ()
else:
print("Can't get token for", username)
diff --git a/examples/my_top_tracks.py b/examples/my_top_tracks.py
index 6bd72ec..f1a96ea 100644
--- a/examples/my_top_tracks.py
+++ b/examples/my_top_tracks.py
@@ -1,4 +1,4 @@
-# Adds tracks to a playlist
+# Shows the top tracks for a user
import pprint
import sys
@@ -21,11 +21,11 @@ if token:
sp.trace = False
ranges = ['short_term', 'medium_term', 'long_term']
for range in ranges:
- print "range:", range
+ print ("range:", range)
results = sp.current_user_top_tracks(time_range=range, limit=50)
for i, item in enumerate(results['items']):
- print i, item['name'], '//', item['artists'][0]['name']
- print
-
+ print (i, item['name'], '//', item['artists'][0]['name'])
+ print ()
+
else:
print("Can't get token for", username)
diff --git a/examples/read_a_playlist.py b/examples/read_a_playlist.py
index dbcf984..6c0dc72 100644
--- a/examples/read_a_playlist.py
+++ b/examples/read_a_playlist.py
@@ -10,4 +10,4 @@ username = uri.split(':')[2]
playlist_id = uri.split(':')[4]
results = sp.user_playlist(username, playlist_id)
-print json.dumps(results, indent=4)
+print (json.dumps(results, indent=4))
diff --git a/examples/remove_specific_tracks_from_playlist.py b/examples/remove_specific_tracks_from_playlist.py
index a99dc94..c0bbcd7 100644
--- a/examples/remove_specific_tracks_from_playlist.py
+++ b/examples/remove_specific_tracks_from_playlist.py
@@ -1,5 +1,4 @@
-
-# Adds tracks to a playlist
+# removes tracks from a playlist
import pprint
import sys
diff --git a/examples/remove_tracks_from_playlist.py b/examples/remove_tracks_from_playlist.py
index e9fca7b..73a65c5 100644
--- a/examples/remove_tracks_from_playlist.py
+++ b/examples/remove_tracks_from_playlist.py
@@ -1,5 +1,4 @@
-
-# Adds tracks to a playlist
+# removes tracks to a playlist
import pprint
import sys
diff --git a/examples/replace_tracks_in_playlist.py b/examples/replace_tracks_in_playlist.py
index 452d328..d7236cc 100644
--- a/examples/replace_tracks_in_playlist.py
+++ b/examples/replace_tracks_in_playlist.py
@@ -1,4 +1,3 @@
-
# Replaces all tracks in a playlist
import pprint
diff --git a/examples/show_album.py b/examples/show_album.py
index e492b3c..acd310f 100644
--- a/examples/show_album.py
+++ b/examples/show_album.py
@@ -2,6 +2,7 @@
# shows album info for a URN or URL
import spotipy
+from spotipy.oauth2 import SpotifyClientCredentials
import sys
import pprint
@@ -11,6 +12,7 @@ else:
urn = 'spotify:album:5yTx83u3qerZF7GRJu7eFk'
-sp = spotipy.Spotify()
+client_credentials_manager = SpotifyClientCredentials()
+sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
album = sp.album(urn)
pprint.pprint(album)
diff --git a/examples/show_artist.py b/examples/show_artist.py
index 0180b2a..c0a9834 100644
--- a/examples/show_artist.py
+++ b/examples/show_artist.py
@@ -1,6 +1,7 @@
# shows artist info for a URN or URL
import spotipy
+from spotipy.oauth2 import SpotifyClientCredentials
import sys
import pprint
@@ -9,7 +10,8 @@ if len(sys.argv) > 1:
else:
urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu'
-sp = spotipy.Spotify()
+client_credentials_manager = SpotifyClientCredentials()
+sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
artist = sp.artist(urn)
diff --git a/examples/show_artist_top_tracks.py b/examples/show_artist_top_tracks.py
index a80beb8..68d8755 100644
--- a/examples/show_artist_top_tracks.py
+++ b/examples/show_artist_top_tracks.py
@@ -1,6 +1,7 @@
# shows artist info for a URN or URL
import spotipy
+from spotipy.oauth2 import SpotifyClientCredentials
import sys
import pprint
@@ -9,7 +10,8 @@ if len(sys.argv) > 1:
else:
urn = 'spotify:artist:3jOstUTkEu2JkjvRdBA5Gu'
-sp = spotipy.Spotify()
+client_credentials_manager = SpotifyClientCredentials()
+sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
response = sp.artist_top_tracks(urn)
for track in response['tracks']:
diff --git a/examples/show_related.py b/examples/show_related.py
index b78e1dc..0fca47d 100644
--- a/examples/show_related.py
+++ b/examples/show_related.py
@@ -2,6 +2,7 @@
# shows related artists for the given seed artist
import spotipy
+from spotipy.oauth2 import SpotifyClientCredentials
import sys
import pprint
@@ -10,7 +11,9 @@ if len(sys.argv) > 1:
else:
artist_name = 'weezer'
-sp = spotipy.Spotify()
+
+client_credentials_manager = SpotifyClientCredentials()
+sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
result = sp.search(q='artist:' + artist_name, type='artist')
try:
name = result['artists']['items'][0]['name']
diff --git a/examples/show_track_info.py b/examples/show_track_info.py
index b286c0d..def5a9a 100644
--- a/examples/show_track_info.py
+++ b/examples/show_track_info.py
@@ -1,6 +1,7 @@
# shows track info for a URN or URL
import spotipy
+from spotipy.oauth2 import SpotifyClientCredentials
import sys
import pprint
@@ -9,6 +10,7 @@ if len(sys.argv) > 1:
else:
urn = 'spotify:track:0Svkvt5I79wficMFgaqEQJ'
-sp = spotipy.Spotify()
+client_credentials_manager = SpotifyClientCredentials()
+sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
track = sp.track(urn)
pprint.pprint(track)
diff --git a/examples/simple0.py b/examples/simple0.py
index 52540bb..c1ea7d7 100644
--- a/examples/simple0.py
+++ b/examples/simple0.py
@@ -1,5 +1,8 @@
import spotipy
-sp = spotipy.Spotify()
+from spotipy.oauth2 import SpotifyClientCredentials
+
+client_credentials_manager = SpotifyClientCredentials()
+sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
results = sp.search(q='weezer', limit=20)
for i, t in enumerate(results['tracks']['items']):
diff --git a/examples/simple1.py b/examples/simple1.py
index 1748b24..e9c0fb7 100644
--- a/examples/simple1.py
+++ b/examples/simple1.py
@@ -1,14 +1,15 @@
import spotipy
-
+from spotipy.oauth2 import SpotifyClientCredentials
birdy_uri = 'spotify:artist:2WX2uTcsvV5OnS0inACecP'
-spotify = spotipy.Spotify()
+client_credentials_manager = SpotifyClientCredentials()
+sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
-results = spotify.artist_albums(birdy_uri, album_type='album')
+results = sp.artist_albums(birdy_uri, album_type='album')
albums = results['items']
while results['next']:
- results = spotify.next(results)
+ results = sp.next(results)
albums.extend(results['items'])
for album in albums:
diff --git a/examples/simple2.py b/examples/simple2.py
index 3b06ddc..79a67e1 100644
--- a/examples/simple2.py
+++ b/examples/simple2.py
@@ -1,12 +1,14 @@
import spotipy
+from spotipy.oauth2 import SpotifyClientCredentials
lz_uri = 'spotify:artist:36QJpDe2go2KgaRleHCDTp'
-spotify = spotipy.Spotify()
+client_credentials_manager = SpotifyClientCredentials()
+sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
-results = spotify.artist_top_tracks(lz_uri)
+results = sp.artist_top_tracks(lz_uri)
for track in results['tracks'][:10]:
print('track : ' + track['name'])
diff --git a/examples/simple3.py b/examples/simple3.py
index 96f300a..929c899 100644
--- a/examples/simple3.py
+++ b/examples/simple3.py
@@ -1,14 +1,16 @@
import spotipy
+from spotipy.oauth2 import SpotifyClientCredentials
import sys
-spotify = spotipy.Spotify()
+client_credentials_manager = SpotifyClientCredentials()
+sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
if len(sys.argv) > 1:
name = ' '.join(sys.argv[1:])
else:
name = 'Radiohead'
-results = spotify.search(q='artist:' + name, type='artist')
+results = sp.search(q='artist:' + name, type='artist')
items = results['artists']['items']
if len(items) > 0:
artist = items[0]
diff --git a/examples/title_chain.py b/examples/title_chain.py
index 67a55c0..6838e22 100644
--- a/examples/title_chain.py
+++ b/examples/title_chain.py
@@ -60,4 +60,4 @@ if __name__ == '__main__':
import sys
title = ' '.join(sys.argv[1:])
make_chain(sys.argv[1].lower())
-
+
diff --git a/examples/user_public_playlists.py b/examples/user_public_playlists.py
index 3557fc3..808be67 100644
--- a/examples/user_public_playlists.py
+++ b/examples/user_public_playlists.py
@@ -1,6 +1,6 @@
# Gets all the public playlists for the given
# user. Uses Client Credentials flow
-#
+#
import sys
import spotipy
diff --git a/examples/user_saved_albums_delete.py b/examples/user_saved_albums_delete.py
new file mode 100644
index 0000000..e1d4bb4
--- /dev/null
+++ b/examples/user_saved_albums_delete.py
@@ -0,0 +1,30 @@
+"""
+ Deletes user saved album
+
+"""
+
+import pprint
+import sys
+import json
+import spotipy
+import spotipy.util as util
+
+if len(sys.argv) > 1:
+ username = sys.argv[1]
+else:
+ print("Usage: %s username" % (sys.argv[0],))
+ sys.exit()
+
+scope = 'user-library-modify'
+token = util.prompt_for_user_token(username, scope)
+
+if token:
+ sp = spotipy.Spotify(auth=token)
+ sp.trace = False
+ uris = input("input a list of album URIs, URLs or IDs: ")
+ uris = list(map(str, uris.split()))
+ deleted = sp.current_user_saved_albums_delete(uris)
+ print("Deletion successful.")
+
+else:
+ print("Can't get token for", username)
diff --git a/requirements.txt b/requirements.txt
index 47f25d8..d674b24 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,4 @@
+mock==2.0.0
requests==2.3.0
+simplejson==3.13.2
six==1.10.0
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 7b81605..97f74fe 100644
--- a/setup.py
+++ b/setup.py
@@ -2,14 +2,17 @@ from setuptools import setup
setup(
name='spotipy',
- version='2.4.4',
- description='simple client for the Spotify Web API',
+ version='2.5.0',
+ long_description="""### A light weight Python library for the Spotify Web API""",
+ long_description_content_type='text/markdown',
author="@plamere",
author_email="paul@echonest.com",
url='http://spotipy.readthedocs.org/',
install_requires=[
+ 'mock>=2.0.0',
'requests>=2.3.0',
'six>=1.10.0',
- ],
+ 'simplejson==3.13.2',
+ ],
license='LICENSE.txt',
packages=['spotipy'])
diff --git a/spotipy/__init__.py b/spotipy/__init__.py
index 9be1dce..b218c0a 100644
--- a/spotipy/__init__.py
+++ b/spotipy/__init__.py
@@ -1,2 +1,5 @@
-VERSION='2.0.1'
-from .client import Spotify, SpotifyException
+VERSION='2.4.5'
+
+from .client import *
+from .oauth2 import *
+from .util import *
diff --git a/spotipy/client.py b/spotipy/client.py
index 3e33a21..273563c 100644
--- a/spotipy/client.py
+++ b/spotipy/client.py
@@ -1,16 +1,21 @@
-# coding: utf-8
+# -*- coding: utf-8 -*-
+""" A simple and thin Python library for the Spotify Web API """
from __future__ import print_function
-import sys
-import requests
+
+__all__ = [
+ 'Spotify',
+ 'SpotifyException'
+]
+
import json
+import sys
import time
+import requests
import six
-""" A simple and thin Python library for the Spotify Web API
-"""
class SpotifyException(Exception):
@@ -55,7 +60,7 @@ class Spotify(object):
def __init__(self, auth=None, requests_session=True,
client_credentials_manager=None, proxies=None, requests_timeout=None):
"""
- Create a Spotify API object.
+ Creates a Spotify API client.
:param auth: An authorization token (optional)
:param requests_session:
@@ -382,6 +387,18 @@ class Spotify(object):
plid = self._get_id('playlist', playlist_id)
return self._get("users/%s/playlists/%s" % (user, plid), fields=fields)
+ def playlist(self, playlist_id, fields=None, market=None):
+ """ Gets playlist by id
+
+ Parameters:
+ - playlist - the id of the playlist
+ - fields - which fields to return
+ - market - An ISO 3166-1 alpha-2 country code or the string from_token.
+ """
+ plid = self._get_id('playlist', playlist_id)
+ return self._get("playlists/%s" % (plid), fields=fields)
+
+
def user_playlist_tracks(self, user, playlist_id=None, fields=None,
limit=100, offset=0, market=None):
""" Get full details of the tracks of a playlist owned by a user.
@@ -507,7 +524,7 @@ class Spotify(object):
Parameters:
- user - the id of the user
- playlist_id - the id of the playlist
- - tracks - the list of track ids to add to the playlist
+ - tracks - the list of track ids to remove from the playlist
- snapshot_id - optional id of the playlist snapshot
"""
@@ -527,9 +544,11 @@ class Spotify(object):
Parameters:
- user - the id of the user
- playlist_id - the id of the playlist
- - tracks - an array of objects containing Spotify URIs of the tracks to remove with their current positions in the playlist. For example:
- [ { "uri":"4iV5W9uYEdYUVa79Axb7Rh", "positions":[2] },
- { "uri":"1301WleyT98MSxVHPZCA6M", "positions":[7] } ]
+ - tracks - an array of objects containing Spotify URIs of the
+ tracks to remove with their current positions in the
+ playlist. For example:
+ [ { "uri":"4iV5W9uYEdYUVa79Axb7Rh", "positions":[2] },
+ { "uri":"1301WleyT98MSxVHPZCA6M", "positions":[7] } ]
- snapshot_id - optional id of the playlist snapshot
"""
@@ -564,7 +583,8 @@ class Spotify(object):
Parameters:
- playlist_owner_id - the user id of the playlist owner
- playlist_id - the id of the playlist
- - user_ids - the ids of the users that you want to check to see if they follow the playlist. Maximum: 5 ids.
+ - user_ids - the ids of the users that you want to check to see
+ if they follow the playlist. Maximum: 5 ids.
"""
return self._get("users/{}/playlists/{}/followers/contains?ids={}".format(playlist_owner_id, playlist_id, ','.join(user_ids)))
@@ -586,17 +606,6 @@ class Spotify(object):
'''
return self._get('me/player/currently-playing')
- def current_user_saved_albums(self, limit=20, offset=0):
- """ Gets a list of the albums saved in the current authorized user's
- "Your Music" library
-
- Parameters:
- - limit - the number of albums to return
- - offset - the index of the first album to return
-
- """
- return self._get('me/albums', limit=limit, offset=offset)
-
def current_user_saved_tracks(self, limit=20, offset=0):
""" Gets a list of the tracks saved in the current authorized user's
"Your Music" library
@@ -612,8 +621,8 @@ class Spotify(object):
""" Gets a list of the artists followed by the current authorized user
Parameters:
- - limit - the number of tracks to return
- - after - ghe last artist ID retrieved from the previous request
+ - limit - the number of artists to return
+ - after - the last artist ID retrieved from the previous request
"""
return self._get('me/following', type='artist', limit=limit,
@@ -686,9 +695,30 @@ class Spotify(object):
Parameters:
- limit - the number of entities to return
- '''
+ '''
return self._get('me/player/recently-played', limit=limit)
+ def current_user_saved_albums(self, limit=20, offset=0):
+ """ Gets a list of the albums saved in the current authorized user's
+ "Your Music" library
+
+ Parameters:
+ - limit - the number of albums to return
+ - offset - the index of the first album to return
+
+ """
+ return self._get('me/albums', limit=limit, offset=offset)
+
+ def current_user_saved_albums_contains(self, albums=[]):
+ """ Check if one or more albums is already saved in
+ the current Spotify user’s “Your Music” library.
+
+ Parameters:
+ - albums - a list of album URIs, URLs or IDs
+ """
+ alist = [self._get_id('album', a) for a in albums]
+ return self._get('me/albums/contains?ids=' + ','.join(alist))
+
def current_user_saved_albums_add(self, albums=[]):
""" Add one or more albums to the current user's
"Your Music" library.
@@ -696,8 +726,17 @@ class Spotify(object):
- albums - a list of album URIs, URLs or IDs
"""
alist = [self._get_id('album', a) for a in albums]
- r = self._put('me/albums?ids=' + ','.join(alist))
- return r
+ return self._put('me/albums?ids=' + ','.join(alist))
+
+ def current_user_saved_albums_delete(self, albums=[]):
+ """ Remove one or more albums from the current user's
+ "Your Music" library.
+
+ Parameters:
+ - albums - a list of album URIs, URLs or IDs
+ """
+ alist = [self._get_id('album', a) for a in albums]
+ return self._delete('me/albums/?ids=' + ','.join(alist))
def user_follow_artists(self, ids=[]):
''' Follow one or more artists
@@ -713,6 +752,20 @@ class Spotify(object):
'''
return self._put('me/following?type=user&ids=' + ','.join(ids))
+ def user_unfollow_artists(self, ids=[]):
+ ''' Unfollow one or more artists
+ Parameters:
+ - ids - a list of artist IDs
+ '''
+ return self._delete('me/following?type=artist&ids=' + ','.join(ids))
+
+ def user_unfollow_users(self, ids=[]):
+ ''' Unfollow one or more users
+ Parameters:
+ - ids - a list of user IDs
+ '''
+ return self._delete('me/following?type=user&ids=' + ','.join(ids))
+
def featured_playlists(self, locale=None, country=None, timestamp=None,
limit=20, offset=0):
""" Get a list of Spotify featured playlists
@@ -869,14 +922,6 @@ class Spotify(object):
else:
return results
- def audio_analysis(self, id):
- """ Get audio analysis for a track based upon its Spotify ID
- Parameters:
- - id - a track URIs, URLs or IDs
- """
- id = self._get_id('track', id)
- return self._get('audio-analysis/'+id)
-
def devices(self):
''' Get a list of user's available devices.
'''
@@ -1040,15 +1085,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)
+ self._warn('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)
+ self._warn('expected id of type %s but found type %s %s' %
+ (type, itype, id))
return fields[-1]
return id
diff --git a/spotipy/oauth2.py b/spotipy/oauth2.py
index cef7908..60fbc1e 100644
--- a/spotipy/oauth2.py
+++ b/spotipy/oauth2.py
@@ -1,11 +1,21 @@
+# -*- coding: utf-8 -*-
from __future__ import print_function
+
+__all__ = [
+ 'is_token_expired',
+ 'SpotifyClientCredentials',
+ 'SpotifyOAuth',
+ 'SpotifyOauthError'
+]
+
import base64
-import requests
-import os
import json
-import time
+import os
import sys
+import time
+
+import requests
# Workaround to support both python 2 & 3
import six
diff --git a/spotipy/util.py b/spotipy/util.py
index 0dd39a9..0bf9fab 100644
--- a/spotipy/util.py
+++ b/spotipy/util.py
@@ -1,15 +1,31 @@
+# -*- coding: utf-8 -*-
-# 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'
+]
+
import os
+
from . import oauth2
+
import spotipy
+CLIENT_CREDS_ENV_VARS = {
+ 'client_id': 'SPOTIPY_CLIENT_ID',
+ 'client_secret': 'SPOTIPY_CLIENT_SECRET',
+ 'client_username': 'SPOTIPY_CLIENT_USERNAME',
+ 'redirect_uri': 'SPOTIPY_REDIRECT_URI'
+}
+
def prompt_for_user_token(username, scope=None, client_id = None,
client_secret = None, redirect_uri = None, cache_path = None):
''' prompts the user to login if necessary and returns
- the user token suitable for use with the spotipy.Spotify
+ the user token suitable for use with the spotipy.Spotify
constructor
Parameters:
@@ -41,13 +57,13 @@ def prompt_for_user_token(username, scope=None, client_id = None,
export SPOTIPY_CLIENT_SECRET='your-spotify-client-secret'
export SPOTIPY_REDIRECT_URI='your-app-redirect-url'
- Get your credentials at
+ Get your credentials at
https://developer.spotify.com/my-applications
''')
raise spotipy.SpotifyException(550, -1, 'no credentials set')
cache_path = cache_path or ".cache-" + username
- sp_oauth = oauth2.SpotifyOAuth(client_id, client_secret, redirect_uri,
+ sp_oauth = oauth2.SpotifyOAuth(client_id, client_secret, redirect_uri,
scope=scope, cache_path=cache_path)
# try to get a valid token for this user, from the cache,
@@ -82,7 +98,7 @@ def prompt_for_user_token(username, scope=None, client_id = None,
response = input("Enter the URL you were redirected to: ")
print()
- print()
+ print()
code = sp_oauth.parse_response_code(response)
token_info = sp_oauth.get_access_token(code)
diff --git a/tests/authtests.py b/tests/authtests.py
deleted file mode 100644
index 13504a6..0000000
--- a/tests/authtests.py
+++ /dev/null
@@ -1,222 +0,0 @@
-# -*- coding: latin-1 -*-
-
-import spotipy
-from spotipy import util
-import unittest
-import pprint
-import sys
-import simplejson as json
-
-'''
- Since these tests require authentication they are maintained
- separately from the other tests.
-
- These tests try to be benign and leave your collection and
- playlists in a relatively stable state.
-'''
-
-class AuthTestSpotipy(unittest.TestCase):
- '''
- These tests require user authentication
- '''
-
- playlist = "spotify:user:plamere:playlist:2oCEWyyAPbZp9xhVSxZavx"
- four_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp",
- "spotify:track:7IHOIqZUUInxjVkko181PB",
- "4VrWlk8IQxevMvERoX08iC",
- "http://open.spotify.com/track/3cySlItpiPiIAzU3NyHCJf"]
-
- two_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp",
- "spotify:track:7IHOIqZUUInxjVkko181PB"]
-
- other_tracks=["spotify:track:2wySlB6vMzCbQrRnNGOYKa",
- "spotify:track:29xKs5BAHlmlX1u4gzQAbJ",
- "spotify:track:1PB7gRWcvefzu7t3LJLUlf"]
-
- bad_id = 'BAD_ID'
-
- def test_track_bad_id(self):
- try:
- track = spotify.track(self.bad_id)
- self.assertTrue(False)
- except spotipy.SpotifyException:
- self.assertTrue(True)
-
-
- def test_basic_user_profile(self):
- user = spotify.user(username)
- self.assertTrue(user['id'] == username)
-
- def test_current_user(self):
- user = spotify.current_user()
- self.assertTrue(user['id'] == username)
-
- def test_me(self):
- user = spotify.me()
- self.assertTrue(user['id'] == username)
-
- def test_user_playlists(self):
- playlists = spotify.user_playlists(username, limit=5)
- self.assertTrue('items' in playlists)
- self.assertTrue(len(playlists['items']) == 5)
-
- def test_user_playlist_tracks(self):
- playlists = spotify.user_playlists(username, limit=5)
- self.assertTrue('items' in playlists)
- for playlist in playlists['items']:
- user = playlist['owner']['id']
- pid = playlist['id']
- results = spotify.user_playlist_tracks(user, pid)
- self.assertTrue(len(results['items']) >= 0)
-
- def user_playlist_tracks(self, user, playlist_id = None, fields=None,
- limit=100, offset=0):
-
- # known API issue currently causes this test to fail
- # the issue is that the API doesn't currently respect the
- # limit paramter
-
- self.assertTrue(len(playlists['items']) == 5)
-
- def test_current_user_saved_tracks(self):
- tracks = spotify.current_user_saved_tracks()
- self.assertTrue(len(tracks['items']) > 0)
-
- def test_current_user_saved_albums(self):
- albums = spotify.current_user_saved_albums()
- self.assertTrue(len(albums['items']) > 0)
-
- def test_current_user_playlists(self):
- playlists = spotify.current_user_playlists(limit=10)
- self.assertTrue('items' in playlists)
- self.assertTrue(len(playlists['items']) == 10)
-
- def test_user_playlist_follow(self):
- spotify.user_playlist_follow_playlist('plamere', '4erXB04MxwRAVqcUEpu30O')
- follows = spotify.user_playlist_is_following('plamere', '4erXB04MxwRAVqcUEpu30O', ['plamere'])
-
- self.assertTrue(len(follows) == 1, 'proper follows length')
- self.assertTrue(follows[0], 'is following')
- spotify.user_playlist_unfollow('plamere', '4erXB04MxwRAVqcUEpu30O')
-
- follows = spotify.user_playlist_is_following('plamere', '4erXB04MxwRAVqcUEpu30O', ['plamere'])
- self.assertTrue(len(follows) == 1, 'proper follows length')
- self.assertFalse(follows[0], 'is no longer following')
-
-
- def test_current_user_save_and_unsave_tracks(self):
- tracks = spotify.current_user_saved_tracks()
- total = tracks['total']
-
- spotify.current_user_saved_tracks_add(self.four_tracks)
-
- tracks = spotify.current_user_saved_tracks()
- new_total = tracks['total']
- self.assertTrue(new_total - total == len(self.four_tracks))
-
- tracks = spotify.current_user_saved_tracks_delete(self.four_tracks)
- tracks = spotify.current_user_saved_tracks()
- new_total = tracks['total']
- self.assertTrue(new_total == total)
-
-
- def test_categories(self):
- response = spotify.categories()
- self.assertTrue(len(response['categories']) > 0)
-
- def test_category_playlists(self):
- response = spotify.categories()
- for cat in response['categories']['items']:
- cat_id = cat['id']
- response = spotify.category_playlists(category_id=cat_id)
- self.assertTrue(len(response['playlists']["items"]) > 0)
-
- def test_new_releases(self):
- response = spotify.new_releases()
- self.assertTrue(len(response['albums']) > 0)
-
- def test_featured_releases(self):
- response = spotify.featured_playlists()
- self.assertTrue(len(response['playlists']) > 0)
-
- def test_current_user_follows(self):
- response = spotify.current_user_followed_artists()
- artists = response['artists']
- self.assertTrue(len(artists['items']) > 0)
-
- def test_current_user_top_tracks(self):
- response = spotify.current_user_top_tracks()
- items = response['items']
- self.assertTrue(len(items) > 0)
-
- def test_current_user_top_artists(self):
- response = spotify.current_user_top_artists()
- items = response['items']
- self.assertTrue(len(items) > 0)
-
- def get_or_create_spotify_playlist(self, username, playlist_name):
- playlists = spotify.user_playlists(username)
- while playlists:
- for item in playlists['items']:
- if item['name'] == playlist_name:
- return item['id']
- playlists = spotify.next(playlists)
- playlist = spotify.user_playlist_create(username, playlist_name)
- playlist_id = playlist['uri']
- return playlist_id
-
- def test_user_playlist_ops(self):
- # create empty playlist
- playlist_id = self.get_or_create_spotify_playlist(username,
- 'spotipy-testing-playlist-1')
-
- # remove all tracks from it
-
- spotify.user_playlist_replace_tracks(username, playlist_id,[])
-
- playlist = spotify.user_playlist(username, playlist_id)
- self.assertTrue(playlist['tracks']['total'] == 0)
- self.assertTrue(len(playlist['tracks']['items']) == 0)
-
- # add tracks to it
-
- spotify.user_playlist_add_tracks(username, playlist_id, self.four_tracks)
- playlist = spotify.user_playlist(username, playlist_id)
- self.assertTrue(playlist['tracks']['total'] == 4)
- self.assertTrue(len(playlist['tracks']['items']) == 4)
-
- # remove two tracks from it
-
- spotify.user_playlist_remove_all_occurrences_of_tracks (username,
- playlist_id, self.two_tracks)
-
- playlist = spotify.user_playlist(username, playlist_id)
- self.assertTrue(playlist['tracks']['total'] == 2)
- self.assertTrue(len(playlist['tracks']['items']) == 2)
-
- # replace with 3 other tracks
- spotify.user_playlist_replace_tracks(username,
- playlist_id, self.other_tracks)
-
- playlist = spotify.user_playlist(username, playlist_id)
- self.assertTrue(playlist['tracks']['total'] == 3)
- self.assertTrue(len(playlist['tracks']['items']) == 3)
-
-if __name__ == '__main__':
- if len(sys.argv) > 1:
- username = sys.argv[1]
- del sys.argv[1]
-
- scope = 'playlist-modify-public '
- scope += 'user-library-read '
- scope += 'user-follow-read '
- scope += 'user-library-modify '
- scope += 'user-read-private '
- scope += 'user-top-read'
-
- token = util.prompt_for_user_token(username, scope)
- spotify = spotipy.Spotify(auth=token)
- spotify.trace = False
- unittest.main()
- else:
- print("Usage: %s username" % (sys.argv[0],))
diff --git a/tests/authtests2.py b/tests/authtests2.py
deleted file mode 100644
index 670e1c8..0000000
--- a/tests/authtests2.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# -*- coding: latin-1 -*-
-
-import spotipy
-from spotipy import util
-import unittest
-import pprint
-import sys
-import simplejson as json
-from spotipy.oauth2 import SpotifyClientCredentials
-
-'''
- Since these tests require authentication they are maintained
- separately from the other tests.
-
- These tests try to be benign and leave your collection and
- playlists in a relatively stable state.
-'''
-
-class AuthTestSpotipy(unittest.TestCase):
- '''
- These tests require user authentication
- '''
-
- playlist = "spotify:user:plamere:playlist:2oCEWyyAPbZp9xhVSxZavx"
- four_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp",
- "spotify:track:7IHOIqZUUInxjVkko181PB",
- "4VrWlk8IQxevMvERoX08iC",
- "http://open.spotify.com/track/3cySlItpiPiIAzU3NyHCJf"]
-
- two_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp",
- "spotify:track:7IHOIqZUUInxjVkko181PB"]
-
- other_tracks=["spotify:track:2wySlB6vMzCbQrRnNGOYKa",
- "spotify:track:29xKs5BAHlmlX1u4gzQAbJ",
- "spotify:track:1PB7gRWcvefzu7t3LJLUlf"]
-
- bad_id = 'BAD_ID'
-
-
- def test_audio_analysis(self):
- result = spotify.audio_analysis(self.four_tracks[0])
- assert('beats' in result)
-
- def test_audio_features(self):
- results = spotify.audio_features(self.four_tracks)
- self.assertTrue(len(results) == len(self.four_tracks))
- for track in results:
- assert('speechiness' in track)
-
- def test_audio_features_with_bad_track(self):
- bad_tracks = []
- bad_tracks = ['spotify:track:bad']
- input = self.four_tracks + bad_tracks
- results = spotify.audio_features(input)
- self.assertTrue(len(results) == len(input))
- for track in results[:-1]:
- if track != None:
- assert('speechiness' in track)
- self.assertTrue(results[-1] == None)
-
- def test_recommendations(self):
- results = spotify.recommendations(seed_tracks=self.four_tracks, min_danceability=0, max_loudness=0, target_popularity=50)
- self.assertTrue(len(results['tracks']) == 20)
-
-
-if __name__ == '__main__':
- client_credentials_manager = SpotifyClientCredentials()
- spotify = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
- spotify.trace = False
- unittest.main()
diff --git a/tests/client_credentials_tests.py b/tests/client_credentials_tests.py
deleted file mode 100644
index 4905062..0000000
--- a/tests/client_credentials_tests.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# -*- coding: latin-1 -*-
-
-import spotipy
-from spotipy.oauth2 import SpotifyClientCredentials
-import unittest
-
-'''
- Client Credentials Requests Tests
-'''
-
-class ClientCredentialsTestSpotipy(unittest.TestCase):
- '''
- These tests require user authentication
- '''
-
- muse_urn = 'spotify:artist:12Chz98pHFMPJEknJQMWvI'
-
- def test_request_with_token(self):
- artist = spotify.artist(self.muse_urn)
- self.assertTrue(artist['name'] == 'Muse')
-
-
-if __name__ == '__main__':
- spotify_cc = SpotifyClientCredentials()
- spotify = spotipy.Spotify(client_credentials_manager=spotify_cc)
- spotify.trace = False
- unittest.main()
diff --git a/tests/test_auth.py b/tests/test_auth.py
new file mode 100644
index 0000000..66e2ab4
--- /dev/null
+++ b/tests/test_auth.py
@@ -0,0 +1,297 @@
+# -*- coding: utf-8 -*-
+
+"""
+These tests require user authentication - provide client credentials using the
+following environment variables
+
+::
+
+ 'SPOTIPY_CLIENT_USERNAME'
+ 'SPOTIPY_CLIENT_ID'
+ 'SPOTIPY_CLIENT_SECRET'
+ 'SPOTIPY_REDIRECT_URI'
+"""
+
+from __future__ import print_function
+
+import os
+from pprint import pprint
+import sys
+import unittest
+
+import simplejson as json
+
+sys.path.insert(0, os.path.abspath(os.pardir))
+
+from spotipy import (
+ CLIENT_CREDS_ENV_VARS as CCEV,
+ prompt_for_user_token,
+ Spotify,
+ SpotifyException,
+)
+
+
+class AuthTestSpotipy(unittest.TestCase):
+ """
+ These tests require user authentication - provide client credentials using the
+ following environment variables
+
+ ::
+
+ 'SPOTIPY_CLIENT_USERNAME'
+ 'SPOTIPY_CLIENT_ID'
+ 'SPOTIPY_CLIENT_SECRET'
+ 'SPOTIPY_REDIRECT_URI'
+ """
+
+ playlist = "spotify:user:plamere:playlist:2oCEWyyAPbZp9xhVSxZavx"
+ playlist_new_id = "spotify:playlist:7GlxpQjjxRjmbb3RP2rDqI"
+ four_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp",
+ "spotify:track:7IHOIqZUUInxjVkko181PB",
+ "4VrWlk8IQxevMvERoX08iC",
+ "http://open.spotify.com/track/3cySlItpiPiIAzU3NyHCJf"]
+
+ two_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp",
+ "spotify:track:7IHOIqZUUInxjVkko181PB"]
+
+ other_tracks=["spotify:track:2wySlB6vMzCbQrRnNGOYKa",
+ "spotify:track:29xKs5BAHlmlX1u4gzQAbJ",
+ "spotify:track:1PB7gRWcvefzu7t3LJLUlf"]
+
+ album_ids = ["spotify:album:6kL09DaURb7rAoqqaA51KU",
+ "spotify:album:6RTzC0rDbvagTSJLlY7AKl"]
+
+ bad_id = 'BAD_ID'
+
+
+ @classmethod
+ def setUpClass(self):
+
+ missing = list(filter(lambda var: not os.getenv(CCEV[var]), CCEV))
+
+ if missing:
+ raise Exception('Please set the client credentials for the test application using the following environment variables: {}'.format(CCEV.values()))
+
+ self.username = os.getenv(CCEV['client_username'])
+
+ self.scope = (
+ 'playlist-modify-public '
+ 'user-library-read '
+ 'user-follow-read '
+ 'user-library-modify '
+ 'user-read-private '
+ 'user-top-read '
+ 'user-follow-modify'
+ )
+
+ self.token = prompt_for_user_token(self.username, scope=self.scope)
+
+ self.spotify = Spotify(auth=self.token)
+
+ def test_track_bad_id(self):
+ try:
+ self.spotify.track(self.bad_id)
+ self.assertTrue(False)
+ except SpotifyException:
+ self.assertTrue(True)
+
+ def test_basic_user_profile(self):
+ user = self.spotify.user(self.username)
+ self.assertTrue(user['id'] == self.username.lower())
+
+ def test_current_user(self):
+ user = self.spotify.current_user()
+ self.assertTrue(user['id'] == self.username.lower())
+
+ def test_me(self):
+ user = self.spotify.me()
+ self.assertTrue(user['id'] == self.username.lower())
+
+ def test_user_playlists(self):
+ playlists = self.spotify.user_playlists(self.username, limit=5)
+ self.assertTrue('items' in playlists)
+ self.assertTrue(len(playlists['items']) == 5)
+
+ def test_user_playlist_tracks(self):
+ playlists = self.spotify.user_playlists(self.username, limit=5)
+ self.assertTrue('items' in playlists)
+ for playlist in playlists['items']:
+ user = playlist['owner']['id']
+ pid = playlist['id']
+ results = self.spotify.user_playlist_tracks(user, pid)
+ self.assertTrue(len(results['items']) >= 0)
+
+ def user_playlist_tracks(self, user, playlist_id = None, fields=None,
+ limit=100, offset=0):
+
+ # known API issue currently causes this test to fail
+ # the issue is that the API doesn't currently respect the
+ # limit parameter
+
+ self.assertTrue(len(playlists['items']) == 5)
+
+ def test_current_user_saved_albums(self):
+ # List
+ albums = self.spotify.current_user_saved_albums()
+ self.assertTrue(len(albums['items']) == 1)
+
+ # Add
+ self.spotify.current_user_saved_albums_add(self.album_ids)
+
+ # Contains
+ self.assertTrue(self.spotify.current_user_saved_albums_contains(self.album_ids) == [True, True])
+
+ # Remove
+ self.spotify.current_user_saved_albums_delete(self.album_ids)
+ albums = self.spotify.current_user_saved_albums()
+ self.assertTrue(len(albums['items']) == 1)
+
+ def test_current_user_playlists(self):
+ playlists = self.spotify.current_user_playlists(limit=10)
+ self.assertTrue('items' in playlists)
+ self.assertTrue(len(playlists['items']) == 10)
+
+ def test_user_playlist_follow(self):
+ self.spotify.user_playlist_follow_playlist('plamere', '4erXB04MxwRAVqcUEpu30O')
+ follows = self.spotify.user_playlist_is_following('plamere', '4erXB04MxwRAVqcUEpu30O', [self.spotify.current_user()['id']])
+
+ self.assertTrue(len(follows) == 1, 'proper follows length')
+ self.assertTrue(follows[0], 'is following')
+ self.spotify.user_playlist_unfollow('plamere', '4erXB04MxwRAVqcUEpu30O')
+
+ follows = self.spotify.user_playlist_is_following('plamere', '4erXB04MxwRAVqcUEpu30O', [self.spotify.current_user()['id']])
+ self.assertTrue(len(follows) == 1, 'proper follows length')
+ self.assertFalse(follows[0], 'is no longer following')
+
+ def test_current_user_saved_tracks(self):
+ tracks = self.spotify.current_user_saved_tracks()
+ self.assertTrue(len(tracks['items']) > 0)
+
+ def test_current_user_save_and_unsave_tracks(self):
+ tracks = self.spotify.current_user_saved_tracks()
+ total = tracks['total']
+ self.spotify.current_user_saved_tracks_add(self.four_tracks)
+
+ tracks = self.spotify.current_user_saved_tracks()
+ new_total = tracks['total']
+ self.assertTrue(new_total - total == len(self.four_tracks))
+
+ tracks = self.spotify.current_user_saved_tracks_delete(self.four_tracks)
+ tracks = self.spotify.current_user_saved_tracks()
+ new_total = tracks['total']
+ self.assertTrue(new_total == total)
+
+ def test_categories(self):
+ response = self.spotify.categories()
+ self.assertTrue(len(response['categories']) > 0)
+
+ def test_category_playlists(self):
+ response = self.spotify.categories()
+ for cat in response['categories']['items']:
+ cat_id = cat['id']
+ response = self.spotify.category_playlists(category_id=cat_id)
+ if len(response['playlists']["items"]) > 0:
+ break
+ self.assertTrue(True)
+
+ def test_new_releases(self):
+ response = self.spotify.new_releases()
+ self.assertTrue(len(response['albums']) > 0)
+
+ def test_featured_releases(self):
+ response = self.spotify.featured_playlists()
+ self.assertTrue(len(response['playlists']) > 0)
+
+ def test_current_user_follows(self):
+ response = self.spotify.current_user_followed_artists()
+ artists = response['artists']
+ self.assertTrue(len(artists['items']) > 0)
+
+ def test_current_user_top_tracks(self):
+ response = self.spotify.current_user_top_tracks()
+ items = response['items']
+ self.assertTrue(len(items) > 0)
+
+ def test_current_user_top_artists(self):
+ response = self.spotify.current_user_top_artists()
+ items = response['items']
+ self.assertTrue(len(items) > 0)
+
+ def get_or_create_spotify_playlist(self, playlist_name):
+ playlists = self.spotify.user_playlists(self.username)
+ while playlists:
+ for item in playlists['items']:
+ if item['name'] == playlist_name:
+ return item['id']
+ playlists = self.spotify.next(playlists)
+ playlist = self.spotify.user_playlist_create(self.username, playlist_name)
+ playlist_id = playlist['uri']
+ return playlist_id
+
+ def test_user_playlist_ops(self):
+ # create empty playlist
+ playlist_id = self.get_or_create_spotify_playlist('spotipy-testing-playlist-1')
+
+ # remove all tracks from it
+ self.spotify.user_playlist_replace_tracks(self.username, playlist_id,[])
+ playlist = self.spotify.user_playlist(self.username, playlist_id)
+ self.assertTrue(playlist['tracks']['total'] == 0)
+ self.assertTrue(len(playlist['tracks']['items']) == 0)
+
+ # add tracks to it
+ self.spotify.user_playlist_add_tracks(self.username, playlist_id, self.four_tracks)
+ playlist = self.spotify.user_playlist(self.username, playlist_id)
+ self.assertTrue(playlist['tracks']['total'] == 4)
+ self.assertTrue(len(playlist['tracks']['items']) == 4)
+
+ # remove two tracks from it
+ self.spotify.user_playlist_remove_all_occurrences_of_tracks (self.username,
+ playlist_id, self.two_tracks)
+ playlist = self.spotify.user_playlist(self.username, playlist_id)
+ self.assertTrue(playlist['tracks']['total'] == 2)
+ self.assertTrue(len(playlist['tracks']['items']) == 2)
+
+ # replace with 3 other tracks
+ self.spotify.user_playlist_replace_tracks(self.username,
+ playlist_id, self.other_tracks)
+ playlist = self.spotify.user_playlist(self.username, playlist_id)
+ self.assertTrue(playlist['tracks']['total'] == 3)
+ self.assertTrue(len(playlist['tracks']['items']) == 3)
+
+ def test_playlist(self):
+ # New playlist ID
+ pl = self.spotify.playlist(self.playlist_new_id)
+ self.assertTrue(pl["tracks"]["total"] > 0)
+
+ # Old playlist ID
+ pl = self.spotify.playlist(self.playlist)
+ self.assertTrue(pl["tracks"]["total"] > 0)
+
+ def test_user_follows_and_unfollows_artist(self):
+ # Initially follows 1 artist
+ res = self.spotify.current_user_followed_artists()
+ self.assertTrue(res['artists']['total'] == 1)
+
+ # Follow 2 more artists
+ artists = ["6DPYiyq5kWVQS4RGwxzPC7", "0NbfKEOTQCcwd6o7wSDOHI"]
+ self.spotify.user_follow_artists(artists)
+ res = self.spotify.current_user_followed_artists()
+ self.assertTrue(res['artists']['total'] == 3)
+
+ # Unfollow these 2 artists
+ self.spotify.user_unfollow_artists(artists)
+ res = self.spotify.current_user_followed_artists()
+ self.assertTrue(res['artists']['total'] == 1)
+
+ def test_user_follows_and_unfollows_user(self):
+ # TODO improve after implementing `me/following/contains`
+ users = ["11111204", "xlqeojt6n7on0j7coh9go8ifd"]
+
+ # Follow 2 more users
+ self.spotify.user_follow_users(users)
+
+ # Unfollow these 2 users
+ self.spotify.user_unfollow_users(users)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_auth2.py b/tests/test_auth2.py
new file mode 100644
index 0000000..e52092a
--- /dev/null
+++ b/tests/test_auth2.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+
+"""
+These tests require user authentication - provide client credentials using the
+following environment variables
+
+::
+
+ 'SPOTIPY_CLIENT_USERNAME'
+ 'SPOTIPY_CLIENT_ID'
+ 'SPOTIPY_CLIENT_SECRET'
+ 'SPOTIPY_REDIRECT_URI'
+"""
+
+import os
+import pprint
+import sys
+import unittest
+
+import simplejson as json
+
+sys.path.insert(0, os.path.abspath(os.pardir))
+
+from spotipy import (
+ Spotify,
+ SpotifyClientCredentials,
+)
+
+
+class AuthTestSpotipy(unittest.TestCase):
+ """
+ These tests require user authentication - provide client credentials using the
+ following environment variables
+
+ ::
+
+ 'SPOTIPY_CLIENT_USERNAME'
+ 'SPOTIPY_CLIENT_ID'
+ 'SPOTIPY_CLIENT_SECRET'
+ 'SPOTIPY_REDIRECT_URI'
+ """
+
+ playlist = "spotify:user:plamere:playlist:2oCEWyyAPbZp9xhVSxZavx"
+ four_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp",
+ "spotify:track:7IHOIqZUUInxjVkko181PB",
+ "4VrWlk8IQxevMvERoX08iC",
+ "http://open.spotify.com/track/3cySlItpiPiIAzU3NyHCJf"]
+
+ two_tracks = ["spotify:track:6RtPijgfPKROxEzTHNRiDp",
+ "spotify:track:7IHOIqZUUInxjVkko181PB"]
+
+ other_tracks=["spotify:track:2wySlB6vMzCbQrRnNGOYKa",
+ "spotify:track:29xKs5BAHlmlX1u4gzQAbJ",
+ "spotify:track:1PB7gRWcvefzu7t3LJLUlf"]
+
+ bad_id = 'BAD_ID'
+
+ @classmethod
+ def setUpClass(self):
+ self.spotify = Spotify(client_credentials_manager=SpotifyClientCredentials())
+ self.spotify.trace = False
+
+ def test_audio_analysis(self):
+ result = self.spotify.audio_analysis(self.four_tracks[0])
+ assert('beats' in result)
+
+ def test_audio_features(self):
+ results = self.spotify.audio_features(self.four_tracks)
+ self.assertTrue(len(results) == len(self.four_tracks))
+ for track in results:
+ assert('speechiness' in track)
+
+ def test_audio_features_with_bad_track(self):
+ bad_tracks = []
+ bad_tracks = ['spotify:track:bad']
+ input = self.four_tracks + bad_tracks
+ results = self.spotify.audio_features(input)
+ self.assertTrue(len(results) == len(input))
+ for track in results[:-1]:
+ if track != None:
+ assert('speechiness' in track)
+ self.assertTrue(results[-1] == None)
+
+ def test_recommendations(self):
+ results = self.spotify.recommendations(seed_tracks=self.four_tracks, min_danceability=0, max_loudness=0, target_popularity=50)
+ self.assertTrue(len(results['tracks']) == 20)
+
+
+if __name__ == '__main__':
+
+ unittest.main()
diff --git a/tests/test_client_credentials.py b/tests/test_client_credentials.py
new file mode 100644
index 0000000..a3b7103
--- /dev/null
+++ b/tests/test_client_credentials.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+""" Client Credentials Requests Tests """
+
+import os
+import sys
+import unittest
+
+sys.path.insert(0, os.path.abspath(os.pardir))
+
+from spotipy import (
+ Spotify,
+ SpotifyClientCredentials,
+)
+
+
+class ClientCredentialsTestSpotipy(unittest.TestCase):
+ """
+ These tests require user authentication - provide client credentials using the
+ following environment variables
+
+ ::
+
+ 'SPOTIPY_CLIENT_USERNAME'
+ 'SPOTIPY_CLIENT_ID'
+ 'SPOTIPY_CLIENT_SECRET'
+ 'SPOTIPY_REDIRECT_URI'
+ """
+
+ @classmethod
+ def setUpClass(self):
+ self.spotify = Spotify(client_credentials_manager=SpotifyClientCredentials())
+ self.spotify.trace = False
+
+ muse_urn = 'spotify:artist:12Chz98pHFMPJEknJQMWvI'
+
+ def test_request_with_token(self):
+ artist = self.spotify.artist(self.muse_urn)
+ self.assertTrue(artist['name'] == 'Muse')
+
+
+if __name__ == '__main__':
+
+ unittest.main()
diff --git a/tests/test_oauth.py b/tests/test_oauth.py
index 1871b60..0c18ef1 100644
--- a/tests/test_oauth.py
+++ b/tests/test_oauth.py
@@ -1,8 +1,15 @@
-from spotipy.oauth2 import SpotifyOAuth
-import json
+# -*- coding: utf-8 -*-
+
import io
+import json
+import os
+import sys
import unittest
+sys.path.insert(0, os.path.abspath(os.pardir))
+
+from spotipy import SpotifyOAuth
+
try:
import unittest.mock as mock
except ImportError:
@@ -166,4 +173,5 @@ class TestSpotifyOAuth(unittest.TestCase):
if __name__ == '__main__':
+
unittest.main()
diff --git a/tests/tests.py b/tests/tests.py
index 760b91c..4cd90df 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -1,13 +1,36 @@
-# -*- coding: latin-1 -*-
-import spotipy
-import unittest
+# -*- coding: utf-8 -*-
+
+import os
import pprint
+import sys
+import unittest
+
import requests
-from spotipy.client import SpotifyException
+
+sys.path.insert(0, os.path.abspath(os.pardir))
+
+from spotipy import (
+ CLIENT_CREDS_ENV_VARS as CCEV,
+ prompt_for_user_token,
+ Spotify,
+ SpotifyException,
+)
class TestSpotipy(unittest.TestCase):
+ """
+ These tests require user authentication - provide client credentials using the
+ following environment variables
+
+ ::
+
+ 'SPOTIPY_CLIENT_USERNAME'
+ 'SPOTIPY_CLIENT_ID'
+ 'SPOTIPY_CLIENT_SECRET'
+ 'SPOTIPY_REDIRECT_URI'
+ """
+
creep_urn = 'spotify:track:3HfB5hBU0dmBt8T0iCmH42'
creep_id = '3HfB5hBU0dmBt8T0iCmH42'
creep_url = 'http://open.spotify.com/track/3HfB5hBU0dmBt8T0iCmH42'
@@ -22,8 +45,20 @@ class TestSpotipy(unittest.TestCase):
bad_id = 'BAD_ID'
- def setUp(self):
- self.spotify = spotipy.Spotify()
+ @classmethod
+ def setUpClass(self):
+ missing = list(filter(lambda var: not os.getenv(CCEV[var]), CCEV))
+
+ if missing:
+ raise Exception('Please set the client credentials for the test application using the following environment variables: {}'.format(CCEV.values()))
+
+ self.username = os.getenv(CCEV['client_username'])
+
+ self.scope = 'user-library-read'
+
+ self.token = prompt_for_user_token(self.username, scope=self.scope)
+
+ self.spotify = Spotify(auth=self.token)
def test_artist_urn(self):
artist = self.spotify.artist(self.radiohead_urn)
@@ -41,7 +76,7 @@ class TestSpotipy(unittest.TestCase):
def test_album_tracks(self):
results = self.spotify.album_tracks(self.pinkerton_urn)
self.assertTrue(len(results['items']) == 10)
-
+
def test_album_tracks_many(self):
results = self.spotify.album_tracks(self.angeles_haydn_urn)
tracks = results['items']
@@ -74,7 +109,7 @@ class TestSpotipy(unittest.TestCase):
try:
track = self.spotify.track(self.el_scorcho_bad_urn)
self.assertTrue(False)
- except spotipy.SpotifyException:
+ except SpotifyException:
self.assertTrue(True)
def test_tracks(self):
@@ -121,11 +156,11 @@ class TestSpotipy(unittest.TestCase):
self.assertTrue(found)
def test_search_timeout(self):
- sp = spotipy.Spotify(requests_timeout=.1)
+ sp = Spotify(auth=self.token, requests_timeout=.01)
try:
results = sp.search(q='my*', type='track')
self.assertTrue(False, 'unexpected search timeout')
- except requests.ReadTimeout:
+ except requests.Timeout:
self.assertTrue(True, 'expected search timeout')
@@ -149,14 +184,14 @@ class TestSpotipy(unittest.TestCase):
try:
track = self.spotify.track(self.bad_id)
self.assertTrue(False)
- except spotipy.SpotifyException:
+ except SpotifyException:
self.assertTrue(True)
def test_track_bad_id(self):
try:
track = self.spotify.track(self.bad_id)
self.assertTrue(False)
- except spotipy.SpotifyException:
+ except SpotifyException:
self.assertTrue(True)
def test_unauthenticated_post_fails(self):
@@ -166,20 +201,17 @@ class TestSpotipy(unittest.TestCase):
cm.exception.http_status == 403)
def test_custom_requests_session(self):
- from requests import Session
- sess = Session()
+ sess = requests.Session()
sess.headers["user-agent"] = "spotipy-test"
- with_custom_session = spotipy.Spotify(requests_session=sess)
+ with_custom_session = Spotify(auth=self.token, requests_session=sess)
self.assertTrue(with_custom_session.user(user="akx")["uri"] == "spotify:user:akx")
def test_force_no_requests_session(self):
- from requests import Session
- with_no_session = spotipy.Spotify(requests_session=False)
- self.assertFalse(isinstance(with_no_session._session, Session))
+ with_no_session = Spotify(auth=self.token, requests_session=False)
+ self.assertFalse(isinstance(with_no_session._session, requests.Session))
self.assertTrue(with_no_session.user(user="akx")["uri"] == "spotify:user:akx")
-
'''
Need tests for:
@@ -188,4 +220,5 @@ class TestSpotipy(unittest.TestCase):
'''
if __name__ == '__main__':
+
unittest.main()
diff --git a/tox.ini b/tox.ini
index e3af7ee..dcbdb72 100644
--- a/tox.ini
+++ b/tox.ini
@@ -3,6 +3,7 @@ envlist = py27,py34
[testenv]
deps=
requests
+ simplejson
six
py27: mock
-commands=python -m unittest discover tests
+commands=python -m unittest discover -v tests