2

I've read about the offset parameter in the documentation; however, I can't figure out how to use it. Here's my code so far. Unfortunately only the first 100 songs are retrieved from the playlist. How do I change the index so that I can retrieve more songs from a playlist?

import os, re, shutil

import spotipy
import spotipy.util as util
import time

# Parameters
username      = 'REDACTED'
client_id     = 'REDACTED'
client_secret = 'REDACTED'
redirect_uri  = 'http://localhost/'
scope         = 'user-library-read'
playlist      = '17gneMykp6L6O5R70wm0gE'


def show_tracks(tracks):
    for i, item in enumerate(tracks['items']):
        track = item['track']
        myName = re.sub('[^A-Za-z0-9\ ]+', '', track['name'])
        dirName = "/Users/pschorn/Songs/" + myName + ".app"
        if os.path.exists(dirName):
            continue
            #shutil.rmtree(dirName)
        os.mkdir(dirName)
        os.mkdir(dirName + "/Contents")
        with open(dirName + "/Contents/PkgInfo", "w+") as f:
            f.write("APPL????")
        os.mkdir(dirName + "/Contents/MacOS")
        with open(dirName + "/Contents/MacOS/" + myName, "w+") as f:
            f.write("#!/bin/bash\n")
            f.write("osascript -e \'tell application \"Spotify\" to play track \"{}\"\'".format(track['uri']))
        os.lchmod(dirName + "/Contents/MacOS/" + myName, 0o777)

        myName = re.sub('\ ', '\\ ', myName)
        # I've installed a third-party command-line utility that
        # allows me to set the icon for applications.
        # If there's a way to do this from python, let me know.
        os.system(
            '/usr/local/bin/fileicon set /Users/pschorn/Songs/' + myName + '.app /Users/pschorn/Code/PyCharmSupport/Icon.icns')





token = util.prompt_for_user_token(username, scope, client_id, client_secret, redirect_uri)

if token:
    sp = spotipy.Spotify(auth=token)
    results = sp.user_playlist(username, playlist, fields="tracks,next")
    tracks = results['tracks', offset=100]
    show_tracks(tracks)

else:
    print("Can't get token for", username)

EDIT: I've since figured out how to return songs starting at a given index and much more than that. You can check out my code here! It retrieves all the songs in all of the user's playlists and makes an application for each one that can be opened to play the song. The purpose of this is so that you can play your Spotify songs directly from spotlight search!

Peter Schorn
  • 916
  • 3
  • 10
  • 20

1 Answers1

0

This custom class I wrote that extends functionality offered by the Spotipy library has a wrapper function that handles offsets.

def user_playlist_tracks_full(spotify, user, playlist_id=None, fields=None, market=None):
    """ Get full details of the tracks of a playlist owned by a user.
        Parameters:
            - spotify - spotipy instance
            - user - the id of the user
            - playlist_id - the id of the playlist
            - fields - which fields to return
            - market - an ISO 3166-1 alpha-2 country code.
    """

    # first run through also retrieves total no of songs in library
    response = spotify.user_playlist_tracks(user, playlist_id, fields=fields, limit=100, market=market)
    results = response["items"]

    # subsequently runs until it hits the user-defined limit or has read all songs in the library
    while len(results) < response["total"]:
        response = spotify.user_playlist_tracks(
            user, playlist_id, fields=fields, limit=100, offset=len(results), market=market
        )
        results.extend(response["items"])

    return results

This code might be enough to illustrate what you have to do, loop over and change the offset each time.

The full class is in a standalone gist that should work, in this example I've just replaced self with spotify.

Rach Sharp
  • 2,324
  • 14
  • 31