[GH-ISSUE #1066] Example code does not work #629

Closed
opened 2026-02-28 00:00:23 +03:00 by kerem · 2 comments
Owner

Originally created by @aryan-gupta on GitHub (Dec 31, 2023).
Original GitHub issue: https://github.com/spotipy-dev/spotipy/issues/1066

BUG
A script I wrote few months ago is not working. To debug this issue, I ran the example: examples/user_playlists_contents.py which also failes with an error similar to my code.

MY CODE
This code gets the list of tracks from all the playlists the user has. user_playlists_short is a list of two-tuples with first element being the name of the playlist and the second item being the playlist id. This fails with this error:

def get_tracks(user_playlists_short):

    user_tracks = []
    user_tracks_set = set()
    for name, plid in user_playlists_short:
        results = sp.playlist(plid, fields="tracks,next")
        tracks = results['tracks']
        tracks_json = tracks['items']


        while tracks['next']:
            tracks = sp.next(tracks)
            tracks_json.extend(tracks['items'])
        
        user_tracks = user_tracks + [ (i['track']['name'], i['track']['id']) for i in tracks_json ]
        user_tracks_set = user_tracks_set.union(set([ i['track']['id'] for i in tracks_json ]))

    return user_tracks_set

ERROR:

Traceback (most recent call last):
  File "/[omitted]/spotify/./match_friends.py", line 94, in <module>
    ari_tracks = get_tracks(ari_playlists_short)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/[omitted]/spotify/./match_friends.py", line 77, in get_tracks
    tracks_json.extend(tracks['items'])
                       ~~~~~~^^^^^^^^^
KeyError: 'items'

The correct output should not error and the tracks inside the while loop should contain the next paged results. However, probing the tracks variable, there is only one item, but should contain the next paged link and the current list of tracks.

{'next': 'https://api.spotify.com/v1/playlists/[playlist_id_omitted]/tracks?offset=200&limit=100&fields=tracks,next&additional_types=track'}

FULL MINIMAL EXAMPLE
This is the examples/user_playlists_contents.py example with some modifications for the environment variables. This also errors out similar to my code.

import string
import time
import os
from os.path import join, dirname
from dotenv import load_dotenv
import json
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
from spotipy.oauth2 import SpotifyOAuth

dotenv_path = join(dirname(__file__), 'secret.env')
load_dotenv(dotenv_path)


SPOTIPY_CLIENT_ID = os.environ.get("SPOTIPY_CLIENT_ID")
SPOTIPY_CLIENT_SECRET = os.environ.get('SPOTIPY_CLIENT_SECRET')
SPOTIPY_REDIRECT_URI = os.environ.get('SPOTIPY_REDIRECT_URI')
SPOTIPY_USERNAME = os.environ.get('SPOTIPY_USER')


def show_tracks(results):
    for i, item in enumerate(results['items']):
        track = item['track']
        print(
            "   %d %32.32s %s" %
            (i, track['artists'][0]['name'], track['name']))


if __name__ == '__main__':
    scope = 'playlist-read-private'
    sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))

    playlists = sp.current_user_playlists()
    user_id = sp.me()['id']

    for playlist in playlists['items']:
        if playlist['owner']['id'] == user_id:
            print()
            print(playlist['name'])
            print('  total tracks', playlist['tracks']['total'])

            results = sp.playlist(playlist['id'], fields="tracks,next")
            tracks = results['tracks']
            show_tracks(tracks)

            while tracks['next']:
                tracks = sp.next(tracks)
                show_tracks(tracks)

ERROR:

Traceback (most recent call last):
  File "/[omitted]/spotify/./test.py", line 48, in <module>
    show_tracks(tracks)
  File "/[omitted]/spotify/./test.py", line 22, in show_tracks
    for i, item in enumerate(results['items']):
                             ~~~~~~~^^^^^^^^^
KeyError: 'items'

In this full minimal example, the same error happens. The while loop at the end, the tracks variable only contains the item below, however should contain both next and tracks items.

{'next': 'https://api.spotify.com/v1/playlists/[playlist_id_omitted]/tracks?offset=200&limit=100&fields=tracks,next&additional_types=track'}

ENVIRONMENT:

  • OS: Arch Linux
  • Python version: 3.11.6
  • spotipy version: 2.23.0
  • your IDE: VS-code, teminal, pyenv
