spotipy-dev / spotipy

A light weight Python library for the Spotify Web API
http://spotipy.readthedocs.org
MIT License
4.97k stars 956 forks source link

util.prompt_for_user_token stops opening correct browser page to actually log in to Spotify for authorization #405

Closed grantbrewster closed 4 years ago

grantbrewster commented 4 years ago

Hi everyone! Looking forward to the updates to this awesome project and hoping to help out. I just started working with this API this weekend, and I made a simple console application that scrapes setlist URLs in order to automatically create playlists for people based on setlist.fm urls. Repo : https://github.com/grantbrewster/SpotifySetlistCreator . However for my auth, after the first time i run the program, it never again correctly opens a browser window to let me log in to spotify, so it limits the app to only work for my account. I tried deleting the cache in the directory as well as clearing my chrome cache and then running it but that does not solve the problem. SO i feel the issue may be in the prompt_for_user_token method. I found this stackoverflow that mentions that webbrowser.open() may be at fault : https://stackoverflow.com/questions/38574629/webbrowser-not-opening-new-windows

here is the code from util

def prompt_for_user_token(username, scope=None, client_id = None,
        client_secret = None, redirect_uri = None):
    ''' prompts the user to login if necessary and returns
        the user token suitable for use with the spotipy.Spotify 
        constructor

        Parameters:

         - username - the Spotify username
         - scope - the desired scope of the request
         - client_id - the client id of your app
         - client_secret - the client secret of your app
         - redirect_uri - the redirect URI of your app

    '''

    if not client_id:
        client_id = os.getenv('SPOTIPY_CLIENT_ID')

    if not client_secret:
        client_secret = os.getenv('SPOTIPY_CLIENT_SECRET')

    if not redirect_uri:
        redirect_uri = os.getenv('SPOTIPY_REDIRECT_URI')

    if not client_id:
        print('''
            You need to set your Spotify API credentials. You can do this by
            setting environment variables like so:

            export SPOTIPY_CLIENT_ID='your-spotify-client-id'
            export SPOTIPY_CLIENT_SECRET='your-spotify-client-secret'
            export SPOTIPY_REDIRECT_URI='your-app-redirect-url'

            Get your credentials at     
                https://developer.spotify.com/my-applications
        ''')
        raise spotipy.SpotifyException(550, -1, 'no credentials set')

    sp_oauth = oauth2.SpotifyOAuth(client_id, client_secret, redirect_uri, 
        scope=scope, cache_path=".cache-" + username )

    # try to get a valid token for this user, from the cache,
    # if not in the cache, the create a new (this will send
    # the user to a web page where they can authorize this app)

    token_info = sp_oauth.get_cached_token()

    if not token_info:
        print('''

            User authentication requires interaction with your
            web browser. Once you enter your credentials and
            give authorization, you will be redirected to
            a url.  Paste that url you were directed to to
            complete the authorization.

        ''')
        auth_url = sp_oauth.get_authorize_url()
        try:
            webbrowser.open(auth_url)
            print("Opened %s in your browser" % auth_url)
        except:
            print("Please navigate here: %s" % auth_url)

        print()
        print()
        try:
            response = raw_input("Enter the URL you were redirected to: ")
        except NameError:
            response = input("Enter the URL you were redirected to: ")

        print()
        print() 

        code = sp_oauth.parse_response_code(response)
        token_info = sp_oauth.get_access_token(code)
    # Auth'ed API request
    if token_info:
        return token_info['access_token']
    else:
        return None

and this is how I get the token:

def getNewAccessToken():

    token = util.prompt_for_user_token(spotifyUserId,scope,client_id=clientId,client_secret=clientSecret,redirect_uri=redirect_uri)
    if token:
        return token
    else:
        raise Exception("Can't get token")

I am new to Spotipy so maybe i am doing something incorrectly but according to the documentation this seems to be the correct way of doing it ! Any help would be appreciated

felix-hilden commented 4 years ago

Does it work if you print the link and manually navigate to the page? Then it might be webbrowser at fault, in which case you could construct another version of the function yourself. However, if you are talking about an automatic login, that's Spotify remembering that you already gave permission to the app. Changing scope might require another login. But in that case, printing the link and opening it in a private window might do the trick!

grantbrewster commented 4 years ago

It seems like the prompt correctly opening a Spotify auth is pretty buggy, but honestly might be on the chrome side of things opposed to the the Spotipy side. Sometimes it works, and other times it does not even if both the local/chrome cache are deleted. The only thing that spotipy caches in this function is the user token correct? Thanks for the quick reply!

felix-hilden commented 4 years ago

For me, when I use an equivalent routine (without token caching, mind you), the redirects are automatic yielding the final redirect url with code immediately. But it works as expected consistently. I think it is a Spotify login session thing before anything else. Can't really speak for you if you think there is something else happening. I'm on Windows 10 and Firefox.

Yes, only the token is cached.

stephanebruckert commented 4 years ago

Your browser is still connected to your spotify account, just go to https://www.spotify.com/ and log out