Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refreshing a token with authorization code flow #263

Closed
nhend opened this issue Mar 12, 2018 · 19 comments · Fixed by #428
Closed

Refreshing a token with authorization code flow #263

nhend opened this issue Mar 12, 2018 · 19 comments · Fixed by #428

Comments

@nhend
Copy link

nhend commented Mar 12, 2018

I have a long-running script using spotipy. After an hour (per the Spotify API), my access token expires. I am catching this successfully, but I don't know where to go from there in regards to actually refreshing the token. I am using the authorization code flow, not client credentials. Here's how I authorize:

`token = util.prompt_for_user_token(username,scope=scopes,client_id=client_id,client_secret=client_secret, redirect_uri=redirect_uri)

sp = spotipy.Spotify(auth=token)`

All refresh examples I've seen involve an oauth2 object (ex. oauth.refresh_access_token()), and the docs list only that function as a method of refreshing your token. It's my understanding that with authorization code flow, you don't need an oauth object (because you authenticate with prompt_for_user_token(). If that's the case, how do I refresh my token?

@onatilhan
Copy link

+1

@nhend
Copy link
Author

nhend commented Mar 20, 2018

Since I'm fairly certain refreshing a token without OAuth isn't possible, I'm linking my StackOverflow post where I detailed my solution and OAuth implementation, for Googler's sake

@kylegbakker
Copy link

If you look at https://github.com/plamere/spotipy/blob/master/spotipy/util.py you can see it does all the oauth for you, however I am experiencing a similar issue where my tokens are not refreshing. I'm not sure if it is just my implementation or what. Available information is spotty at best.

@nhend
Copy link
Author

nhend commented Mar 21, 2018

Yeah, but without actually having the OAuth object, you can't call any of the refresh functions. Perhaps refreshing should be built into the prompt_for_user_token() function, since that's where the OAuth object lives.

@kylegbakker
Copy link

out of curiosity, what version of python are you running?

@nhend
Copy link
Author

nhend commented Mar 21, 2018

3.6

@RaymondReed1208
Copy link

For what its worth, I've noticed that I am able to successfully refresh my spotify token when launching a python session in terminal, and running my code line by line... but if I try to do this in a python script, i get an invalid refresh token error

@devxpy
Copy link

devxpy commented Jun 2, 2018

@nhend I haven't tried this myself, but these are my findings -

The token does get automatically refeshed when you call the prompt_user_for_token() function

Here is the trace

sp_oauth.get_cached_token() in prompt_for_user_token()

self.refresh_access_token(token_info['refresh_token']) in get_cached_token()

However, you can see that refresh_access_token() only gets called if it can find the cached token, and it's expired.

So maybe try seeing if the token is cached in your local pc?

@josephgroton
Copy link

Hi, I'm trying to authenticate, and I'm using the code snippet you posted above, but I keep getting the error: "NameError: name 'util' is not defined"
Would you happen to know why this might be happening?

@nhend
Copy link
Author

nhend commented Nov 6, 2019

@josephgroton See this instead: https://stackoverflow.com/questions/49239516/spotipy-refreshing-a-token-with-authorization-code-flow

I used an OAuth object since the method I was originally posting about doesn't have a working refresh method.

@JattMones
Copy link

I believe @devxpy is correct in that refresh_access_token() only gets called by the prompt_for_user_token() function if it can find the cached token. However, I believe it should be able to find the refresh token in a file called '.cache-spotifyUsername', which should appear in your current working directory after you've authorized (ie. login with spotify username and password and entered the redirect url) your Spotify account with the app once. If you add the keyword cache_path and path\to\.cache-file as the value in prompt_for_user_token(), it should be able to automatically refresh this token for you (this is because the refresh token never expires, it is only deactivated when requested).

@JattMones
Copy link

JattMones commented Jan 17, 2020

An example for Bob Smith's Spotify would be: prompt_for_user_token(client_id='your_client_id', client_secret='your_client_secret', cache_path='.cache-BobSmith1234')

I'm not exactly sure how the cache file is created since I haven't done that much testing. It may require you to do your initial authentication slightly differently, but still following the Spotify OAuth2.0 flow (that is if the file isn't created using the normal prompt_for_user_token() function).

@stephanebruckert
Copy link
Member

stephanebruckert commented Jan 26, 2020

Here is a suggestion that replaces #87 (comment), please let me know what you think:

sp_oauth = oauth2.SpotifyOAuth(scope=SCOPE, prompt=True)
sp = spotipy.Spotify(oauth_manager=sp_oauth)

while True:
    sp.do_something()
    time.sleep(60)

Basically:

  • it adds a new oauth_manager parameter, just like we have one for the other flow client_credentials_manager https://github.com/plamere/spotipy/blob/master/examples/client_credentials_flow.py
  • this would deprecate util.prompt_for_user_token which has always been a bit confusing. We would keep it but the documentation would not mention it anymore
  • oauth2.SpotifyOAuth is called only once and does everything that util.prompt_for_user_token used to do, that includes prompting for the token if prompt=True and there is no cached token
  • spotipy.Spotify would be responsible for refreshing the token (it's already doing it for the client credentials flow)
  • it's also making the client ID/SECRET/URI and username optional, knowing that we can get them from the environment variables

Or, keeping util.prompt_for_user_token:

util.prompt_for_user_token(scope=SCOPE)
sp_oauth = oauth2.SpotifyOAuth(scope=SCOPE)
sp = spotipy.Spotify(oauth_manager=sp_oauth)

while True:
    sp.do_something()
    time.sleep(60)

@MaZderMind
Copy link
Contributor

Your first suggestion seems like a reasonable API design that would solve the problem neatly. 👍

@stephanebruckert
Copy link
Member

Done in #435 thanks to @stefanondisponibile

Now there is no need for util.prompt_for_user_token anymore. Instead you need to instantiate an oauth object. That will also take care of refreshing the token in the background so you shouldn't need to do it yourself.

Example from https://github.com/plamere/spotipy/blob/master/examples/simple4.py:

spotify = spotipy.Spotify(auth_manager=spotipy.SpotifyOAuth())
me = spotify.me()

@philipzimmermann
Copy link

First of all thanks for spotipy. I am struggling with refreshing the token for a while now. Unfortunately, the example code does not seem to work for me. I tried:

spotify=spotipy.Spotify(auth_manager=spotipy.SpotifyOAuth(client_id,client_secret,redirect_uri,scope=scope,cache_path=cache_path))
me = spotify.me()
pprint(me)

But I'm getting a TypeError: __init__() got an unexpected keyword argument 'auth_manager'

@stefanondisponibile
Copy link
Contributor

Hey @phixxx5 , I guess that's because the changes have been merged to master but still haven't been released to pypi.

If you really can't wait or simply want to try the preview I think you could clone the repo and pip install . it. But I'd suggest waiting for the next release, if possible 🙂

@stephanebruckert
Copy link
Member

@phixxx5 creating a new release now

@stephanebruckert
Copy link
Member

Done, just do pip install spotipy --upgrade

I haven't updated the doc yet, but yes your code above should now work!

sqrx-mckl added a commit to sqrx-mckl/spotify_app that referenced this issue Mar 23, 2020
I added too a new way to connect to the OAuth API
spotipy-dev/spotipy#263
conorhennessy added a commit to conorhennessy/Spotify-OLED-Control that referenced this issue May 9, 2020
In line with the following issue being fixed, changed authorisation flow to oauth.

spotipy-dev/spotipy#263
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.