Originally created by @aryan-gupta on GitHub (Dec 31, 2023). Original GitHub issue: https://github.com/spotipy-dev/spotipy/issues/1066 **BUG** A script I wrote few months ago is not working. To debug this issue, I ran the example: `examples/user_playlists_contents.py` which also failes with an error similar to my code. **MY CODE** This code gets the list of tracks from all the playlists the user has. `user_playlists_short` is a list of two-tuples with first element being the name of the playlist and the second item being the playlist id. This fails with this error: ``` def get_tracks(user_playlists_short): user_tracks = [] user_tracks_set = set() for name, plid in user_playlists_short: results = sp.playlist(plid, fields="tracks,next") tracks = results['tracks'] tracks_json = tracks['items'] while tracks['next']: tracks = sp.next(tracks) tracks_json.extend(tracks['items']) user_tracks = user_tracks + [ (i['track']['name'], i['track']['id']) for i in tracks_json ] user_tracks_set = user_tracks_set.union(set([ i['track']['id'] for i in tracks_json ])) return user_tracks_set ``` ERROR: ``` Traceback (most recent call last): File "/[omitted]/spotify/./match_friends.py", line 94, in <module> ari_tracks = get_tracks(ari_playlists_short) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/[omitted]/spotify/./match_friends.py", line 77, in get_tracks tracks_json.extend(tracks['items']) ~~~~~~^^^^^^^^^ KeyError: 'items' ``` The correct output should not error and the `tracks` inside the while loop should contain the next paged results. However, probing the tracks variable, there is only one item, but should contain the next paged link and the current list of tracks. ``` {'next': 'https://api.spotify.com/v1/playlists/[playlist_id_omitted]/tracks?offset=200&limit=100&fields=tracks,next&additional_types=track'} ``` **FULL MINIMAL EXAMPLE** This is the `examples/user_playlists_contents.py` example with some modifications for the environment variables. This also errors out similar to my code. ``` import string import time import os from os.path import join, dirname from dotenv import load_dotenv import json import spotipy from spotipy.oauth2 import SpotifyClientCredentials from spotipy.oauth2 import SpotifyOAuth dotenv_path = join(dirname(__file__), 'secret.env') load_dotenv(dotenv_path) SPOTIPY_CLIENT_ID = os.environ.get("SPOTIPY_CLIENT_ID") SPOTIPY_CLIENT_SECRET = os.environ.get('SPOTIPY_CLIENT_SECRET') SPOTIPY_REDIRECT_URI = os.environ.get('SPOTIPY_REDIRECT_URI') SPOTIPY_USERNAME = os.environ.get('SPOTIPY_USER') def show_tracks(results): for i, item in enumerate(results['items']): track = item['track'] print( " %d %32.32s %s" % (i, track['artists'][0]['name'], track['name'])) if __name__ == '__main__': scope = 'playlist-read-private' sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope)) playlists = sp.current_user_playlists() user_id = sp.me()['id'] for playlist in playlists['items']: if playlist['owner']['id'] == user_id: print() print(playlist['name']) print(' total tracks', playlist['tracks']['total']) results = sp.playlist(playlist['id'], fields="tracks,next") tracks = results['tracks'] show_tracks(tracks) while tracks['next']: tracks = sp.next(tracks) show_tracks(tracks) ``` ERROR: ``` Traceback (most recent call last): File "/[omitted]/spotify/./test.py", line 48, in <module> show_tracks(tracks) File "/[omitted]/spotify/./test.py", line 22, in show_tracks for i, item in enumerate(results['items']): ~~~~~~~^^^^^^^^^ KeyError: 'items' ``` In this full minimal example, the same error happens. The while loop at the end, the tracks variable only contains the item below, however should contain both `next` and `tracks` items. ``` {'next': 'https://api.spotify.com/v1/playlists/[playlist_id_omitted]/tracks?offset=200&limit=100&fields=tracks,next&additional_types=track'} ``` **ENVIRONMENT:** - OS: Arch Linux - Python version: 3.11.6 - spotipy version: 2.23.0 - your IDE: VS-code, teminal, pyenv
kerem 2026-02-28 00:00:23 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@debfx commented on GitHub (Jan 1, 2024):

My guess is that fetching playlists and then paginating over one of the fields (tracks) somehow broke server side.

Doing pagination over playlist_items() still works and IMHO is much cleaner.

<!-- gh-comment-id:1873471429 --> @debfx commented on GitHub (Jan 1, 2024): My guess is that fetching playlists and then paginating over one of the fields (tracks) somehow broke server side. Doing pagination over `playlist_items()` still works and IMHO is much cleaner.
Author
Owner

@Jack-Dane commented on GitHub (Jan 2, 2024):

@aryan-gupta it appears the problem is that the "next" request requires a different field present than the original playlist request.

This example works for me on playlists that require next when I change the fields kwarg:

results = sp.playlist("<playlist-id>", fields="tracks,next,items")

This example is broken and does need to be updated, here is a brief description of why this fixes the issue:

The next request is using the endpoint playlists/{playlist_id}/tracks (documentation) but the original sp.playlist is using a different endpoint playlists/{playlist_id} documentation.

These two endpoints return different data so you need to supply the additional items field so that the following /tracks, returned in the "next" key, will also have it. I couldn't find any documentation to support this, but it looks like any fields supplied in the playlist or track request will also be present in the next request.

<!-- gh-comment-id:1874053640 --> @Jack-Dane commented on GitHub (Jan 2, 2024): @aryan-gupta it appears the problem is that the "next" request requires a different field present than the original playlist request. This example works for me on playlists that require next when I change the fields kwarg: ``` results = sp.playlist("<playlist-id>", fields="tracks,next,items") ``` This example is broken and does need to be updated, here is a brief description of why this fixes the issue: The next request is using the endpoint `playlists/{playlist_id}/tracks` ([documentation](https://developer.spotify.com/documentation/web-api/reference/get-playlists-tracks)) but the original `sp.playlist` is using a different endpoint `playlists/{playlist_id}` [documentation](https://developer.spotify.com/documentation/web-api/reference/get-playlist). These two endpoints return different data so you need to supply the additional `items` field so that the following `/tracks`, returned in the "next" key, will also have it. I couldn't find any documentation to support this, but it looks like any fields supplied in the playlist or track request will also be present in the next request.
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#629
No description provided.