Adventures in Spotipy

Isn’t it a bummer that Spotify’s Wrapped only comes once a year?

Well, turns out they offer something that is nearly as good; Spotify Web API Endpoints. You can get basic information like track name, artist name and track popularity, as well as somewhat more obscure information found in “audio analysis.”

For my forthcoming analysis, I wanted to get the audio information for tracks on public Spotify playlists. Pretty simple to do, with Spotipy, a Python library you can read about here. A Google search shows several Medium articles explaining how to do just that–the Spotipy website is also a great resource.

However, to get to the real meaty data (i.e. personal data), I found the process a bit more complex. It became necessary to utilize the Client Authorization Code Flow rather than the Client Credentials Flow. For that, I had to set my credentials (so to speak) as environment variables. I found that the export Python command wasn’t quite doing it for me, so I found a little workaround:

import spotipy
import os
os.environ['SPOTIPY_CLIENT_ID']='CLIENT'
os.environ['SPOTIPY_CLIENT_SECRET']='SECRET'
os.environ['SPOTIPY_REDIRECT_URI']='https://localhost:808/callback/'

Where CLIENT and SECRET were my actual IDs. I found my top, medium-range (approx. 6 months) artists first:

import spotipy
from spotipy.oauth2 import SpotifyOAuth

scope = 'user-top-read'
ranges = 'medium_term'

sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))

sp_range = 'medium_term'

results = sp.current_user_top_artists(time_range=sp_range, limit=50)

The first time I ran through this code, my browser opened up a new window (thanks redirect URL!) to authenticate my request. Nothing appeared on my browser window, but the key is the URL itself. Text will appear that says:

Enter the URL you were redirected to:

Where you will simply paste said URL. From there comes the fun stuff. The Client Authorization Code Flow is meant for long-term authorization, meaning I’ve only ever had to do this once when I was running this all using my simple Mac terminal. I was having issues actually getting this flow to work when I was working in the Jupyter Notebook environment I had set up using Docker, which is something I hope to work out in the future.

The next bit is the fun part; I actually get my medium-term top artists:

for i, item in enumerate(results['items']):
    print(i, item['name'])

Which returns:

0 The Rolling Stones
1 Beck
2 Whitney
3 Tears For Fears
4 Coldplay
5 Joni Mitchell
6 John Mulaney
7 Phoenix
8 Cold War Kids
9 The Black Keys
10 The Lumineers
11 Phoebe Bridgers
12 The Killers
13 The Shins
14 John Mayer
15 Chris Stapleton
16 fun.
17 Jim Gaffigan
18 The Velvet Underground
19 Talking Heads
20 Carole King
21 Zac Brown Band
22 Wallows
23 Mumford & Sons
24 Neil Young
25 Tame Impala
26 Oasis
27 Miley Cyrus
28 The Flaming Lips
29 Glass Animals
30 Modest Mouse
31 Arcade Fire
32 Vampire Weekend
33 MGMT
34 The Head and the Heart
35 Shakey Graves
36 NEU!
37 Foster The People
38 Neutral Milk Hotel
39 The Avett Brothers
40 The B-52's
41 Tyler Childers
42 Alabama Shakes
43 Cage The Elephant
44 The Neighbourhood
45 The Strokes
46 The Beatles
47 David Bowie
48 Grateful Dead
49 U2

The index starts at 0, so these are my whole top 50 artists. Next, I was interested in my top 50 songs in the medium term. Same basic principle, slightly different code. I was also interested in capturing the artist name for each song as well as Spotify’s given “popularity” of each song, on a scale of 0-100.

import spotipy
from spotipy.oauth2 import SpotifyOAuth

scope = 'user-top-read'
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))

sp_range = 'medium_term'

results = sp.current_user_top_tracks(time_range=sp_range, limit=50)
for i, item in enumerate(results['items']):
        print(i,'//', 'popularity:', item['popularity'], '//', item['name'], '//', item['artists'][0]['name'])

The results:

