I am practicing to extract audio features using Spotify API by referring to this repo https://github.com/MaxHilsdorf/introduction_to_spotipy/blob/master/introduction_to_spotipy.ipynb . However, I keep facing an error at the line
token = util.oauth2.SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)
The error looks like this:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[4], line 1
----> 1 token = util.oauth2.SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)
2 cache_token = token.get_access_token()
3 sp = spotipy.Spotify(cache_token)
AttributeError: module 'spotipy.util' has no attribute 'oauth2'
I searched for ways to solve it and so I corrected the code with:
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
import pandas as pd
client_credentials_manager = SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
But it will face an error when I run the line
playlist_df = analyze_playlist(playlist_creator, playlist_id)
Which looks like this
HTTPError Traceback (most recent call last)
File ~\anaconda3\lib\site-packages\spotipy\client.py:275, in Spotify._internal_call(self, method, url, payload, params)
270 response = self._session.request(
271 method, url, headers=headers, proxies=self.proxies,
272 timeout=self.requests_timeout, **args
273 )
--> 275 response.raise_for_status()
276 results = response.json()
File ~\anaconda3\lib\site-packages\requests\models.py:1021, in Response.raise_for_status(self)
1020 if http_error_msg:
-> 1021 raise HTTPError(http_error_msg, response=self)
HTTPError: 403 Client Error: Forbidden for url: https://api.spotify.com/v1/audio-features/?ids=3AWDeHLc88XogCaCnZQLVI
During handling of the above exception, another exception occurred:
SpotifyException Traceback (most recent call last)
Cell In[60], line 1
----> 1 playlist_df = analyze_playlist(playlist_creator, playlist_id)
Cell In[59], line 21, in analyze_playlist(creator, playlist_id)
19 playlist_features["track_id"] = track["track"]["id"]
20 # Get audio features
---> 21 audio_features = sp.audio_features(playlist_features["track_id"])[0]
22 for feature in playlist_features_list[4:]:
23 playlist_features[feature] = audio_features[feature]
File ~\anaconda3\lib\site-packages\spotipy\client.py:1799, in Spotify.audio_features(self, tracks)
1797 if isinstance(tracks, str):
1798 trackid = self._get_id("track", tracks)
-> 1799 results = self._get("audio-features/?ids=" + trackid)
1800 else:
1801 tlist = [self._get_id("track", t) for t in tracks]
File ~\anaconda3\lib\site-packages\spotipy\client.py:327, in Spotify._get(self, url, args, payload, **kwargs)
324 if args:
325 kwargs.update(args)
--> 327 return self._internal_call("GET", url, payload, kwargs)
File ~\anaconda3\lib\site-packages\spotipy\client.py:297, in Spotify._internal_call(self, method, url, payload, params)
290 reason = None
292 logger.error(
293 'HTTP Error for %s to %s with Params: %s returned %s due to %s',
294 method, url, args.get("params"), response.status_code, msg
295 )
--> 297 raise SpotifyException(
298 response.status_code,
299 -1,
300 f"{response.url}:\n {msg}",
301 reason=reason,
302 headers=response.headers,
303 )
304 except requests.exceptions.RetryError as retry_error:
305 request = retry_error.request
SpotifyException: http status: 403, code:-1 - https://api.spotify.com/v1/audio-features/?ids=3AWDeHLc88XogCaCnZQLVI:
None, reason: None
Below is the full code I have written:
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
import pandas as pd
CLIENT_ID = "myidfromapidashboard"
CLIENT_SECRET = "mysecretfromapidashboard"
token = util.oauth2.SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)
cache_token = token.get_access_token()
sp = spotipy.Spotify(cache_token)
playlist_creator = "spotify"
playlist_id = "37i9dQZF1DX5IDTimEWoTd"
def analyze_playlist(creator, playlist_id):
# Create empty dataframe
playlist_features_list = ["artist", "album", "track_name", "track_id",
"danceability", "energy", "key", "loudness", "mode", "speechiness",
"instrumentalness", "liveness", "valence", "tempo", "duration_ms", "time_signature"]
playlist_df = pd.DataFrame(columns = playlist_features_list)
# Create empty dict
playlist_features = {}
# Loop through every track in the playlist, extract features and append the features to the playlist df
playlist = sp.user_playlist_tracks(creator, playlist_id)["items"]
for track in playlist:
# Get metadata
playlist_features["artist"] = track["track"]["album"]["artists"][0]["name"]
playlist_features["album"] = track["track"]["album"]["name"]
playlist_features["track_name"] = track["track"]["name"]
playlist_features["track_id"] = track["track"]["id"]
# Get audio features
audio_features = sp.audio_features(playlist_features["track_id"])[0]
for feature in playlist_features_list[4:]:
playlist_features[feature] = audio_features[feature]
# Concat the dfs
track_df = pd.DataFrame(playlist_features, index = [0])
playlist_df = pd.concat([playlist_df, track_df], ignore_index = True)
return playlist_df
playlist_df = analyze_playlist(playlist_creator, playlist_id)
Does anyone know how to solve this problem? Please help me if you have experience on this. Thank you in advance!
I googled your error and it seems the API endpoint corresponding to spotipy.Spotify.audio_features()
has been deprecated (EDIT: announced November 27, 2024).
Note about the deprecation in Spotify's developer feed:
https://developer.spotify.com/documentation/web-api/reference/get-audio-features
Info about all related changes to the web API with other stuff that has become deprecated:
https://developer.spotify.com/blog/2024-11-27-changes-to-the-web-api
The link I found the info through: