[GH-ISSUE #396] Offset field not working for user_playlist_tracks(), wrong response back #234

Closed
opened 2026-02-27 23:21:32 +03:00 by kerem · 22 comments
Owner

Originally created by @AndrewKassab on GitHub (Oct 10, 2019).
Original GitHub issue: https://github.com/spotipy-dev/spotipy/issues/396

I'm getting an odd issue where I'm not retrieving the response that I'm expecting when calling user_playlist_tracks() to retrieve tracks from a playlist. I still retrieve the songs, but the paging object I receive back is incorrect, which is also preventing the 'limit' and 'offset' field from being set correctly, since they are now located in the 'track' object that gets returned.

According to the spotify docs: https://developer.spotify.com/documentation/web-api/reference/playlists/get-playlists-tracks/

I should be receiving a paging object like such:

{
  "href": "",
  "items": [ ],
  "limit": 0,
  "next": "",
  "offset": 0,
  "previous": "",
  "total" 0
}

Instead, I am receiving this:

{ 
  "collaborative": False,
  "description": "",
  "external_urls": {},
  "followers": {},
  "href": "",
  "id": "",
  "images": [],
  "name": "",
  "owner": {},
  "primary_color": null,
  "public": False
  "snapshot_id": "",
  "tracks": {},
  "type": "",
  "uri": "",
  "len": 0
}

Where the tracks object contains the paging object that I am actually expecting according to the Spotify docs above.

I am aware that this used to work properly since I have previously implemented code to retrieve all the tracks from my playlists, but for some reason, the response I'm getting back now with identical code is different. I'm not sure if this is something that has changed on Spotipy's end or the Spotify API.

Originally created by @AndrewKassab on GitHub (Oct 10, 2019). Original GitHub issue: https://github.com/spotipy-dev/spotipy/issues/396 I'm getting an odd issue where I'm not retrieving the response that I'm expecting when calling user_playlist_tracks() to retrieve tracks from a playlist. I still retrieve the songs, but the paging object I receive back is incorrect, which is also preventing the 'limit' and 'offset' field from being set correctly, since they are now located in the 'track' object that gets returned. According to the spotify docs: https://developer.spotify.com/documentation/web-api/reference/playlists/get-playlists-tracks/ I should be receiving a paging object like such: ``` { "href": "", "items": [ ], "limit": 0, "next": "", "offset": 0, "previous": "", "total" 0 } ``` Instead, I am receiving this: ``` { "collaborative": False, "description": "", "external_urls": {}, "followers": {}, "href": "", "id": "", "images": [], "name": "", "owner": {}, "primary_color": null, "public": False "snapshot_id": "", "tracks": {}, "type": "", "uri": "", "len": 0 } ``` Where the `tracks` object contains the paging object that I am actually *expecting* according to the Spotify docs above. I am aware that this used to work properly since I have previously implemented code to retrieve all the tracks from my playlists, but for some reason, the response I'm getting back now with identical code is different. I'm not sure if this is something that has changed on Spotipy's end or the Spotify API.
kerem closed this issue 2026-02-27 23:21:32 +03:00
Author
Owner

@stephanebruckert commented on GitHub (Jan 12, 2020):

Hi, I am correctly receiving something like:

{
  "href": "",
  "items": [ ],
  "limit": 0,
  "next": "",
  "offset": 0,
  "previous": "",
  "total" 0
}

Are you using any fields filter? Closing for now but feel free to re-open with your code.

<!-- gh-comment-id:573406287 --> @stephanebruckert commented on GitHub (Jan 12, 2020): Hi, I am correctly receiving something like: ``` { "href": "", "items": [ ], "limit": 0, "next": "", "offset": 0, "previous": "", "total" 0 } ``` Are you using any fields filter? Closing for now but feel free to re-open with your code.
Author
Owner

@stephanebruckert commented on GitHub (Jan 16, 2020):

I just found what happened.

github.com/plamere/spotipy@6da643e8c1/spotipy/client.py (L393)

It looks like you've used user_playlist (not user_playlist_tracks) without playlist_id. When no playlist id is passed, it used to return your "starred playlist" by default. If that endpoint still responds successfully, most fields are empty because these starred playlists have been removed and have become "liked songs".

Anyway, you should now use playlist(playlist_id) or playlist_tracks(playlist_id)

<!-- gh-comment-id:575384770 --> @stephanebruckert commented on GitHub (Jan 16, 2020): I just found what happened. https://github.com/plamere/spotipy/blob/6da643e8c16dd1d45dc9a9c452c2a73937b18515/spotipy/client.py#L393 It looks like you've used `user_playlist` (not `user_playlist_tracks`) without `playlist_id`. When no playlist id is passed, it used to return your "starred playlist" by default. If that endpoint still responds successfully, most fields are empty because these starred playlists have been removed and have become "liked songs". Anyway, you should now use `playlist(playlist_id)` or `playlist_tracks(playlist_id)`
Author
Owner

@AndrewKassab commented on GitHub (Feb 12, 2020):

Still having the same issue. This is my code:

track_ids = set()

for playlist_id in source_playlist_ids:
    response = sp.playlist_tracks(playlist_id, fields='tracks')
    playlist_tracks = response['tracks']['items']
    while len(playlist_tracks) < response['tracks']['total']:
        response = sp.playlist_tracks(playlist_id,
                                           offset=len(playlist_tracks), fields='tracks')
        playlist_tracks.extend(response['tracks']['items'])
    for item in playlist_tracks:
        track_ids.add(item['track']['id'])

For the given playlist I am testing, response['tracks']['total'] is 699. Every iteration of the while loop is increasing the offset field by another 100, but the offset field never gets set in the playlist_tracks() call. I've followed your advice and used playlist_tracks instead of user_playlist_tracks, but now I just get a response like such.

{ 
    "tracks": { }
}

On one hand I got rid of the irrelevant fields, but on the other hand I still can't get the offset field within the tracks object to get set to anything but 0, and continuously receive the first 100 songs over and over.

Any idea why?? @stephanebruckert

<!-- gh-comment-id:585453515 --> @AndrewKassab commented on GitHub (Feb 12, 2020): Still having the same issue. This is my code: ``` track_ids = set() for playlist_id in source_playlist_ids: response = sp.playlist_tracks(playlist_id, fields='tracks') playlist_tracks = response['tracks']['items'] while len(playlist_tracks) < response['tracks']['total']: response = sp.playlist_tracks(playlist_id, offset=len(playlist_tracks), fields='tracks') playlist_tracks.extend(response['tracks']['items']) for item in playlist_tracks: track_ids.add(item['track']['id']) ``` For the given playlist I am testing, response['tracks']['total'] is 699. Every iteration of the while loop is increasing the offset field by another 100, but the offset field never gets set in the playlist_tracks() call. I've followed your advice and used playlist_tracks instead of user_playlist_tracks, but now I just get a response like such. ``` { "tracks": { } } ``` On one hand I got rid of the irrelevant fields, but on the other hand I still can't get the offset field within the tracks object to get set to anything but 0, and continuously receive the first 100 songs over and over. Any idea why?? @stephanebruckert
Author
Owner

@stephanebruckert commented on GitHub (Feb 12, 2020):

Hey @AndrewKassab. In your code you should have used items instead of tracks (see doc). I just added an example that uses playlist_tracks https://github.com/plamere/spotipy/blob/master/examples/playlist_tracks.py

<!-- gh-comment-id:585464736 --> @stephanebruckert commented on GitHub (Feb 12, 2020): Hey @AndrewKassab. In your code you should have used `items` instead of `tracks` (see [doc](https://developer.spotify.com/documentation/web-api/reference/playlists/get-playlists-tracks/)). I just added an example that uses `playlist_tracks` https://github.com/plamere/spotipy/blob/master/examples/playlist_tracks.py
Author
Owner

@AndrewKassab commented on GitHub (Feb 12, 2020):

@stephanebruckert

I've followed your advice and made the change, but now all I receive is an empty dictionary / object. I copied your example exactly and received the same response from the playlist_tracks call.

I can't get items because items is inside tracks, and playlist_tracks is returning the parent object containing tracks, and not the tracks object itself....

Is this working on your end? Because I'm very confused. A previous app that I had coded, to use the exact same code to receive all songs from a playlist, stopped working as well with no changes from me and I have no clue why.

<!-- gh-comment-id:585467073 --> @AndrewKassab commented on GitHub (Feb 12, 2020): @stephanebruckert I've followed your advice and made the change, but now all I receive is an empty dictionary / object. I copied your example exactly and received the same response from the playlist_tracks call. I can't get items because items is inside tracks, and playlist_tracks is returning the parent object containing tracks, and not the tracks object itself.... Is this working on your end? Because I'm very confused. A previous app that I had coded, to use the exact same code to receive all songs from a playlist, stopped working as well with no changes from me and I have no clue why.
Author
Owner

@stephanebruckert commented on GitHub (Feb 12, 2020):

Yeah it works for me. For playlist_tracks there is no "tracks" field in the response.

get-playlist has "items" in "tracks" but get-playlist-tracks only has "items".

<!-- gh-comment-id:585469276 --> @stephanebruckert commented on GitHub (Feb 12, 2020): Yeah it works for me. For `playlist_tracks` there is no "tracks" field in the response. [get-playlist](https://developer.spotify.com/documentation/web-api/reference/playlists/get-playlist/) has "items" in "tracks" but [get-playlist-tracks](https://developer.spotify.com/documentation/web-api/reference/playlists/get-playlists-tracks/) only has "items".
Author
Owner

@stephanebruckert commented on GitHub (Feb 12, 2020):

So https://github.com/plamere/spotipy/blob/master/examples/playlist_tracks.py does not work for you? What result do you get?

Please also make sure that you are using the latest version:

pip install spotipy --upgrade
<!-- gh-comment-id:585470040 --> @stephanebruckert commented on GitHub (Feb 12, 2020): So https://github.com/plamere/spotipy/blob/master/examples/playlist_tracks.py does not work for you? What result do you get? Please also make sure that you are using the latest version: pip install spotipy --upgrade
Author
Owner

@AndrewKassab commented on GitHub (Feb 12, 2020):

@stephanebruckert

It does work in your code. Even after the first call to playlist_tracks(playlist_id, fields='items.track.id, total'), when debugging the response is just an empty dictionary.

Could this be a scope or setup issue? Check if you get the chance here

https://github.com/AndrewKassab/Playlist-Sync/blob/master/sync_playlist.py

<!-- gh-comment-id:585473167 --> @AndrewKassab commented on GitHub (Feb 12, 2020): @stephanebruckert It does work in your code. Even after the first call to playlist_tracks(playlist_id, fields='items.track.id, total'), when debugging the response is just an empty dictionary. Could this be a scope or setup issue? Check if you get the chance here https://github.com/AndrewKassab/Playlist-Sync/blob/master/sync_playlist.py
Author
Owner

@AndrewKassab commented on GitHub (Feb 12, 2020):

Just pushed the new code with new fields parameter set

<!-- gh-comment-id:585473652 --> @AndrewKassab commented on GitHub (Feb 12, 2020): Just pushed the new code with new fields parameter set
Author
Owner

@stephanebruckert commented on GitHub (Feb 12, 2020):

You are still looking for the tracks field that does not exist. Please start from the example and adapt it to your needs

<!-- gh-comment-id:585473931 --> @stephanebruckert commented on GitHub (Feb 12, 2020): You are still looking for the `tracks` field that does not exist. Please start from the example and adapt it to your needs
Author
Owner

@AndrewKassab commented on GitHub (Feb 12, 2020):

Sorry. Check now.
@stephanebruckert

<!-- gh-comment-id:585474035 --> @AndrewKassab commented on GitHub (Feb 12, 2020): Sorry. Check now. @stephanebruckert
Author
Owner

@AndrewKassab commented on GitHub (Feb 12, 2020):

When debugging at line 31. Response is empty. Dictionary with length 0

<!-- gh-comment-id:585474131 --> @AndrewKassab commented on GitHub (Feb 12, 2020): When debugging at line 31. Response is empty. Dictionary with length 0
Author
Owner

@stephanebruckert commented on GitHub (Feb 12, 2020):

Yeah. As explained in https://github.com/plamere/spotipy/issues/396#issuecomment-585469276, tracks does not exist for the endpoint you are using.

github.com/AndrewKassab/Playlist-Sync@b8db8958a2/sync_playlist.py (L31)

<!-- gh-comment-id:585474411 --> @stephanebruckert commented on GitHub (Feb 12, 2020): Yeah. As explained in https://github.com/plamere/spotipy/issues/396#issuecomment-585469276, `tracks` does not exist for the endpoint you are using. https://github.com/AndrewKassab/Playlist-Sync/blob/b8db8958a28f176af4ca38cef8654942d871b432/sync_playlist.py#L31
Author
Owner

@AndrewKassab commented on GitHub (Feb 12, 2020):

I'm confused. Like I said I am now calling response = sp.playlist_tracks(playlist_id, fields='items.track.id, total')

And when debugging after this call, response is set to an empty dictionary.

<!-- gh-comment-id:585475075 --> @AndrewKassab commented on GitHub (Feb 12, 2020): I'm confused. Like I said I am now calling response = sp.playlist_tracks(playlist_id, fields='items.track.id, total') And when debugging after this call, response is set to an empty dictionary.
Author
Owner

@stephanebruckert commented on GitHub (Feb 12, 2020):

Ok I see,

source_playlist_ids = ['3nWTj1ZAdLJXNiaLdMUOwj?si=0THwLcT5SDujFJhKt5aYIw']

Your playlist ID here should be 3nWTj1ZAdLJXNiaLdMUOwj

<!-- gh-comment-id:585475262 --> @stephanebruckert commented on GitHub (Feb 12, 2020): Ok I see, source_playlist_ids = ['3nWTj1ZAdLJXNiaLdMUOwj?si=0THwLcT5SDujFJhKt5aYIw'] Your playlist ID here should be `3nWTj1ZAdLJXNiaLdMUOwj`
Author
Owner

@AndrewKassab commented on GitHub (Feb 12, 2020):

@stephanebruckert
nice! You're a legend haha. Thanks a ton

<!-- gh-comment-id:585475643 --> @AndrewKassab commented on GitHub (Feb 12, 2020): @stephanebruckert nice! You're a legend haha. Thanks a ton
Author
Owner

@AndrewKassab commented on GitHub (Feb 12, 2020):

Any explanation as to why it still returned the playlist, but not in the same format?

<!-- gh-comment-id:585475766 --> @AndrewKassab commented on GitHub (Feb 12, 2020): Any explanation as to why it still returned the playlist, but not in the same format?
Author
Owner

@stephanebruckert commented on GitHub (Feb 12, 2020):

You mean an empty {}? Not sure, this has probably more to do with https://github.com/spotify/web-api/. This library is just stupidly returning what Spotify returns

<!-- gh-comment-id:585476057 --> @stephanebruckert commented on GitHub (Feb 12, 2020): You mean an empty `{}`? Not sure, this has probably more to do with https://github.com/spotify/web-api/. This library is just stupidly returning what Spotify returns
Author
Owner

@AndrewKassab commented on GitHub (Feb 12, 2020):

I mean when I was calling with fields='tracks', I was receiving an object containing tracks:

{
    "tracks": { all tracks content here }
}

Weird, but anyways I can finally say this is solved

<!-- gh-comment-id:585476691 --> @AndrewKassab commented on GitHub (Feb 12, 2020): I mean when I was calling with fields='tracks', I was receiving an object containing tracks: ``` { "tracks": { all tracks content here } } ``` Weird, but anyways I can finally say this is solved
Author
Owner

@stephanebruckert commented on GitHub (Feb 12, 2020):

Is it possible you were calling sp.playlist, not sp.playlist_tracks?

<!-- gh-comment-id:585477300 --> @stephanebruckert commented on GitHub (Feb 12, 2020): Is it possible you were calling `sp.playlist`, not `sp.playlist_tracks`?
Author
Owner

@AndrewKassab commented on GitHub (Feb 12, 2020):

See here:

outputresponsedebug

Using playlist_tracks on line 28, and debug output below does give me the tracks object

<!-- gh-comment-id:585478696 --> @AndrewKassab commented on GitHub (Feb 12, 2020): See here: ![outputresponsedebug](https://user-images.githubusercontent.com/38924027/74388418-36f79700-4db0-11ea-8646-139db73cd370.png) Using playlist_tracks on line 28, and debug output below does give me the tracks object
Author
Owner

@stephanebruckert commented on GitHub (Feb 13, 2020):

I agree it's a bit weird. Unfortunately I can't test it because 3nWTj1ZAdLJXNiaLdMUOwj might be private? If you make it public or create a new public one with the same problem, I can check.

<!-- gh-comment-id:585483974 --> @stephanebruckert commented on GitHub (Feb 13, 2020): I agree it's a bit weird. Unfortunately I can't test it because `3nWTj1ZAdLJXNiaLdMUOwj` might be private? If you make it public or create a new public one with the same problem, I can check.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/spotipy#234
No description provided.