Spotify API get_playlists not showing Discover Weekly

106 Views Asked by At

I have some Python code to make a flask app that just auto saves all my discover weekly songs into a playlist, but it is unable to find the discover weekly. I have it list all my other playlists and they show up fine, and I have manually followed the discover weekly playlist in Spotify but it won't show.

EDIT: someone suggested checking the max limit, however for me at least this does not apply as the default limit is 50 and I have 41 playlists (including discover weekly)

def save_discover_weekly(token_info):
    sp = spotipy.Spotify(auth=token_info['access_token'])
    cur_playlists = sp.current_user_playlists()['items']
    discover_weekly_id = None
    saved_weekly_id = None
    for playlist in cur_playlists:
        print(playlist['name'])
        if playlist['name'] == 'Discover Weekly':
            discover_weekly_id = playlist['id']
            print(discover_weekly_id)
            break
        if playlist['name'] == 'Saved Weekly':
            saved_weekly_id = playlist['id']
            print(saved_weekly_id)

    if discover_weekly_id is None:
        return "Discover Weekly not found"
    if not saved_weekly_id:
        print("Creating saved weekly playlist")
        saved_weekly = sp.user_playlist_create(sp.current_user()['id'],
                                               "Saved Weekly", True)
        saved_weekly_id = saved_weekly['id']

    discover_weekly_songs = sp.playlist_items(discover_weekly_id)
    song_uris = [song['track']['uri'] for song in discover_weekly_songs['items']]

    sp.user_playlist_add_tracks(sp.current_user()['id'], saved_weekly_id, 
                                song_uris)

    return "Discover Weekly songs saved to Saved Weekly playlist!"
2

There are 2 best solutions below

3
Dmitry On

Pagination

A lot of Spotify endpoints use pagination and take a pair of parameters: offset and limit. If skipped the default values are taken, which are usually documented in the corresponding endpoint reference. For example, the current user’s playlist request has a default limit of 20.

spotipy follows this way, sometimes using different default values. For example, current_user_playlist has default limit of 50:

def current_user_playlists(self, limit=50, offset=0):
   """ Get current user playlists without required getting his profile
       Parameters:
           - limit  - the number of items to return
           - offset - the index of the first item to return
   """
   return self._get("me/playlists", limit=limit, offset=offset)

So for the user with lots of playlists there is a chance not to retrieve enough data to get the desired playlist. You need to request these playlists page by page:

MAX_LIMIT = 50
MAX_OFFSET = 100000
DISCOVER_WEEKLY = "Discover Weekly"
SPOTIFY_USER_ID = 'spotify'

def get_discover_weekly_playlist(spotify: spotipy.Spotify) -> Optional[dict]:

    for offset in range(0, MAX_OFFSET + 1, MAX_LIMIT):

        try:
            response = spotify.current_user_playlists(limit=MAX_LIMIT,
                                                      offset=offset)
        except spotipy.SpotifyException:
            break

        try:
            playlists = response['items']
        except (TypeError, KeyError):
            break

        if not playlists:
            break

        for playlist in playlists:
            if (playlist['owner']['id'] == SPOTIFY_USER_ID
                    and playlist['name'] == DISCOVER_WEEKLY):
                
                # playlist found doesn't have tracks
                # have to request the full data by id
                return spotify.playlist(playlist['id'])

    return None

Search

Considering boundary cases there could be a situation that browsing playlists is more inferior than a simple search. It seems that there are not so many public playlists in search results by query “Discover Weekly”. And also Spotify ranks it high. It could be actually the very first playlist in the result collection. Still all the said above about paging applies here:

MAX_LIMIT = 50
MAX_OFFSET = 1000
DISCOVER_WEEKLY_QUERY = "Discover Weekly"
PLAYLIST_TYPE = 'playlist'
SPOTIFY_USER_ID = 'spotify'

def get_discover_weekly(spotify: spotipy.Spotify) -> Optional[dict]:

    for offset in range(0, MAX_OFFSET + 1, MAX_LIMIT):
        try:
            response = spotify.search(q=DISCOVER_WEEKLY_QUERY, type=PLAYLIST_TYPE,
                                      offset=offset, limit=MAX_LIMIT)
        except spotipy.SpotifyException:
            break

        try:
            playlists = response['playlists']['items']
        except (TypeError, KeyError):
            break

        if not playlists:
            break

        for playlist in playlists:
            if (playlist['owner']['id'] == SPOTIFY_USER_ID
                    and playlist['name'] == DISCOVER_WEEKLY_QUERY):

                # same here, item found doesn't have tracks
                # have to request the full data by id
                return spotify.playlist(playlist['id'])

    return None
0
Nithin Ram Kalava On

It's possible to find those playlists using the Search API https://developer.spotify.com/documentation/web-api/reference/search

def save_discover_weekly(token_info):
    sp = spotipy.Spotify(auth=token_info['access_token'])
    cur_playlists = sp.current_user_playlists()['items']

    """The modified code uses the Spotify API to search for the
       "Discover Weekly" playlist and retrieve its ID.
       This ID is then assigned to the variable discover_weekly_id."""
    
    discover_weekly_playlist = sp.search("Discover Weekly", limit=1, type="playlist")
    discover_weekly_id = discover_weekly_playlist["playlists"]["items"][0]["id"]

    saved_weekly_id = None
    for playlist in cur_playlists:
        if playlist['name'] == 'Saved Weekly':
            saved_weekly_id = playlist['id']
            break

    if discover_weekly_id is None:
        return "Discover Weekly not found"
    if not saved_weekly_id:
        print("Creating saved weekly playlist")
        saved_weekly = sp.user_playlist_create(sp.current_user()['id'],
                                               "Saved Weekly", True)
        saved_weekly_id = saved_weekly['id']

    discover_weekly_songs = sp.playlist_items(discover_weekly_id)
    song_uris = [song['track']['uri'] for song in discover_weekly_songs['items']]

    sp.user_playlist_add_tracks(sp.current_user()['id'], saved_weekly_id, 
                                song_uris)

    return "Discover Weekly songs saved to Saved Weekly playlist!"