pythonapijupyter-notebookoauth-2.0spotify

Spotify API AttributeError: module 'spotipy.util' has no attribute 'oauth2'


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!


Solution

  • 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:

    https://community.spotify.com/t5/Spotify-for-Developers/Getting-403-error-when-using-sp-audio-features/td-p/6547327