'Python: using Spotipy to create playlist but getting 403 Code1 Error

I am using the Spotipy API to create a spotify playlist in python. My code uses beautifulSoup to scrape the contents from a website and creates an input to be passed onto Spotipy. The part where my code tries to create a Spotipy playlist is failing however. I think I am doing everything correctly as per the API documentation. Was hoping anyone could provide any help. See my code and errors below:

import requests
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from spotipy.oauth2 import SpotifyClientCredentials
from pprint import pprint

SPOTIFY_CLIENT_ID = "[id]"
SPOTIFY_SECRET = "[secret]"
REDIRECT_URL = "http://example.com"

sp = spotipy.Spotify(
    auth_manager=SpotifyOAuth(
        scope="playlist-modify-private",
        redirect_uri=REDIRECT_URL,
        client_id=SPOTIFY_CLIENT_ID,
        client_secret=SPOTIFY_SECRET,
        cache_path="token.txt"
    )
)

SONG_YEAR = input("What year would you like to travel back to? Enter YYYY-MM-DD format: ")
BILL_BOARD_URL = f"https://www.billboard.com/charts/hot-100/{SONG_YEAR}/"
SONG_YEAR_YEAR = SONG_YEAR.split("-")[0]
print(SONG_YEAR_YEAR)

response = requests.get(BILL_BOARD_URL)
song_scrape = response.text

soup = BeautifulSoup(song_scrape, "html.parser")

song_tags_list = soup.findAll(name="h3", class_="a-no-trucate")
artists_tags_list = soup.findAll(name="span", class_="a-no-trucate")


song_list_1 = [tag.getText().replace("\n", "") for tag in song_tags_list]
song_list_2 = [song.replace("\t", "") for song in song_list_1]

artist_list_1 = [tag.getText().replace("\n", "") for tag in artists_tags_list]
artist_list_2 = [artist.replace("\t", "") for artist in artist_list_1]

song_artist_list = dict(zip(artist_list_2, song_list_2))
# pprint(song_artist_list)


results = sp.current_user()
# pprint(results)
user_id = results['id']

# print(results)
# print(user_id)

spotify_song_uris = []
##TAKEN OUT OF BELOW FOR LOOP ['artists'][0] -> remember to add back in
for key, value in song_artist_list.items():
    spotify_result = sp.search(q=f"artist:{key} track:{value} year:{SONG_YEAR_YEAR}", type="track")
    try:
        song_uri = spotify_result['tracks']['items'][0]['uri']
        spotify_song_uris.append(song_uri)
    except IndexError:
        print(f"{value} doesn't exist in Spotify. Skipped.")

print(len(spotify_song_uris))

my_playlist = sp.user_playlist_create(user=f"{user_id}", name=f"{SONG_YEAR} Billboard Top Tracks", public=True,
                                      description="Top Tracks from back in the Dayz of Brunel")

I get this error when I run my code:

Traceback (most recent call last):
  File "C:\Users\zeesh\PycharmProjects\Day46-UsingBeautifulSoup\venv\lib\site-packages\spotipy\client.py", line 245, in _internal_call
    response.raise_for_status()
  File "C:\Users\zeesh\PycharmProjects\Day46-UsingBeautifulSoup\venv\lib\site-packages\requests\models.py", line 960, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://api.spotify.com/v1/users/31qjiqkvnqvjhi34ukkoef7mloom/playlists

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\zeesh\PycharmProjects\Day46-SpotifyPlaylist\main.py", line 65, in <module>
    my_playlist = sp.user_playlist_create(user=f"{user_id}", name=f"{SONG_YEAR} Billboard Top Tracks", public=True,
  File "C:\Users\zeesh\PycharmProjects\Day46-UsingBeautifulSoup\venv\lib\site-packages\spotipy\client.py", line 784, in user_playlist_create
    return self._post("users/%s/playlists" % (user,), payload=data)
  File "C:\Users\zeesh\PycharmProjects\Day46-UsingBeautifulSoup\venv\lib\site-packages\spotipy\client.py", line 302, in _post
    return self._internal_call("POST", url, payload, kwargs)
  File "C:\Users\zeesh\PycharmProjects\Day46-UsingBeautifulSoup\venv\lib\site-packages\spotipy\client.py", line 267, in _internal_call
    raise SpotifyException(
spotipy.exceptions.SpotifyException: http status: 403, code:-1 - https://api.spotify.com/v1/users/31qjiqkvnqvjhi34ukkoef7mloom/playlists:
 Insufficient client scope, reason: None

When I click the API call link in the error i get:

{
"error": {
"status": 401,
"message": "No token provided"
}
}

I've done some reading around on StackOverflow and other sites. I tried changing the scope but that didnt work.

Any Thoughts or guidance would be much appreciated. Thank you. Zeeshan



Solution 1:[1]

The scope in your code is playlist-modify-private, but in the last row you're trying to create a playlist with public=True.
To solve this issue, you have to change the scope to playlist-modify-public or change public to False.

Solution 2:[2]

if you want your playlist to be private try this (I changed the public to False):

import requests
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from spotipy.oauth2 import SpotifyClientCredentials
from pprint import pprint

SPOTIFY_CLIENT_ID = "[id]"
SPOTIFY_SECRET = "[secret]"
REDIRECT_URL = "http://example.com"

sp = spotipy.Spotify(
    auth_manager=SpotifyOAuth(
        scope="playlist-modify-private",
        redirect_uri=REDIRECT_URL,
        client_id=SPOTIFY_CLIENT_ID,
        client_secret=SPOTIFY_SECRET,
        cache_path="token.txt"
    )
)

SONG_YEAR = input("What year would you like to travel back to? Enter YYYY-MM-DD format: ")
BILL_BOARD_URL = f"https://www.billboard.com/charts/hot-100/{SONG_YEAR}/"
SONG_YEAR_YEAR = SONG_YEAR.split("-")[0]
print(SONG_YEAR_YEAR)

response = requests.get(BILL_BOARD_URL)
song_scrape = response.text

soup = BeautifulSoup(song_scrape, "html.parser")

song_tags_list = soup.findAll(name="h3", class_="a-no-trucate")
artists_tags_list = soup.findAll(name="span", class_="a-no-trucate")


song_list_1 = [tag.getText().replace("\n", "") for tag in song_tags_list]
song_list_2 = [song.replace("\t", "") for song in song_list_1]

artist_list_1 = [tag.getText().replace("\n", "") for tag in artists_tags_list]
artist_list_2 = [artist.replace("\t", "") for artist in artist_list_1]

song_artist_list = dict(zip(artist_list_2, song_list_2))
# pprint(song_artist_list)


results = sp.current_user()
# pprint(results)
user_id = results['id']

# print(results)
# print(user_id)

spotify_song_uris = []
##TAKEN OUT OF BELOW FOR LOOP ['artists'][0] -> remember to add back in
for key, value in song_artist_list.items():
    spotify_result = sp.search(q=f"artist:{key} track:{value} year:{SONG_YEAR_YEAR}", type="track")
    try:
        song_uri = spotify_result['tracks']['items'][0]['uri']
        spotify_song_uris.append(song_uri)
    except IndexError:
        print(f"{value} doesn't exist in Spotify. Skipped.")

print(len(spotify_song_uris))

my_playlist = sp.user_playlist_create(user=f"{user_id}", name=f"{SONG_YEAR} Billboard Top Tracks", public=False,
                                      description="Top Tracks from back in the Dayz of Brunel")

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Vincent van Leeuwen
Solution 2 Tal Folkman