Hey everyone! I’m working on a Python project to connect to the Spotify Web API and I keep running into this annoying 400 error. The authentication part seems to work fine, but when I try to make a search request I get an error saying “Only valid bearer authentication supported”.
Here’s my code:
import base64, requests
import datetime
from urllib.parse import urlencode
app_id = "your_app_id"
app_secret = "your_app_secret"
class MusicAPI(object):
token = None
token_expires = datetime.datetime.now()
token_expired = True
app_id = None
app_secret = None
auth_url = "https://accounts.spotify.com/api/token"
def __init__(self, app_id, app_secret, *args, **kwargs):
super().__init__(*args, **kwargs)
self.app_id = app_id
self.app_secret = app_secret
def encodeCredentials(self):
app_id = self.app_id
app_secret = self.app_secret
if app_id is None or app_secret is None:
raise Exception('App ID and secret are required')
credentials = f"{app_id}:{app_secret}"
encoded_creds = base64.b64encode(credentials.encode())
return encoded_creds.decode()
def buildAuthHeader(self):
encoded_creds = self.encodeCredentials()
return {
'Authorization': f"Basic {encoded_creds}"
}
def buildTokenData(self):
return {
"grant_type": "client_credentials"
}
def authenticate(self):
auth_url = self.auth_url
token_data = self.buildTokenData()
auth_header = self.buildAuthHeader()
response = requests.post(auth_url, data=token_data, headers=auth_header)
if response.status_code not in range(200, 299):
return False
current_time = datetime.datetime.now()
response_data = response.json()
token = response_data['access_token']
expires_in = response_data['expires_in']
expiry_time = current_time + datetime.timedelta(seconds=expires_in)
self.token = token
self.token_expires = expiry_time
self.token_expired = expiry_time < current_time
return True
music_client = MusicAPI(app_id, app_secret)
print(music_client.authenticate())
current_token = music_client.token
request_header = {
"Authorization": f"Bearer {current_token}"
}
search_endpoint = "https://api.spotify.com/v1/search"
query_params = urlencode({"q": "Love", "type": "track"})
full_url = f"{search_endpoint}?{query_params}"
response = requests.get(full_url, headers=request_header)
print(response.json())
The authentication returns True so that part works, but then I get this error: {'error': {'status': 400, 'message': 'Only valid bearer authentication supported'}}. Can someone help me figure out what I’m doing wrong? Thanks!