简体   繁体   中英

Spotify API Access Tokens after 60 Minutes - How to Reset to Keep Webapp Working

I have a hobby Python/Flask web application on PythonAnywhere.com to develop functionality that Spotify doesn't natively support. My web app works as expected after manually reload the web app (via the "Web" tab on PythonAnywhere). However, the problem I'm encountering is that after a period of time, when API calls are made via the front-end web pages, an "Internal Server Error" is returned.

I traced the problem and found the calls to the Spotify APIs were returning a 401 error response after about an hour - and then found that Spotify access tokens only last 1 hour .

One troubleshooting theory was that maybe pythonanywhere.com was only running the code to refresh my access tokens once (when reloading the web app), so then they would expire after 60 minutes. So I tried making the access token refresh into a function, and then calling that function from other functions that make the API calls. But this didn't work, but here's below is my code to show what I did.

My only remaining theory now is that the web server only gets the access tokens once (when the web server is refreshed) - but I'm not quite sure how to troubleshoot that.

Any thoughts on that theory, or other avenues I should explore so that I don't need to manually restart the web server to get my app to work?

set variables

AUTH_URL = 'https://accounts.spotify.com/api/token'
BASE_URL = 'https://api.spotify.com/v1/'

Code to get access token and return headers for the API call

auth_response = requests.post(AUTH_URL, {
    'grant_type': 'client_credentials',
    'client_id': CLIENT_ID,
    'client_secret': CLIENT_SECRET,
})


def setHeaders():
    try:
        auth_response.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print("!!!Error setting auth_response. System detail:")
        print(e)
        raise

    # convert the response to JSON
    auth_response_data = auth_response.json()

    # save the access token
    access_token = auth_response_data['access_token']

    headers = {
        'Authorization': 'Bearer {token}'.format(token=access_token)
    }

    return headers

function that makes the call to Spotify API that returns all playlist for a user:

#API GET link: https://api.spotify.com/v1/users/{user_id}/playlists
def getRawPlaylistMetadata(username,offset_value=0):

    headers = setHeaders()

    r_list = []
    result_limit = 50
    #print(offset_value)

    params = {'offset': offset_value,
              'limit': result_limit}

    r = requests.get(BASE_URL + 'users/' + username + '/playlists', \
        headers=headers,params=params)

    response_code = str(r.status_code)

    sys.stderr.write("\nr response code=" + response_code + "\n\n")

    r = r.json()

    try:
        r_list = r['items']
    except KeyError:
        print("Getting all of Spotify user's playlist metadata failed.")

    if len(r_list) < result_limit:
        #print(len(r_list))
        return r_list

    return r_list + getRawPlaylistMetadata(username,offset_value + len(r_list))

I'm not sure how running it in the terminal does not cause the same issue, as your function doesn't even refresh the session:

# REQUEST EXECUTED HERE
auth_response = requests.post(AUTH_URL, {
    'grant_type': 'client_credentials',
    'client_id': CLIENT_ID,
    'client_secret': CLIENT_SECRET,
})


def setHeaders():
    # Function ran here
    # the request is not re-executed
    ...

So you should probably put it inside the function:

def setHeaders():
    auth_response = requests.post(AUTH_URL, {
        'grant_type': 'client_credentials',
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
    })

    ...

Then, to keep re-authenticating while running the Flask server, I recommend using a Thread:

from time import sleep

def reauth():
    while True:
        setHeaders()
        sleep(30 * 60) # Sleep for half an hour, then re-authenticate

t = Thread(target=reauth)
t.start()

This would keep it running in parallel with the Flask server, and would keep calling it to reauthenticate the client every half an hour.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM