%%capture
!pip install spotipy
36 The Spotify API
In this notebook we will fetch and process music data from Spotify, using the Spotify API.
Specifically we will lookup and display the top tracks for any given artist.
36.1 Setup
Sometimes when working with an API we will fetch data directly, using a web request. However in other cases there might be a Python package that can help make our lives easier, especially when there are complicated authorization steps involved.
For this demo, we will use the spotipy
package, which provides a high level interface into the Spotify API.
Installing the spotipy
package into the notebook environment:
Ensuring the package has been installed:
!pip list | grep spotipy
spotipy 2.25.1
To interface with the Spotify API, you need to create a Spotify API Client application, with corresponding credentials (i.e. the “client identifier” and “client secret”).
Before proceeding, set these credentials as notebook secrets called SPOTIPY_CLIENT_ID
and SPOTIPY_CLIENT_SECRET
, respectively.
Accessing the credentials from notebook secrets:
from google.colab import userdata
= userdata.get("SPOTIPY_CLIENT_ID")
SPOTIPY_CLIENT_ID = userdata.get("SPOTIPY_CLIENT_SECRET") SPOTIPY_CLIENT_SECRET
Initializing a new Spotify API client, using the provided credentials:
from spotipy import Spotify
from spotipy.oauth2 import SpotifyClientCredentials
= SpotifyClientCredentials(
creds =SPOTIPY_CLIENT_ID,
client_id=SPOTIPY_CLIENT_SECRET
client_secret
)
= Spotify(client_credentials_manager=creds)
client print("CLIENT:", type(client))
CLIENT: <class 'spotipy.client.Spotify'>
The client
object will allow us to make various requests to the API.
36.2 Example: Artist Top Tracks
To get the top tracks for a given artist, we will use the client
object’s artist_top_tracks
method, which issues a request to the Spotify API’s Artist Top Tracks endpoint.
Since this request requires us to supply the official Spotify identifier of a given artist, we’ll need to first get the artist idenfier, and then get their top tracks.
Selecting an artist name:
= input("Please choose an artist: ")
artist_name artist_name
Please choose an artist: Dua Lipa
'Dua Lipa'
Getting the official Spotify identifier for the given artist (assuming the first artist is the closest match):
= client.search(q=artist_name, type='artist', limit=1)
artist_response artist_response
{'artists': {'href': 'https://api.spotify.com/v1/search?offset=0&limit=1&query=Dua%20Lipa&type=artist',
'limit': 1,
'next': 'https://api.spotify.com/v1/search?offset=1&limit=1&query=Dua%20Lipa&type=artist',
'offset': 0,
'previous': None,
'total': 804,
'items': [{'external_urls': {'spotify': 'https://open.spotify.com/artist/6M2wZ9GZgrQXHCFfjv46we'},
'followers': {'href': None, 'total': 46530425},
'genres': ['pop'],
'href': 'https://api.spotify.com/v1/artists/6M2wZ9GZgrQXHCFfjv46we',
'id': '6M2wZ9GZgrQXHCFfjv46we',
'images': [{'url': 'https://i.scdn.co/image/ab6761610000e5eb0c68f6c95232e716f0abee8d',
'height': 640,
'width': 640},
{'url': 'https://i.scdn.co/image/ab676161000051740c68f6c95232e716f0abee8d',
'height': 320,
'width': 320},
{'url': 'https://i.scdn.co/image/ab6761610000f1780c68f6c95232e716f0abee8d',
'height': 160,
'width': 160}],
'name': 'Dua Lipa',
'popularity': 89,
'type': 'artist',
'uri': 'spotify:artist:6M2wZ9GZgrQXHCFfjv46we'}]}}
Parsing the response data:
= artist_response["artists"]["items"][0]
artist artist
{'external_urls': {'spotify': 'https://open.spotify.com/artist/6M2wZ9GZgrQXHCFfjv46we'},
'followers': {'href': None, 'total': 46530425},
'genres': ['pop'],
'href': 'https://api.spotify.com/v1/artists/6M2wZ9GZgrQXHCFfjv46we',
'id': '6M2wZ9GZgrQXHCFfjv46we',
'images': [{'url': 'https://i.scdn.co/image/ab6761610000e5eb0c68f6c95232e716f0abee8d',
'height': 640,
'width': 640},
{'url': 'https://i.scdn.co/image/ab676161000051740c68f6c95232e716f0abee8d',
'height': 320,
'width': 320},
{'url': 'https://i.scdn.co/image/ab6761610000f1780c68f6c95232e716f0abee8d',
'height': 160,
'width': 160}],
'name': 'Dua Lipa',
'popularity': 89,
'type': 'artist',
'uri': 'spotify:artist:6M2wZ9GZgrQXHCFfjv46we'}
Displaying information about the artist, including their unique identifier:
from IPython.display import Image, display
= artist['followers']['total']
followers = artist["images"][0]["url"]
image_url
print("ARTIST:", artist["name"])
print("ID:", artist["id"])
print("POPULARITY:", artist["popularity"])
print(f"FOLLOWERS: {followers:,}")
print("GENRES:", artist["genres"])
=image_url, height=200)) display(Image(url
ARTIST: Dua Lipa
ID: 6M2wZ9GZgrQXHCFfjv46we
POPULARITY: 89
FOLLOWERS: 46,530,425
GENRES: ['pop']
Fetching the artist’s top tracks (given their official Spotify artist identifier):
= artist["id"]
artist_id = client.artist_top_tracks(artist_id)
tracks_response print(type(tracks_response))
tracks_response.keys()
<class 'dict'>
dict_keys(['tracks'])
Exploring and processing the response data:
= tracks_response["tracks"]
top_tracks print(type(top_tracks))
len(top_tracks)
<class 'list'>
10
It looks like the API returned information about ten tracks. Investigating the structure of one of the tracks:
= top_tracks[0]
track type(track)
dict
track.keys()
dict_keys(['album', 'artists', 'available_markets', 'disc_number', 'duration_ms', 'explicit', 'external_ids', 'external_urls', 'href', 'id', 'is_local', 'is_playable', 'name', 'popularity', 'preview_url', 'track_number', 'type', 'uri'])
from datetime import timedelta
from IPython.display import Image, display
= [artist["name"] for artist in track["artists"]]
artist_names
= int(track['duration_ms'] / 1000)
duration_s = timedelta(seconds=duration_s)
track_duration
print(f"TRACK: '{track['name']}'")
print("ARTIST NAME(S):", artist_names)
print(f"ALBUM: '{track['album']['name']}'")
print("RELEASE DATE:", track["album"]["release_date"])
print("DURATION:", str(track_duration))
print("MARKETS:", len(track["available_markets"]))
print("POPULARITY SCORE:", track["popularity"])
= track["album"]["images"][0]["url"]
album_img_url =album_img_url, width=200)) display(Image(url
TRACK: 'New Rules'
ARTIST NAME(S): ['Dua Lipa']
ALBUM: 'Dua Lipa (Deluxe)'
RELEASE DATE: 2017-06-02
DURATION: 0:03:29
MARKETS: 179
POPULARITY SCORE: 81
Sorting the top tracks in order of their popularity:
from operator import itemgetter
= sorted(top_tracks, key=itemgetter("popularity"), reverse=True) top_tracks
Looping through the top tracks to display the name and popularity score of each:
for i, track in enumerate(top_tracks):
print(i+1, track["name"], "|", track["popularity"])
1 Don't Start Now | 82
2 Levitating (feat. DaBaby) | 81
3 New Rules | 81
4 Houdini | 81
5 Dance The Night - From Barbie The Album | 80
6 Levitating | 80
7 IDGAF | 78
8 Training Season | 77
9 One Kiss (with Dua Lipa) | 76
10 Cold Heart - PNAU Remix | 69
Alright, we did it!
Getting an artist’s top tracks is just one capability of the Spotify API.
After reading through more of the spotipy
package documentation, what other capabilities are you interested in exploring?