0 // popularity: 71 // Once in a Lifetime - 2005 Remaster // Talking Heads
1 // popularity: 79 // Paint It, Black // The Rolling Stones
2 // popularity: 50 // In The City - From "The Warriors" Soundtrack // Joe Walsh
3 // popularity: 75 // Sympathy For The Devil - 50th Anniversary Edition // The Rolling Stones
4 // popularity: 63 // Hang Me Up To Dry // Cold War Kids
5 // popularity: 63 // I Fought the Law // The Clash
6 // popularity: 59 // I'm Waiting For The Man // The Velvet Underground
7 // popularity: 68 // My Generation - Stereo Version // The Who
8 // popularity: 63 // She's Not There // The Zombies
9 // popularity: 70 // Perfect Day // Lou Reed
10 // popularity: 58 // Laid // James
11 // popularity: 22 // Take Me Home, Country Roads (ft. Waxahatchee) // Whitney
12 // popularity: 67 // In the Aeroplane Over the Sea // Neutral Milk Hotel
13 // popularity: 79 // Tennessee Whiskey // Chris Stapleton
14 // popularity: 80 // Heat Waves // Glass Animals
15 // popularity: 69 // Pinball Wizard // The Who
16 // popularity: 73 // Lonely Boy // The Black Keys
17 // popularity: 56 // The Start Of Something // Voxtrot
18 // popularity: 46 // Lady Jane - Mono Version // The Rolling Stones
19 // popularity: 71 // Shout // Tears For Fears
20 // popularity: 50 // Can We Hang On ? // Cold War Kids
21 // popularity: 61 // Love Is The Drug // Roxy Music
22 // popularity: 33 // Saw Lightning - Freestyle // Beck
23 // popularity: 64 // My Own Soul’s Warning // The Killers
24 // popularity: 36 // High And Dry // The Rolling Stones
25 // popularity: 74 // Psycho Killer - 2005 Remaster // Talking Heads
26 // popularity: 69 // Social Cues // Cage The Elephant
27 // popularity: 46 // Shark Attack // Grouplove
28 // popularity: 70 // Never Going Back Again - 2004 Remaster // Fleetwood Mac
29 // popularity: 31 // Hammond Song // Whitney
30 // popularity: 43 // Off The Record // My Morning Jacket
31 // popularity: 38 // Suffer For Fashion // of Montreal
32 // popularity: 41 // Stupid Girl // The Rolling Stones
33 // popularity: 57 // She's So Cold - Remastered // The Rolling Stones
34 // popularity: 46 // Out Of Time // The Rolling Stones
35 // popularity: 66 // Revolution - Remastered 2009 // The Beatles
36 // popularity: 57 // Wars // Of Monsters and Men
37 // popularity: 54 // Meet Me in the City // The Black Keys
38 // popularity: 50 // I'll Be Your Man // The Black Keys
39 // popularity: 53 // Crimson & Clover - Single Version // Tommy James & The Shondells
40 // popularity: 74 // The Gambler // Kenny Rogers
41 // popularity: 65 // Under My Thumb // The Rolling Stones
42 // popularity: 62 // Marcel // Her's
43 // popularity: 59 // Neighborhood #1 (Tunnels) // Arcade Fire
44 // popularity: 48 // Is It Real - Acoustic // Bombay Bicycle Club
45 // popularity: 38 // Doncha Bother Me // The Rolling Stones
46 // popularity: 38 // Once Around the Block // Badly Drawn Boy
47 // popularity: 37 // Flight 505 // The Rolling Stones
48 // popularity: 50 // Such Great Heights - Remastered // The Postal Service
49 // popularity: 41 // Your Sweet Touch // Bahamas

Special thanks to this GitHub repository; it’s got a ton of code for getting user and other data from Spotify. What are the next steps? Well, for satisfying my curiosity, this suffices. However, in the future I can definitely see myself wanting to do more with this data; for example, grabbing the track IDs as well and looping through those to get Spotify’s audio analysis data to create my own little dataframe.

Leave a comment