2014-08-22 15:00:29 +00:00
|
|
|
|
.. image:: images/spotify-web-api-doc.jpg
|
|
|
|
|
:width: 100 %
|
|
|
|
|
|
2014-08-22 15:48:12 +00:00
|
|
|
|
Welcome to Spotipy!
|
2014-08-21 15:08:32 +00:00
|
|
|
|
===================================
|
2014-08-22 15:00:29 +00:00
|
|
|
|
*Spotipy* is a lightweight Python library for the `Spotify Web API
|
|
|
|
|
<https://developer.spotify.com/web-api/>`_. With *Spotipy*
|
2014-08-22 13:28:19 +00:00
|
|
|
|
you get full access to all of the music data provided by the Spotify platform.
|
2014-08-21 15:08:32 +00:00
|
|
|
|
|
2014-08-22 15:00:29 +00:00
|
|
|
|
Here's a quick example of using *Spotipy* to list the names of all the albums
|
2014-08-22 13:28:19 +00:00
|
|
|
|
released by the artist 'Birdy'::
|
2014-08-21 15:08:32 +00:00
|
|
|
|
|
2014-08-22 13:28:19 +00:00
|
|
|
|
import spotipy
|
|
|
|
|
|
|
|
|
|
birdy_uri = 'spotify:artist:2WX2uTcsvV5OnS0inACecP'
|
|
|
|
|
spotify = spotipy.Spotify()
|
|
|
|
|
|
|
|
|
|
results = spotify.artist_albums(birdy_uri, album_type='album')
|
|
|
|
|
albums = results['items']
|
|
|
|
|
while results['next']:
|
|
|
|
|
results = spotify.next(results)
|
|
|
|
|
albums.extend(results['items'])
|
|
|
|
|
|
|
|
|
|
for album in albums:
|
|
|
|
|
print(album['name'])
|
|
|
|
|
|
|
|
|
|
Here's another example showing how to get 30 second samples and cover art
|
|
|
|
|
for the top 10 tracks for Led Zeppelin::
|
|
|
|
|
|
|
|
|
|
import spotipy
|
|
|
|
|
|
|
|
|
|
lz_uri = 'spotify:artist:36QJpDe2go2KgaRleHCDTp'
|
|
|
|
|
|
|
|
|
|
spotify = spotipy.Spotify()
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
Finally, here's an example that will get the URL for an artist image given the
|
|
|
|
|
artist's name::
|
|
|
|
|
|
|
|
|
|
import spotipy
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
spotify = spotipy.Spotify()
|
|
|
|
|
|
|
|
|
|
if len(sys.argv) > 1:
|
|
|
|
|
name = ' '.join(sys.argv[1:])
|
|
|
|
|
else:
|
|
|
|
|
name = 'Radiohead'
|
|
|
|
|
|
|
|
|
|
results = spotify.search(q='artist:' + name, type='artist')
|
|
|
|
|
items = results['artists']['items']
|
|
|
|
|
if len(items) > 0:
|
|
|
|
|
artist = items[0]
|
|
|
|
|
print artist['name'], artist['images'][0]['url']
|
2014-08-21 15:08:32 +00:00
|
|
|
|
|
2014-08-21 17:57:19 +00:00
|
|
|
|
|
|
|
|
|
Features
|
|
|
|
|
========
|
2014-08-22 13:28:19 +00:00
|
|
|
|
*Spotipy* supports all of the features of the Spotify Web API including access
|
2014-08-22 15:00:29 +00:00
|
|
|
|
to all end points, and support for user authorization. For details on the
|
|
|
|
|
capabilities you are encouraged to review the `Spotify Web
|
|
|
|
|
API <https://developer.spotify.com/web-api/>`_ documentation.
|
2014-08-21 17:57:19 +00:00
|
|
|
|
|
|
|
|
|
Installation
|
|
|
|
|
============
|
2014-08-22 15:00:29 +00:00
|
|
|
|
Install *Spotipy* with::
|
2014-08-22 13:28:19 +00:00
|
|
|
|
|
2014-08-25 21:30:31 +00:00
|
|
|
|
pip install spotipy
|
2014-08-22 13:28:19 +00:00
|
|
|
|
|
|
|
|
|
Or with::
|
|
|
|
|
|
2014-08-25 21:30:31 +00:00
|
|
|
|
easy_install spotipy
|
2014-08-22 13:28:19 +00:00
|
|
|
|
|
|
|
|
|
Or you can get the source from github at https://github.com/plamere/spotipy
|
2014-08-21 17:57:19 +00:00
|
|
|
|
|
|
|
|
|
Getting Started
|
|
|
|
|
===============
|
|
|
|
|
|
2014-08-22 15:00:29 +00:00
|
|
|
|
Non-Authorized requests
|
2014-08-22 16:59:43 +00:00
|
|
|
|
=======================
|
2014-08-22 15:00:29 +00:00
|
|
|
|
For methods that do not require authorization, simply create a Spotify object
|
|
|
|
|
and start making method calls like so::
|
2014-08-22 13:28:19 +00:00
|
|
|
|
|
|
|
|
|
import spotipy
|
|
|
|
|
spotify = spotipy.Spotify()
|
|
|
|
|
results = spotify.search(q='artist:' + name, type='artist')
|
|
|
|
|
print results
|
|
|
|
|
|
2014-08-22 15:00:29 +00:00
|
|
|
|
Authorized requests
|
2014-08-22 16:59:43 +00:00
|
|
|
|
=======================
|
2014-08-22 13:28:19 +00:00
|
|
|
|
Many methods require user authentication. For these requests you will need to
|
|
|
|
|
generate an authorization token that indicates that the user has granted
|
2014-08-22 15:00:29 +00:00
|
|
|
|
permission for your application to perform the given task. You will need to
|
|
|
|
|
register your app to get the credentials necessary to make authorized calls.
|
2015-10-31 15:59:04 +00:00
|
|
|
|
|
|
|
|
|
Even if your script does not have an accessible URL you need to specify one
|
|
|
|
|
when registering your application where the spotify authentication API will
|
|
|
|
|
redirect to after successful login. The URL doesn't need to work or be
|
|
|
|
|
accessible, you can specify "http://localhost/", after successful login you
|
|
|
|
|
just need to copy the "http://localhost/?code=..." URL from your browser
|
|
|
|
|
and paste it to the console where your script is running.
|
|
|
|
|
|
2014-08-22 15:00:29 +00:00
|
|
|
|
Register your app at
|
|
|
|
|
`My Applications
|
|
|
|
|
<https://developer.spotify.com/my-applications/#!/applications>`_.
|
|
|
|
|
|
|
|
|
|
|
2016-12-31 14:33:09 +00:00
|
|
|
|
*spotipy* supports two authorization flows:
|
|
|
|
|
|
|
|
|
|
- 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
|
|
|
|
|
to authenticate your requests to the Spotify Web API and to obtain
|
|
|
|
|
a higher rate limit than you would
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Authorization Code Flow
|
|
|
|
|
=======================
|
|
|
|
|
To support the **Authorization Code Flow** *Spotipy* provides a
|
2014-08-22 13:28:19 +00:00
|
|
|
|
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,
|
|
|
|
|
or if you are reluctant to immortalize your app credentials in your source code,
|
|
|
|
|
you can set environment variables like so::
|
|
|
|
|
|
2014-08-22 15:00:29 +00:00
|
|
|
|
export SPOTIPY_CLIENT_ID='your-spotify-client-id'
|
|
|
|
|
export SPOTIPY_CLIENT_SECRET='your-spotify-client-secret'
|
|
|
|
|
export SPOTIPY_REDIRECT_URI='your-app-redirect-url'
|
2014-08-22 13:28:19 +00:00
|
|
|
|
|
|
|
|
|
Call ``util.prompt_for_user_token`` method with the username and the
|
|
|
|
|
desired scope (see `Using
|
|
|
|
|
Scopes <https://developer.spotify.com/web-api/using-scopes/>`_ for information
|
|
|
|
|
about scopes) and credentials. This will coordinate the user authorization via
|
2015-10-31 15:59:04 +00:00
|
|
|
|
your web browser and ask for the SPOTIPY_REDIRECT_URI you were redirected to
|
|
|
|
|
with the authorization token appended. The credentials are cached locally and
|
|
|
|
|
are used to automatically re-authorized expired tokens.
|
2014-08-22 13:28:19 +00:00
|
|
|
|
|
2014-08-22 15:00:29 +00:00
|
|
|
|
Here's an example of getting user authorization to read a user's saved tracks::
|
2014-08-22 13:28:19 +00:00
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
import spotipy
|
|
|
|
|
import spotipy.util as util
|
|
|
|
|
|
|
|
|
|
scope = 'user-library-read'
|
|
|
|
|
|
|
|
|
|
if len(sys.argv) > 1:
|
|
|
|
|
username = sys.argv[1]
|
|
|
|
|
else:
|
|
|
|
|
print "Usage: %s username" % (sys.argv[0],)
|
|
|
|
|
sys.exit()
|
|
|
|
|
|
|
|
|
|
token = util.prompt_for_user_token(username, scope)
|
|
|
|
|
|
|
|
|
|
if token:
|
|
|
|
|
sp = spotipy.Spotify(auth=token)
|
|
|
|
|
results = sp.current_user_saved_tracks()
|
|
|
|
|
for item in results['items']:
|
|
|
|
|
track = item['track']
|
|
|
|
|
print track['name'] + ' - ' + track['artists'][0]['name']
|
|
|
|
|
else:
|
|
|
|
|
print "Can't get token for", username
|
|
|
|
|
|
2016-12-31 14:33:09 +00:00
|
|
|
|
Client Credentials Flow
|
|
|
|
|
=======================
|
|
|
|
|
To support the **Client Credentials Flow** *Spotipy* provides a
|
|
|
|
|
class SpotifyClientCredentials that can be used to authenticate requests like so::
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import spotipy
|
|
|
|
|
from spotipy.oauth2 import SpotifyClientCredentials
|
|
|
|
|
|
|
|
|
|
client_credentials_manager = SpotifyClientCredentials()
|
|
|
|
|
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
|
|
|
|
|
|
|
|
|
|
playlists = sp.user_playlists('spotify')
|
|
|
|
|
while playlists:
|
|
|
|
|
for i, playlist in enumerate(playlists['items']):
|
|
|
|
|
print("%4d %s %s" % (i + 1 + playlists['offset'], playlist['uri'], playlist['name']))
|
|
|
|
|
if playlists['next']:
|
|
|
|
|
playlists = sp.next(playlists)
|
|
|
|
|
else:
|
|
|
|
|
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
|
|
|
|
|
|
2014-08-22 15:00:29 +00:00
|
|
|
|
IDs URIs and URLs
|
2014-08-22 16:59:43 +00:00
|
|
|
|
=======================
|
2014-08-22 15:00:29 +00:00
|
|
|
|
*Spotipy* supports a number of different ID types:
|
|
|
|
|
|
|
|
|
|
- Spotify URI - The resource identifier that you can enter, for example, in
|
|
|
|
|
the Spotify Desktop client's search box to locate an artist, album, or
|
|
|
|
|
track. Example: spotify:track:6rqhFgbbKwnb9MLmUQDhG6
|
|
|
|
|
- Spotify URL - An HTML link that opens a track, album, app, playlist or other
|
|
|
|
|
Spotify resource in a Spotify client. Example:
|
|
|
|
|
http://open.spotify.com/track/6rqhFgbbKwnb9MLmUQDhG6
|
|
|
|
|
- Spotify ID - A base-62 number that you can find at the end of the Spotify
|
|
|
|
|
URI (see above) for an artist, track, album, etc. Example:
|
|
|
|
|
6rqhFgbbKwnb9MLmUQDhG6
|
|
|
|
|
|
|
|
|
|
In general, any *Spotipy* method that needs an artist, album, track or playlist ID
|
|
|
|
|
will accept ids in any of the above form
|
|
|
|
|
|
2014-08-22 15:48:12 +00:00
|
|
|
|
Examples
|
2014-08-22 16:36:18 +00:00
|
|
|
|
========
|
2014-08-22 15:48:12 +00:00
|
|
|
|
Here are a few more examples of using *Spotipy*.
|
|
|
|
|
|
|
|
|
|
Add tracks to a playlist::
|
|
|
|
|
|
|
|
|
|
import pprint
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Shows the contents of every playlist owned by a user::
|
|
|
|
|
|
|
|
|
|
# shows a user's playlists (need to be authenticated via oauth)
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
import spotipy
|
|
|
|
|
import spotipy.util as util
|
|
|
|
|
|
2016-05-08 10:01:05 +00:00
|
|
|
|
def show_tracks(tracks):
|
2014-08-22 15:48:12 +00:00
|
|
|
|
for i, item in enumerate(tracks['items']):
|
|
|
|
|
track = item['track']
|
|
|
|
|
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]"
|
|
|
|
|
sys.exit()
|
|
|
|
|
|
|
|
|
|
token = util.prompt_for_user_token(username)
|
|
|
|
|
|
|
|
|
|
if token:
|
|
|
|
|
sp = spotipy.Spotify(auth=token)
|
|
|
|
|
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'],
|
|
|
|
|
fields="tracks,next")
|
|
|
|
|
tracks = results['tracks']
|
|
|
|
|
show_tracks(tracks)
|
|
|
|
|
while tracks['next']:
|
|
|
|
|
tracks = sp.next(tracks)
|
|
|
|
|
show_tracks(tracks)
|
|
|
|
|
else:
|
|
|
|
|
print "Can't get token for", username
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
More Examples
|
2014-08-22 16:59:43 +00:00
|
|
|
|
=======================
|
2014-08-22 15:48:12 +00:00
|
|
|
|
There are many more examples of how to use *Spotipy* in the `Examples
|
|
|
|
|
Directory <https://github.com/plamere/spotipy/tree/master/examples>`_ on Github
|
|
|
|
|
|
2014-08-22 15:00:29 +00:00
|
|
|
|
API Reference
|
|
|
|
|
==============
|
2014-08-22 13:28:19 +00:00
|
|
|
|
|
|
|
|
|
:mod:`client` Module
|
2014-08-22 16:59:43 +00:00
|
|
|
|
=======================
|
2014-08-22 13:28:19 +00:00
|
|
|
|
|
|
|
|
|
.. automodule:: spotipy.client
|
|
|
|
|
:members:
|
|
|
|
|
:undoc-members:
|
2016-06-20 14:30:15 +00:00
|
|
|
|
:special-members: __init__
|
2014-08-22 13:28:19 +00:00
|
|
|
|
:show-inheritance:
|
|
|
|
|
|
|
|
|
|
:mod:`oauth2` Module
|
2014-08-22 16:59:43 +00:00
|
|
|
|
=======================
|
2014-08-22 13:28:19 +00:00
|
|
|
|
|
|
|
|
|
.. automodule:: spotipy.oauth2
|
|
|
|
|
:members:
|
|
|
|
|
:undoc-members:
|
2016-06-20 14:30:15 +00:00
|
|
|
|
:special-members: __init__
|
2014-08-22 13:28:19 +00:00
|
|
|
|
:show-inheritance:
|
|
|
|
|
|
|
|
|
|
:mod:`util` Module
|
2014-08-22 16:36:18 +00:00
|
|
|
|
--------------------
|
2014-08-22 13:28:19 +00:00
|
|
|
|
|
|
|
|
|
.. automodule:: spotipy.util
|
|
|
|
|
:members:
|
|
|
|
|
:undoc-members:
|
2016-06-20 14:30:15 +00:00
|
|
|
|
:special-members: __init__
|
2014-08-22 13:28:19 +00:00
|
|
|
|
:show-inheritance:
|
|
|
|
|
|
|
|
|
|
|
2014-08-21 17:57:19 +00:00
|
|
|
|
Support
|
|
|
|
|
=======
|
2014-08-22 15:48:12 +00:00
|
|
|
|
You can ask questions about Spotipy on Stack Overflow. Don’t forget to add the
|
|
|
|
|
*Spotipy* tag, and any other relevant tags as well, before posting.
|
|
|
|
|
|
|
|
|
|
http://stackoverflow.com/questions/ask
|
|
|
|
|
|
|
|
|
|
If you think you've found a bug, let us know at
|
|
|
|
|
`Spotify Issues <https://github.com/plamere/spotipy/issues>`_
|
|
|
|
|
|
2014-08-21 17:57:19 +00:00
|
|
|
|
|
|
|
|
|
Contribute
|
|
|
|
|
==========
|
2014-08-22 15:48:12 +00:00
|
|
|
|
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
|
2014-08-25 21:41:21 +00:00
|
|
|
|
- Steve Winton // swinton
|
2014-08-22 15:48:12 +00:00
|
|
|
|
- Tim Balzer // timbalzer
|
|
|
|
|
- corycorycory // corycorycory
|
2014-08-21 17:57:19 +00:00
|
|
|
|
|
|
|
|
|
License
|
|
|
|
|
=======
|
2014-08-22 15:48:12 +00:00
|
|
|
|
https://github.com/plamere/spotipy/blob/master/LICENSE.txt
|
2014-08-21 15:08:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Indices and tables
|
|
|
|
|
==================
|
|
|
|
|
|
|
|
|
|
* :ref:`genindex`
|
|
|
|
|
* :ref:`modindex`
|
|
|
|
|
* :ref:`search`
|
|
|
|
|
|