15

I'm trying to pull all tracks in a certain playlist using the Spotipy library for python.

The user_playlist_tracks function is limited to 100 tracks, regardless of the parameter limit. The Spotipy documentation describes it as:

user_playlist_tracks(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.

Parameters:

  • user
  • the id of the user playlist_id
  • the id of the playlist fields
  • which fields to return limit
  • the maximum number of tracks to return offset
  • the index of the first track to return market
  • an ISO 3166-1 alpha-2 country code.

After authenticating with Spotify, I'm currently using something like this:

username = xxxx
playlist = #fromspotipy
sp_playlist = sp.user_playlist_tracks(username, playlist_id=playlist)
tracks = sp_playlist['items']
print tracks

Is there a way to return more than 100 tracks? I've tried setting the limit=None in the function parameters, but it returns an error.

gestalt
  • 153
  • 1
  • 2
  • 7

6 Answers6

39

Many of the spotipy methods return paginated results, so you will have to scroll through them to view more than just the max limit. I've encountered this most often when collecting a playlist's full track listing and consequently created a custom method to handle this:

def get_playlist_tracks(username,playlist_id):
    results = sp.user_playlist_tracks(username,playlist_id)
    tracks = results['items']
    while results['next']:
        results = sp.next(results)
        tracks.extend(results['items'])
    return tracks
ackleyrc
  • 506
  • 3
  • 3
3

I wrote a function that can output Panda's DataFrame where it pulls all the metadata (not all of it because I didn't want to, but you can make some space for that) for playlists over 100 songs. I do it by iterating over every song, finding the metadata for each, saving the metadata to a dictionary, and then concatenating the dictionary to the DataFrame. It takes your username and the Playlist ID as input.

# Function to extract MetaData from a playlist thats longer than 100 songs
def get_playlist_tracks_more_than_100_songs(username, playlist_id):
    results = sp.user_playlist_tracks(username,playlist_id)
    tracks = results['items']
    while results['next']:
        results = sp.next(results)
        tracks.extend(results['items'])
    results = tracks    

    playlist_tracks_id = []
    playlist_tracks_titles = []
    playlist_tracks_artists = []
    playlist_tracks_first_artists = []
    playlist_tracks_first_release_date = []
    playlist_tracks_popularity = []

    for i in range(len(results)):
        print(i) # Counter
        if i == 0:
            playlist_tracks_id = results[i]['track']['id']
            playlist_tracks_titles = results[i]['track']['name']
            playlist_tracks_first_release_date = results[i]['track']['album']['release_date']
            playlist_tracks_popularity = results[i]['track']['popularity']

            artist_list = []
            for artist in results[i]['track']['artists']:
                artist_list= artist['name']
            playlist_tracks_artists = artist_list

            features = sp.audio_features(playlist_tracks_id)
            features_df = pd.DataFrame(data=features, columns=features[0].keys())
            features_df['title'] = playlist_tracks_titles
            features_df['all_artists'] = playlist_tracks_artists
            features_df['popularity'] = playlist_tracks_popularity
            features_df['release_date'] = playlist_tracks_first_release_date
            features_df = features_df[['id', 'title', 'all_artists', 'popularity', 'release_date',
                                       'danceability', 'energy', 'key', 'loudness',
                                       'mode', 'acousticness', 'instrumentalness',
                                       'liveness', 'valence', 'tempo',
                                       'duration_ms', 'time_signature']]
            continue
        else:
            try:
                playlist_tracks_id = results[i]['track']['id']
                playlist_tracks_titles = results[i]['track']['name']
                playlist_tracks_first_release_date = results[i]['track']['album']['release_date']
                playlist_tracks_popularity = results[i]['track']['popularity']
                artist_list = []
                for artist in results[i]['track']['artists']:
                    artist_list= artist['name']
                playlist_tracks_artists = artist_list
                features = sp.audio_features(playlist_tracks_id)
                new_row = {'id':[playlist_tracks_id],
               'title':[playlist_tracks_titles],
               'all_artists':[playlist_tracks_artists],
               'popularity':[playlist_tracks_popularity],
               'release_date':[playlist_tracks_first_release_date],
               'danceability':[features[0]['danceability']],
               'energy':[features[0]['energy']],
               'key':[features[0]['key']],
               'loudness':[features[0]['loudness']],
               'mode':[features[0]['mode']],
               'acousticness':[features[0]['acousticness']],
               'instrumentalness':[features[0]['instrumentalness']],
               'liveness':[features[0]['liveness']],
               'valence':[features[0]['valence']],
               'tempo':[features[0]['tempo']],
               'duration_ms':[features[0]['duration_ms']],
               'time_signature':[features[0]['time_signature']]
               }

                dfs = [features_df, pd.DataFrame(new_row)]
                features_df = pd.concat(dfs, ignore_index = True)
            except:
                continue
                
    return features_df
