I am trying to understand Spotipy library to create some programs for personal use. Initially I have tried and access Spotify using "Client Credentials Flow" but since "Authorization Code Flow" seems more suited for my use cases currently focused on that.
I believe I have managed to implement the basic flow that checks whether there is a cached token or not. If there is not any cached token, tries to get new one and cache the new token.
The issue is when I try to get currently playing song or user info, API returns "Only valid bearer authentication supported" error. I understand that Spotify API fires this exeption either using non valid token or bearer token does not have the required scope. But still cannot find the issue.
My Client ID, Client Secret and Redirect URI defined as environmental variables.
You can find the code and its output below. (There might be some non-Pythonesque use in the code, I am open to the any suggestions that refines my python skills.)
CODE:
import spotipy
from spotipy import oauth2
from spotipy import cache_handler
import requests
import json
from pprint import pprint
oAuthscope = "user-read-email,user-read-private,user-library-read,user-read-playback-state,user-modify-playback-state,user-read-currently-playing"
Sp_Cache = cache_handler.CacheFileHandler()
auth_manager = spotipy.SpotifyOAuth(scope=oAuthscope,cache_handler=Sp_Cache)
Sp_oAuth = spotipy.Spotify(auth_manager)
def init_Spotify_Session():
#Define access_token variable
access_token = ""
print ("\n Access_Token variable defined!")
#Try to get cached token
print ("\n Trying to get cached token!")
Token_Data = Sp_Cache.get_cached_token()
if Token_Data is not None:
print ("\n Cached Token = \n")
pprint (Token_Data )
print ("\n\n\n")
else :
print ("There is no cached token!!! Token cannot be printed!!")
if not Token_Data:
print ("There is not any cached token!")
authorisation_url = auth_manager.get_authorize_url()
print ("\n Authorisation URL retrieved = " + authorisation_url)
print ("\n Trying to get authorisation response:")
oAuth_Response = auth_manager.get_auth_response()
print ("\n oAuthResponse= ")
print (type(oAuth_Response))
print("\n oAuth_Response = " + oAuth_Response + "\n")
#Sp_Cache.save_token_to_cache(oAuth_Response)
#auth_Token = auth_manager.get_authorization_code(oAuth_Response)
#print ("\n CODE = \n" + auth_Token + "\n")
print ("\n\n\n Trying to get new access token!!! \n\n\n")
Token_Data = auth_manager.get_access_token(code=oAuth_Response)
access_token = Token_Data["access_token"]
print ("\n Access Token = \n")
pprint (Token_Data)
print ("\n\n\n")
pprint (access_token)
print ("\n\n\n")
Sp_Cache.save_token_to_cache(Token_Data)
print("\n Cached New Token = ")
print(Sp_Cache.get_cached_token()),print ("\n\n\n")
def Get_Current_Song():
global song_current_track, artist_current_track, cover_art_url
try:
response_current_track = Sp_oAuth.current_user_playing_track() # Gets response of currently playing track
song_current_track = response_current_track["item"]["name"]
artist_current_track = response_current_track["item"]["album"]["artists"][0]["name"]
cover_art_url = response_current_track ["item"]["album"]["images"][0]["url"]
#cover_art = urllib.request.urlretrieve(cover_art_url, "downloaded.jpg")
cover_art = requests.get(cover_art_url, "downloaded.jpg") ##gpt suggestion
#cover_art = Image.open("downloaded.jpg")
#cover_art.show()
print("cover art downloaded!!!")
#pprint(response_current_track) #prints whole response json
print("**************************")
print("Currently Playing:")
pprint(song_current_track) #prints current song title
pprint(artist_current_track) #prints current song artist
print("**************************")
except TypeError:
print(" ")
print ("Error Occured Details Below:")
print(" ")
print("!!!Check if spotify playing!!!")
print(" ")
#traceback.print_exc()
return song_current_track, artist_current_track, cover_art, cover_art_url
#Get_Current_Song(
def Get_Queued_Song():
global song_next_track, artist_next_track
try:
response_queued_track = Sp_oAuth.queue() #print(json.dumps(results, indent=4)) #Prints out json of
#print(list(response_queued_track.keys()))
#print("____________________________________________")
song_next_track = response_queued_track["queue"][0]["name"]
artist_next_track = response_queued_track["queue"][0]["artists"][0]["name"]
print("**************************")
print("Coming on Next:")
pprint(song_next_track) #prints current song title
pprint(artist_next_track) #prints current song artist
print("**************************")
except:
print(" ")
print ("Error Occured Details Below:")
print(" ")
print("!!!Check if spotify queue is empty!!!")
print(" ")
#traceback.print_exc()
return song_next_track, artist_next_track
init_Spotify_Session()
Get_Current_Song()
OUTPUT:
Access_Token variable defined!
Trying to get cached token!
Cached Token =
{'access_token': 'BQBVdYQaXUI24UZ_f_ttkSYWtRQWc0MGq3zXryEwtYBCBFLUH5AxC-aOnlmz8FmlqHZ7xveU7VeI95whGeitSb6iVuGAydalYcSaDwXFZwxRn24GZpUYYSji09QXaTKSzcTgFV_HtmS3hylvthXM9hAI6AIks1iLA4aU2axT1BjBToiQVagEzqq4pUkgaxHlfLgaIgmTMHe0Lq0mQTTI2Q',
'expires_at': 1680096145,
'expires_in': 3600,
'refresh_token': 'AQCXYYFHq3Xs-DYHsWZHq-TnDAW1OZ-W8TaYqZdSV6LBlJQH6VYqnwrYuEKxy4nsMoMaLHGHxxb8Vf4LZjnkm3E4TRq1QtZ3n5vFg7mZLzTdFaEgPiZhkVBVyRIEL5yW3TY',
'scope': 'user-library-read user-modify-playback-state '
'user-read-currently-playing user-read-email '
'user-read-playback-state user-read-private',
'token_type': 'Bearer'}
HTTP Error for GET to https://api.spotify.com/v1/me/player/currently-playing with Params: {} returned 400 due to Only valid bearer authentication supported
Traceback (most recent call last):
File "C:\Users\erensan\AppData\Roaming\Python\Python310\site-packages\spotipy\client.py", line 269, in _internal_call
response.raise_for_status()
File "C:\Users\erensan\AppData\Roaming\Python\Python310\site-packages\requests\models.py", line
1021, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://api.spotify.com/v1/me/player/currently-playing
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\erensan\Desktop\Python Dev\Spotipy\oAuth\Spotipy_oAuth_eren2.py", line 141, in <module>
Get_Current_Song()
File "C:\Users\erensan\Desktop\Python Dev\Spotipy\oAuth\Spotipy_oAuth_eren2.py", line 78, in Get_Current_Song
response_current_track = Sp_oAuth.current_user_playing_track() # Gets response of currently playing track
File "C:\Users\erensan\AppData\Roaming\Python\Python310\site-packages\spotipy\client.py", line 1230, in current_user_playing_track
return self._get("me/player/currently-playing")
File "C:\Users\erensan\AppData\Roaming\Python\Python310\site-packages\spotipy\client.py", line 321, in _get
return self._internal_call("GET", url, payload, kwargs)
File "C:\Users\erensan\AppData\Roaming\Python\Python310\site-packages\spotipy\client.py", line 291, in _internal_call
raise SpotifyException(
spotipy.exceptions.SpotifyException: http status: 400, code:-1 - https://api.spotify.com/v1/me/player/currently-playing:
Only valid bearer authentication supported, reason: None
PS C:\Users\erensan\Desktop\Python Dev\Spotipy\oAuth>
I have tried the code with clearing the cache, and adding additional scope to the auth_manager but the result is the same.
You missed two items
#1 it needs to set the environment variables for spotipy
os.environ["SPOTIPY_CLIENT_ID"] = "<your client ID>"
os.environ["SPOTIPY_CLIENT_SECRET"] = "<your client Secret>"
os.environ["SPOTIPY_REDIRECT_URI"] = "<your App's registered redirect URI>"
#2 Spotify() class correct assign initialize with input argument
From
spotipy.Spotify(auth_manager)
To
spotipy.Spotify(auth_manager=auth_manager)
Demo code
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from spotipy import cache_handler
import os
from pprint import pprint
# Set your Spotify API credentials as environment variables, it will pick by spotipy API
os.environ["SPOTIPY_CLIENT_ID"] = "<your client ID>"
os.environ["SPOTIPY_CLIENT_SECRET"] = "<your client Secret>"
os.environ["SPOTIPY_REDIRECT_URI"] = "<your App's registered redirect URI>"
# multiple scopes
oAuthscope = "user-read-email,user-read-private,user-library-read,user-read-playback-state,user-modify-playback-state,user-read-currently-playing"
Sp_Cache = cache_handler.CacheFileHandler()
auth_manager = spotipy.SpotifyOAuth(scope=oAuthscope,cache_handler=Sp_Cache)
Sp_oAuth = spotipy.Spotify(auth_manager=auth_manager)
def init_Spotify_Session():
access_token = ""
print ("\n Access_Token variable defined!")
Token_Data = Sp_Cache.get_cached_token()
if Token_Data is not None:
print ("\n Cached Token = \n")
pprint (Token_Data )
print ("\n")
else :
print ("There is no cached token!!! Token cannot be printed!!")
if not Token_Data:
print ("There is not any cached token!")
authorisation_url = auth_manager.get_authorize_url()
print ("\n Authorisation URL retrieved = " + authorisation_url)
print ("\n Trying to get authorisation response:")
oAuth_Response = auth_manager.get_auth_response()
print ("\n oAuthResponse= ")
print (type(oAuth_Response))
print("\n oAuth_Response = " + oAuth_Response + "\n")
print ("\n Trying to get new access token!!! \n")
Token_Data = auth_manager.get_access_token(code=oAuth_Response)
access_token = Token_Data["access_token"]
print ("\n Access Token = \n")
pprint (Token_Data)
pprint (access_token)
Sp_Cache.save_token_to_cache(Token_Data)
print("\n Cached New Token = ")
print(Sp_Cache.get_cached_token()),print ("\n")
def Get_Current_Song():
response_current_track = Sp_oAuth.current_user_playing_track()
if response_current_track is not None and response_current_track["item"] is not None:
song = response_current_track["item"]
print(song['artists'][0]['name'], " – ", song['name'])
init_Spotify_Session()
Get_Current_Song()
Also you don't necessary to handle a token by your self.
spotipy
works for you.
If not exist .cache
, will launch browser and login spotify
for getting token.
If exit '.cache, then skip login and pick up the token from
.cache` file.
.cache
will includes six information
(access_token
, token_type
, expires_in
, refresh_token
, scope
and expires_at
)
This simple code
import spotipy
from spotipy.oauth2 import SpotifyOAuth
import os
# Set your Spotify API credentials as environment variables, it will pick by spotipy API
os.environ["SPOTIPY_CLIENT_ID"] = "<your client ID>"
os.environ["SPOTIPY_CLIENT_SECRET"] = "<your client Secret>"
os.environ["SPOTIPY_REDIRECT_URI"] = "<your App's registered redirect URI>"
# multiple scopes
oAuthscope = "user-read-email,user-read-private,user-library-read,user-read-playback-state,user-modify-playback-state,user-read-currently-playing"
Sp_oAuth = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=oAuthscope))
def Get_Current_Song():
response_current_track = Sp_oAuth.current_user_playing_track()
if response_current_track is not None and response_current_track["item"] is not None:
song = response_current_track["item"]
print(song['artists'][0]['name'], " – ", song['name'])
Get_Current_Song()