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

Empty calls to currently_playing, current_user_playing_track raise an exception: #530

Closed
MikeiLL opened this issue Jul 6, 2020 · 7 comments

Comments

@MikeiLL
Copy link
Contributor

MikeiLL commented Jul 6, 2020

Playing with App.py:

"""
credentials.py looks like
SPOTIPY_CLIENT_ID='bla bla bla'
SPOTIPY_CLIENT_SECRET='bla bla bla'
SPOTIPY_REDIRECT_URI='http://127.0.0.1:8080'
"""

import os
from flask import Flask, session, request, redirect
from flask_session import Session
import spotipy
import credentials

app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(64)
app.config['SESSION_TYPE'] = 'filesystem'

Session(app)

CACHE = ".cache-" + "test"
SCOPE = None
# user-top-read user-library-read playlist-read-public user-follow-read
auth_manager = spotipy.oauth2.SpotifyOAuth(credentials.SPOTIPY_CLIENT_ID, credentials.SPOTIPY_CLIENT_SECRET, credentials.SPOTIPY_REDIRECT_URI, scope=SCOPE, show_dialog=True, cache_path=CACHE)
spotify = spotipy.Spotify(auth_manager=auth_manager)


@app.route('/')
def index():
    if request.args.get("code"):
        session['token_info'] = auth_manager.get_access_token(request.args["code"])
        return redirect('/')

    if not session.get('token_info'):
        auth_url = auth_manager.get_authorize_url()
        return f'<h2><a href="{auth_url}">Sign in</a></h2>'

    return f'<h2>Hi {spotify.me()["display_name"]}, ' \
           f'<small><a href="/sign_out">[sign out]<a/></small></h2>' \
           f'<a href="/playlists">my playlists</a> | ' \
           f'<a href="/currently_playing">currently playing</a> | ' \
           f'<a href="/current_user">me</a> | ' \

# some code ommited
        
@app.route('/currently_playing')
def current_playing_track():
	if not session.get('token_info'):
		return redirect('/')
	else:
		return spotify.current_user_playing_track()   # or spotify.currently_playing()
		     
@app.route('/current_user')
def current_user():
	if not session.get('token_info'):
		return redirect('/')
	else:
		return spotify.current_user()

And here's the whole stack:


Traceback (most recent call last)
File "/MyEnv/pyspotify/lib/python3.7/site-packages/spotipy/client.py", line 175, in _internal_call

    response.raise_for_status()

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/requests/models.py", line 941, in raise_for_status

    raise HTTPError(http_error_msg, response=self)

    During handling of the above exception, another exception occurred:
    File "/MyEnv/pyspotify/lib/python3.7/site-packages/flask/app.py", line 2464, in __call__

    return self.wsgi_app(environ, start_response)

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/flask/app.py", line 2450, in wsgi_app

    response = self.handle_exception(e)

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/flask/app.py", line 1867, in handle_exception

    reraise(exc_type, exc_value, tb)

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise

    raise value

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app

    response = self.full_dispatch_request()

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request

    rv = self.handle_user_exception(e)

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception

    reraise(exc_type, exc_value, tb)

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise

    raise value

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request

    rv = self.dispatch_request()

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request

    return self.view_functions[rule.endpoint](**req.view_args)

    File "/MyEnv/pyspotify/app.py", line 66, in current_playing_track

    return spotify.current_user_playing_track()

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/spotipy/client.py", line 843, in current_user_playing_track

    return self._get("me/player/currently-playing")

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/spotipy/client.py", line 210, in _get

    return self._internal_call("GET", url, payload, kwargs)

    File "/MyEnv/pyspotify/lib/python3.7/site-packages/spotipy/client.py", line 190, in _internal_call

    headers=response.headers,

    spotipy.exceptions.SpotifyException: http status: 401, code:-1 - https://api.spotify.com/v1/me/player/currently-playing:
     Permissions missing
    

Am expecting that I should be sending some other argument

@stephanebruckert
Copy link
Member

stephanebruckert commented Jul 6, 2020

You have SCOPE=None?

The access token must have the user-read-currently-playing and/or user-read-playback-state scope authorized in order to read information.
https://developer.spotify.com/documentation/web-api/reference/player/get-the-users-currently-playing-track/

@MikeiLL
Copy link
Contributor Author

MikeiLL commented Jul 6, 2020

Correct. And Duh! It needs to be user-read-currently-playing.

I'm a little unclear on where to look for how to handle tokens. Would the app, potentially store (and when necessary replace) different tokens for different tasks?

Does the request only accept a single scope at a time?

@MikeiLL
Copy link
Contributor Author

MikeiLL commented Jul 6, 2020

This is interesting. When I run the example with a the main scope as user-read-currently-playing, it returns an Address Already in Use error and look, it seems to, indeed, be running twice on the same port:

$ ps -fA | grep python
  501 19517 15945   0  3:25PM ttys025    0:00.25 /usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python -m flask run --port=8080
  501 19518 19517   0  3:25PM ttys025    0:00.28 /usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python -m flask run --port=8080

Update

But that's not what's causing the error, as it runs two threads with a scope of None as well, which doesn't give the same error.

@MikeiLL
Copy link
Contributor Author

MikeiLL commented Jul 7, 2020

The cause of this problem is that there needs to be, if I am understanding correctly, a new spotipy.oauth2.SpotifyOAuth for each new scope.

I am seeing that multiple scopes is possible, but I'm not sure what that would look like.

In my case, so far, I only need a single scope, so once I logged out, I was able to instantiate the single spotipy.oauth2.SpotifyOAuth with the required scope.

I wonder if the demo, app.py, should be one that includes a specific scope, for example:

# code omitted for now
auth_manager = spotipy.oauth2.SpotifyOAuth(scope='user-read-currently-playing', 
									show_dialog=True, 
									cache_path=CACHE)

# more code omitted

@app.route('/currently_playing')
def current_playing_track():
	if not session.get('token_info'):
		return redirect('/currently_playing')
	else:
		cur_track = spotify.current_user_playing_track()
		if not cur_track:
			return f'Seems there is no currently playing track.'
		else:
			return cur_track

If that seems useful, I'll be happy to send a pr.

@stephanebruckert
Copy link
Member

stephanebruckert commented Jul 12, 2020

Answered the multiple scopes issue here #537 – I don't think it needs a different spotipy.oauth2.SpotifyOAuth for each scope

Answered to you about the "missing cache or username" problem here #529 (comment) – you were right, something is wrong. For that problem we can use this issue #533

I agree the script could show an example that uses scopes (just one or multiple), please do open a PR if you get this working!

@stephanebruckert
Copy link
Member

@MikeiLL do you still have the "permissions missing" issue or can we close the current issue and focus on #537 only?

@MikeiLL
Copy link
Contributor Author

MikeiLL commented Jul 12, 2020

Closing this one, as the problem was setting scope to None, when making requests that require user-read-currently-playing (i think there's a second scope that also grants permissions for current_user_playing_track.)

@MikeiLL MikeiLL closed this as completed Jul 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants