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

How to run entirely in a script? (no redirect url) #488

Closed
PAK90 opened this issue May 2, 2020 · 19 comments
Closed

How to run entirely in a script? (no redirect url) #488

PAK90 opened this issue May 2, 2020 · 19 comments

Comments

@PAK90
Copy link

PAK90 commented May 2, 2020

I'm trying to use this library to get recently played information from the API, and I will want this script to run automatically without any user intervention. Is it possible to do that with this library? Right now this is my code:

from spotipy.oauth2 import SpotifyOAuth
token = SpotifyOAuth(
	SPOTIFY_CLIENT_ID,
	SPOTIFY_CLIENT_SECRET,
	'localhost:8000',
	scope='user-read-recently-played',
	username='vacd7qnn09sx0dtj56qtwmix7'
	)

However when I run this it tries to open a window in my browser to get authentication working. The localhost:8000 url is fake, I don't actually have anything there, I just put it in so it would stop complaining about not receiving a redirect url.

What's the way to have this run without requiring manual intervention? I need this script to run by itself entirely. It seems that having the ID and secret should be enough...

@stephanebruckert
Copy link
Member

As opposed to the authorization code flow, you want the client credentials flow

@PAK90
Copy link
Author

PAK90 commented May 2, 2020

The docs tell me that Only endpoints that do not access user information can be accessed. I specifically want to access my user details, specifically which songs have been played. Is the documentation wrong and I will be able to access this info?

@stephanebruckert
Copy link
Member

Sorry I didn't see you needed user info. In that case you have to let the script prompt for sign in at least once so it can retrieve the token. The script should then be able to use the cached token and run without human intervention.

Currently the token is cached in a file. Different ways of persisting this token are discussed here #51

@busybox11
Copy link

Hey,
I'm using the same method on my daily driver.
I'm using spotipy to get the currently playing track and to control it on a polybar module that I created myself.
However, when I log on my computer, a browser window is always appearing with the localhost url and Spotify's code.
How to stop this behaviour ?

@stephanebruckert
Copy link
Member

@busybox11 interesting, do you have the code under hand? what exact URL does it open (do you have a screenshot)?

I assume that it's opening a browser window because it doesn't have a token, and your script needs a token to run. Do you know where the token is kept? Is it not persisted between computer sessions?

@busybox11
Copy link

Yes, it's opening a browser window. (Like, with the Spotify login thing).
I used a workaround that someone posted on Mano other issues (I use crontab to copy the cache file)
I can't send a screenshot since it's an almost-headless script (it can run apps tho, but it doesn't have an output)

@stephanebruckert
Copy link
Member

You shouldn't need crontab. A same token, once generated, can be refreshed an unlimited amount of time.

So just run your script outside of polybar once and you should be good after signing in

@busybox11
Copy link

Yeah, I did it.
But after each reboot (I don't really know but it's something like this) the cache file isn't being used anymore

@busybox11
Copy link

Nope, it's in the "polybar scripts" directory

@stephanebruckert
Copy link
Member

stephanebruckert commented May 4, 2020

Can you please check if the cached file is still there?

Edit: deleted my previous answer and you answered faster than me. Hmm ok, then you are right it shouldn't prompt for another signin

@stephanebruckert
Copy link
Member

stephanebruckert commented May 4, 2020

Do you have the code for this polybar spotipy script?

@busybox11
Copy link

Actually, I have two of them.
This is the script used to display the song currently being played.

import sys
import spotipy
import spotipy.util as util

client_id = 'CLIENT_ID'
client_secret = 'CLIENT_SECRET'
redirect_uri = 'http://localhost/'
scope = 'user-read-currently-playing user-modify-playback-state'

token = spotipy.util.prompt_for_user_token(
    'yha0gdu9143vclyk0cuqoro0m', scope, client_id, client_secret, redirect_uri)

def return_song():
    if current_song != None and current_song != "Spotify":
        print(current_song['item']['name'] + ' - ' + current_song['item']['artists'][0]['name'])
    else:
        if current_song == None:
            print('No song currently playing')
        else:
            print(current_song)

if token:
    sp = spotipy.Spotify(auth=token)
    try:
        current_song = sp.currently_playing()
    except:
        current_song = "Spotify"
    return_song()
else:
    print("Can't get token for", username)

@stephanebruckert
Copy link
Member

stephanebruckert commented May 4, 2020

util.prompt_for_user_token(
    'yha0gdu9143vclyk0cuqoro0m', scope, client_id, client_secret, redirect_uri)

this is a util that should not be used "in production". It should be ran "locally" only to generate the token and can only be ran once.

Instead of:

token = spotipy.util.prompt_for_user_token(
   'yha0gdu9143vclyk0cuqoro0m', scope, client_id, client_secret, redirect_uri)
sp = spotipy.Spotify(auth=token)

Do this:

from spotipy import SpotifyOAuth

creds = SpotifyOAuth(scope=scope, client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri)
sp = spotipy.Spotify(auth_manager=creds)

Hope that fixes it

@PAK90
Copy link
Author

PAK90 commented May 5, 2020

So I ran this:

token = util.prompt_for_user_token(
	'userstring'
	'user-read-recently-played',
	client_id=SPOTIFY_CLIENT_ID,
	client_secret=SPOTIFY_CLIENT_SECRET,
	redirect_uri='http://localhost:8080',
	)

After doing this successfully, I got a local .cache file. However, I don't know how to use this and refresh it accordingly? The docs also don't say. From your response above, I tried doing this:

creds = SpotifyOAuth(
	client_id=SPOTIFY_CLIENT_ID,
	client_secret=SPOTIFY_CLIENT_SECRET,
	redirect_uri='http://localhost:8080',
	scope='user-read-recently-played',
	)
token = creds.get_cached_token()
sp = spotipy.Spotify(auth=token)
user = sp.user('userstring')
print(sp.current_user_recently_played())

However I get a 400 Client Error: Bad Request for url: https://api.spotify.com/v1/users/userstring, Only valid bearer authentication supported.

How do I do this properly? (to be clear, I have my python file and the .cache file in the same directory)

@stephanebruckert
Copy link
Member

@PAK90 the token is refreshed automatically, so you don't need:

token = creds.get_cached_token()

Also you don't need util.prompt_for_user_token anymore, just do spotipy.Spotify(client_credentials_manager=creds).

Lately there has been a lot of changes around how we get the first token and refresh it. The doc might still need a round of updates to reflect that by deprecating util.prompt_for_user_token

@varna9000
Copy link

varna9000 commented May 17, 2020

H @stephanebruckert , do you know why the current playing song method hangs (actually all sp methods hang the code) ? The token seems to be got ok, as the line which hags the code is calling the currently_playing() method. Basically I'm using the spotipy.Spotify(client_credentials_manager=creds) auth method which you recommend here.

@stephanebruckert
Copy link
Member

stephanebruckert commented May 17, 2020

@varna9000 make sure you use the latest version of spotipy: pip install spotipy --upgrade. If the problem persists, please create a new issue with a minimal working example

@varna9000
Copy link

Ok, thanks. I've got the latest release. I'll open new issue.

@stephanebruckert
Copy link
Member

util.prompt_for_user_token is now deprecated and the docs now suggest to use the auth manager instead. Closing as all questions here should be answered

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants