Closed joebonneau closed 3 years ago
I'm not totally sure I understand. When signing in a user from a Spotify app (here, your CLI), the user has to get redirected to the Spotify login window at least once to prove authentication and generate a token. Are you trying to avoid that?
This particular feature (open_browser
) is useful in case the machine doesn't have a browser installed (for example you ssh into a remote machine). But the user still has to open the browser somewhere else, on another machine.
the user has to get redirected to the Spotify login window at least once to prove authentication and generate a token. Are you trying to avoid that?
My intent was to have the user be redirected one time to generate the token and then avoid any browser involvement on the user end beyond that. I'm thinking the issue I'm running into here is related to the way that I'm implementing the authentication. For some context, I submitted this question on Stack Overflow yesterday because I was having trouble passing the auth object to other commands. To get around that, I created a function connect
that is called with every command:
def connect(
scope: str,
client_id: str = SPOTIFY_CLIENT_ID,
client_secret: str = SPOTIFY_CLIENT_SECRET,
redirect_uri: str = SPOTIFY_REDIRECT_URI,
) -> sp.Spotify:
try:
auth = sp.Spotify(
auth_manager=SpotifyOAuth(
scope=scope,
client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri,
)
)
return auth
except:
click.secho(
"API authorization failed! Did you remember to set the environment variables?",
fg="red",
)
where the specific scope
required for the action is passed in. Example below:
def next_track():
sp_auth = connect(scope=USER_MODIFY_PLAYBACK_STATE)
sp_auth.next_track()
get_current_playback(display=True)
After reading your response, I'm guessing that my issue is due to the fact that a new authentication is happening with each call which requires the browser to open. Maybe the real question here is how to pass around the auth
object so that I can change the implementation in the app.
Normally passing around sp_auth
is the way to do it, so you would do:
sp_auth = connect(scope=USER_MODIFY_PLAYBACK_STATE) # only once
next_track(sp_auth)
next_track(sp_auth)
next_track(sp_auth)
def next_track(sp_auth):
sp_auth.next_track()
get_current_playback(display=True)
So there is no need to connect multiple times, even though that still shouldn't open a new browser window every time, since the token is stored on the hard drive and spotipy is able to find the previous one. It doesn't seem to be the case. Can you verify that a hidden .cache
file is stored in the same folder of your script? What OS are you using? Something tells me that your script is not allowed to create files, but it should. Can you see any error message/warning in the logs when running the script?
The method you mentioned was how I initially assumed I'd accomplish what I was trying to do, but it wasn't working in context of the click
package I'm using to design the CLI. Maybe I need to go back to the drawing board on that piece.
There is a hidden .cache
file that is generated and stored in the same folder as my script. I'm running on an Ubuntu machine. I don't see any specific error or warning other than that a GET
or POST
request was denied if authentication was unsuccessful.
To confirm whether the issue is in spotipy or not, you could try this example https://github.com/plamere/spotipy/blob/master/examples/my_playlists.py
Just run it multiple times with:
SPOTIPY_CLIENT_ID=replace SPOTIPY_CLIENT_SECRET=replace SPOTIPY_REDIRECT_URI=http://localhost:8080 python3 my_playlists.py
and it should only open the browser once.
Was able to confirm that it's not a Spotipy issue at least!
Is there an example of how to make a new authorization if one doesn't exist or it's expired? Thinking I would both need to check if .cache
exists and then also validate the token information within.
an example of how to make a new authorization if one doesn't exist or it's expired
The my_playlists.py
example does that, as by default spotipy looks for an existing token and refresh it if it is expired.
It only gets more complicated when looking to deal with multiple users, in which case the API/web example is probably interesting as it does more "manual" stuff https://github.com/plamere/spotipy/blob/master/examples/app.py
But let me know your use case and I might be able to help
I was able to fix the browser issue by changing my implementation of the authorization and how that object is being passed around the various commands. It was mostly an issue with how I set things up, but your insight about how things should work was super helpful and led me to the answer.
Thanks for taking the time to help me out - I really appreciate it!
Hi there,
First and foremost, thanks so much for developing this package. Having a lot of fun using it!
I'm developing a CLI and I want to suppress the browser from opening without prompting the user for the URL. When authenticating using
SpotifyOAuth
and specifyingopen_browser=True
, the browser opens a new tab and immediately closes it (assuming that I already gave the API permission to that function on my account, otherwise that appears and persists).To avoid that, I tried specifying
open_browser=False
- here is what I get with this input (my application is calledspoticli
):Neither outcome is desirable for what I'd ideally want. Ideally, assuming the user has already given Spotify the proper permissions, the entire process is headless and seamless. Any thoughts on how to achieve this?
Thanks!