RiveN
  • 2,595
  • 11
  • 13
  • 26
sfnxboy
  • 31
  • 3
2

Another way around it would be to write a for loop and do:

offset +=100

then you could concatenate the tracks at the end, or put them in a data frame. Function Ref:

playlist_tracks(playlist_id, fields=None, limit=100, offset=0, market=None)

Reference: https://spotipy.readthedocs.io/en/2.7.0/#spotipy.client.Spotify.playlist_tracks

0

Below is the user_playlist_tracks module used in spotipy. (notice it defaults to 100 limit).

Try setting the limit to 200.

def user_playlist_tracks(self, user, playlist_id = None,   fields=None,
    limit=100, offset=0):
    ''' Get full details of the tracks of a playlist owned by a user.

        Parameters:
            - user - the id of the user
            - playlist_id - the id of the playlist
            - fields - which fields to return
            - limit - the maximum number of tracks to return
            - offset - the index of the first track to return
    '''
    plid = self._get_id('playlist', playlist_id)
    return self._get("users/%s/playlists/%s/tracks" % (user, plid),
                limit=limit, offset=offset, fields=fields)
Rob Jarvis
  • 356
  • 1
  • 4
  • 13
  • 1
    Anything over 100 results in this error: `spotipy.client.SpotifyException: http status: 400, code:-1 - https://api.spotify.com/v1/users/im.nick.hello/playlists/7lArr0TzHvKoEsj6cotHqZ/tracks?limit=200&offset=0: Invalid limit` – gestalt Aug 23 '16 at 00:10
  • 1
    @NickBecker check out this link from the spotify web API. https://developer.spotify.com/web-api/get-playlist/ You'll need to make use of the `offset` key within the paging object. In my post above you can see that the code allows for the `offset` parameter. You'll have to make multiple calls to the API, adjusting the offset for each call. – Rob Jarvis Aug 23 '16 at 13:17
0

When trying the above solutions I got key error messages. I eventually figured it out. Here is my solution. This is only for displaying tracks/artists on the next pages.

id = "5lrkIjzukk65X4ksulpA0H?si=9db60a70278a4fd6"

results = sp.playlist_items(id)
tracks = results['tracks']
next_pages = 14
track_list = []

for i in range(next_pages):
    tracks = sp.next(tracks)
    for y in range(0,100):
        try:
            track = tracks['items'][y]['track']['name']
            artist = tracks['items'][y]['track']['artists'][0]['name']
            track_list.append(artist)
        except:
            continue

print(track_list)
0

It's unfortunate SpotiPy makes their API Access to complicated. Try using SpotifyR in r, and you can accomplish this in a few lines of code. No loops, lists, extra variables, or appending required. Then just pop it back into python if you'd like.

library(spotifyr)
df <- get_playlist_audio_features('playlist_owner_username', 'playlist_uri')

And boom, you're done. I'm not sure what the max is, but I know it's over 300 songs because I have pulled that in.

Anurag A S
  • 725
  • 10
  • 23