Anyone know why I am getting a 403 using the below code to remove a track from a Spotify playlist?

63 Views Asked by At

Note: client_id, client_secret, username, and playlist_id declarations have been removed from the code below.

# Number of songs to delete from the playlist
num_songs_to_delete = 5  # Change this to the desired number

# Encode client_id and client_secret for authentication
client_creds = f"{client_id}:{client_secret}"
#client_creds_b64 = base64.b64encode(client_creds.encode()).decode()
client_creds_b64 = base64.b64encode('{}:{}'.format(client_id, client_secret).encode())


# Get access token using client credentials flow
token_url = "https://accounts.spotify.com/api/token"
token_data = {
    "grant_type": "client_credentials"
}
#token_headers = {
#    "Authorization": f"Basic {client_creds_b64}"
#}
token_headers = {"Authorization": "Basic {}".format(client_creds_b64.decode())}


token_response = requests.post(token_url, data=token_data, headers=token_headers)
token_response_data = token_response.json()
access_token = token_response_data['access_token']

# Get playlist tracks using the access token
playlist_url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
playlist_headers = {
    "Authorization": f"Bearer {access_token}"
}
playlist_response = requests.get(playlist_url, headers=playlist_headers)
playlist_data = playlist_response.json()

# Sort tracks by their added_at timestamp in descending order
tracks = playlist_data['items']
sorted_tracks = sorted(tracks, key=lambda x: x['added_at'], reverse=True)


# Extract track URIs
tracks_uris = [track['track']['uri'] for track in sorted_tracks]

# Delete the specified number of tracks from the playlist
tracks_to_delete = tracks_uris[:min(num_songs_to_delete, len(tracks_uris))]

# Delete tracks
delete_url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
delete_data = {
    "tracks": [{"uri": uri} for uri in tracks_to_delete]
}
delete_response = requests.delete(delete_url, headers=playlist_headers, data=json.dumps(delete_data))

print(delete_response)

if delete_response.status_code == 200:
    print(f"{num_songs_to_delete} songs deleted from the playlist.")
else:
    print("Failed to delete songs from the playlist.")

I've tried using both requests and spotipy libraries to connect to the Spotify Web API to create a program to remove songs from a specified playlist, however, I'm getting 403s when running the code. The client_id and client_secret match whats in the developer portal app. I've done research and can't determine the root cause. The app is created properly in the Spotify Developer Portal as well.

Any help is much appreciated!

2

There are 2 best solutions below

0
James M. On BEST ANSWER

The issue was with my app created within the Spotify Dashboard... I'm not sure why, but when I recreated the app and used the new client id/secret/redirect_uri, I was able to authenticate successfully and script ran fine.

Might have been due to me running other scripts trying to authenticate causing some cache issue in the browser?

2
Bench Vue On

Two reasons

#1 Client Credentials Flow can't delete playlist

You did "grant_type": "client_credentials" for getting access token

You should use Authorization Code Flow

If you go Spotify API documentation In Remove Playlist Items,

https://developer.spotify.com/documentation/web-api/reference/remove-tracks-playlist

You can see Authorization scopes. It means your access token have get by Authorization Code Flow.

enter image description here

It means you have to run local server for redirect (callback) URL. The spotipy provides easily for you.

#2 [Scopes] matter

If you go Spotify scopes documentation

https://developer.spotify.com/documentation/web-api/concepts/scopes

Those two scopes are required for removing playlist tracks

playlist-modify-public
playlist-modify-private

enter image description here

I modified your code and added spotipy code.

Save as demo.py

import requests
import json
import spotipy
from spotipy.oauth2 import SpotifyOAuth

client_id = '<your client id>'
client_secret = '<your client secret>'
redirect_uri = '<your redirect uri>' # get from developer dash board
username = '<your user name>'        # get from user profile
SCOPEs = ['playlist-modify-private', 'playlist-modify-public']

playlist_id = '<your playlist ID>'     # You want to delete from this playlist ID
# Number of songs to delete from the playlist
num_songs_to_delete = 5  # Change this to the desired number

auth_manager = SpotifyOAuth(client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, scope=SCOPEs, username=username)
sp = spotipy.Spotify(auth_manager=auth_manager)
token_info = sp.auth_manager.get_cached_token()
access_token = None
if (token_info is None):
    access_token = sp.auth_manager.get_access_token()
else:
    access_token = token_info['access_token']

# Get playlist tracks using the access token
playlist_url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
playlist_headers = {
    "Authorization": f"Bearer {access_token}"
}
playlist_response = requests.get(playlist_url, headers=playlist_headers)
playlist_data = playlist_response.json()

# Sort tracks by their added_at timestamp in descending order
tracks = playlist_data['items']
sorted_tracks = sorted(tracks, key=lambda x: x['added_at'], reverse=True)


# Extract track URIs
tracks_uris = [track['track']['uri'] for track in sorted_tracks]

# Delete the specified number of tracks from the playlist
tracks_to_delete = tracks_uris[:min(num_songs_to_delete, len(tracks_uris))]

# Delete tracks
delete_url = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks"
delete_data = {
    "tracks": [{"uri": uri} for uri in tracks_to_delete]
}
delete_response = requests.delete(delete_url, headers=playlist_headers, data=json.dumps(delete_data))

print(delete_response)

if delete_response.status_code == 200:
    print(f"{num_songs_to_delete} songs deleted from the playlist.")
else:
    print("Failed to delete songs from the playlist.")

How to get

client_id, client_secret and redirect_uri

Open URL by browser

https://developer.spotify.com/dashboard

enter image description here

How to get username

Open URL by browser

https://open.spotify.com/

enter image description here

Install dependencies

pip install requests
pip install spotipy

Before Run it

Check number of songs in your playlist 9 songs before run

enter image description here

Run it

python demo.py

enter image description here

After Run it

4 songs left due to 5 songs being removed

enter image description here

Warp up

I just demo for how to remove songs from playlist but I use mixed API call request API and Spotipy API but I recommend using only Spotipy API if you use Authorization Code Flow.