Search code examples
pythonspotifyspotipyspotify-app

Refresh token Spotify APIs


I have the following python program that starting from the listening history passed in input to extract various information such as acousticness, instrumentalness etc ... the problem I have is when I pass a large listening history the program crashes saying that the token has expired . Reading the spotify documentation I saw that one way to prevent this from happening is to use the Authorization Code Flow but I don't quite understand how to implement it in my code. Can anyone help me?

token = util.prompt_for_user_token(username=config.username, 
                                   scope=config.scope, 
                                   client_id=config.client_id,   
                                   client_secret=config.client_secret,     
                                   redirect_uri=config.redirect_uri)
# Now you can finally authorize your app. Once you click on Agree, 
# you will be taken to the Redirect URI, which may well be a nonexistent page. 
# Just copy the address and paste it in your Python console.
#print(token)

# write the function to get track_id
def get_id(track_name: str,artist:str, token: str) -> str:
    headers = {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'Authorization': f'Bearer ' + token,
    }
    track_artist = track_name+ " " + artist
    params = [
    ('q',track_artist ),#q is the search query parameter
    ('type', 'track'),
    ]
    try:
        response = requests.get('https://api.spotify.com/v1/search', 
                    headers = headers, params = params, timeout = 10)
        json = response.json()
        first_result = json['tracks']['items'][0]
        track_id = first_result['id']
        return track_id
    except:
        return None

# Get track_id for streaming history    
spotify_data["track_id"] = spotify_data.apply(lambda x: get_id(x["track_name"],
                                                               x["artist_name"],
                                                                 token),axis=1)
# get track's feature
my_feature = pd.DataFrame(columns=["song_id","energy", "liveness","tempo","speechiness",
                                "acousticness","instrumentalness","danceability",
                                "duration_ms","loudness","valence",
                                "mode","key"])

# filter the streaming data by non-null result
spotify_data_nonull = spotify_data["track_id"].dropna()
#print(spotify_data_nonull)

track = list(OrderedDict.fromkeys(spotify_data_nonull)) 
#print(track)
sp = spotipy.Spotify(auth=token)
for song in track:
    features = sp.audio_features(tracks = [song])[0]
    if features is not None:
        my_feature = my_feature.append({"song_id":song,
                                    "energy":features['energy'], 
                                    "liveness":features['liveness'],
                                    "tempo":features['tempo'],
                                    "speechiness":features['speechiness'],
                                    "acousticness":features['acousticness'],
                                    "instrumentalness":features['instrumentalness'],
                                    "danceability":features['danceability'],
                                    "duration_ms":features['duration_ms'],
                                    "loudness":features['loudness'],
                                    "valence":features['valence'],
                                    "mode":features['mode'],
                                    "key":features["key"],
                                    
                                 },ignore_index=True)
    else:
        pass

Solution

  • I rewrote the beginning of your code. The refresh token should be generated/requested and used automatically by spotipy when a token expires.

    import spotipy
    from spotipy.oauth2 import SpotifyOAuth
    import pandas as pd
    
    sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=config.client_id,
    client_secret=config.client_secret,
    redirect_uri=config.redirect_uri,
    scope=config.scope))
    
    
    def get_id(track_name: str,artist:str) -> str:
        try:
            q = f"track:'{track_name}' artist:'{artist}'"
            json = sp.search(q=q, limit=1, offset=0, type='track', market=None)
            first_result = json['tracks']['items'][0]
            return first_result['id']
        except:
            return None
    
    print(get_id("Levels","Avicii"))
    

    P.S. At first, your code was scrolled down and didn't see the top of your code. If you use my code, your sp = spotipy.Spotify(auth=token) in the middle of your code can be removed.