Been working on a spotify / spotipy application which will add the current song to a certain playlist.
My functions for getting the current song and showing a playlist are all doing fine. My function for adding a song to a playlist is not.
I am getting the following error in my IDE:
http status: 405, code:-1 - https://api.spotify.com/v1/users/myUserID/playlists/myPlayListID/tracks:
error
When i copy paste the link to the browser i am getting the following error:
{
"error": {
"status": 401,
"message": "No token provided"
}
}
As far as i'm aware i'm providing a token.
Here is my function which makes the spotify object
def __createSpotifyObject(self):
"""Will create a spotify object and return it"""
# Defining the scope(s) of the application
scope = "playlist-modify-public playlist-modify-private user-read-currently-playing"
# Getting the token
token = util.prompt_for_user_token(username=USER_NAME, scope=scope, client_id=CLIENT_ID, client_secret=CLIENT_SECRET, redirect_uri="https://localhost/")
# Returning our spotify object
return spotipy.Spotify(auth=token)
Here is the function which tries to add a song to my playlist (this is where the error occurs)
I've tried catching the exception (which it did) and then trying to make a new spotify object so it will refresh the token or something like that. It just gives me the same error.
def addCurrentSongToSelectedPlaylist(self):
"""Will add the currently playing song to the selected playlist"""
# Checking if a playlist has been selected
if (len(self.__selectedPlaylist ) < 1):
print("No playlist selected")
return
# Getting the current song
currentSong = self.getCurrentSong()
# Adding the current song id to the selected playlist
try:
self.__spotify.user_playlist_add_tracks(USER, self.__selectedPlaylist, [currentSong["id"]])
except spotipy.client.SpotifyException:
# Re authenticating
self.__spotify = self.__createSpotifyObject()
self.__spotify.user_playlist_add_tracks(USER, self.__selectedPlaylist, [currentSong["id"]])
At this point the only thing I can think of is that the show playlist / show current playing song actions require less permission and that is why they work and the add song to playlist won't.
Found out i implemented the user wrong. instead of username?si=someNumbers i needed to just enter the username.
Edit:
Copy and pasting the adress of the error msg in to the browser is useless since it is a api call and it will always give back 401: no token provided due to trying to access it without a token.
Just stumbled across this beautifull list of what every error code means. https://developer.spotify.com/documentation/web-api/ This doesn't just apply to the web api but also to the Spotipy library. Check the error code in your IDE or editor against the list on this page.
Related
I have a list of dictionaries that contain album information which I'm trying to use to search within Spotify and then add to users' saved albums. I tried following the examples given in the spotipy documentation, however, I'm getting an issue when using the search function via spotipy.
SCOPE = 'user-library-modify'
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI, scope=SCOPE))
for album in newMusic:
albumName = album["Title"]
artistName = f"{album['Last Name']}+{album[' First Name']}"
getRecord = sp.search(q = f"artist:{artistName}&album:{albumName}", type='album')
print(getRecord)
I provided the redirect url when prompted after running, but this results in a 401 response for each album result as such:
{
"error": {
"status": 401,
"message": "No token provided"
}
}
I have the .cache file with the access and refresh tokens but it still says no token is provided. I thought maybe I was entering the query incorrectly, but I don't see anything wrong. This is how an example end url looks:
https://api.spotify.com/v1/search?query=artist:band+name&album:album+name&type=album&offset=0&limit=10
What am I doing wrong here? How can I get my access code recognized?
Found the issue; the query entry format was wrong. I found this answer to a past question that explains my problem: Using python to get a track from the spotify API by using search Endpoint
The artist, album, etc. do not need to be declared separately (e.g. "artist: _", "album: _"). They should just be combined together like:
https://api.spotify.com/v1/search?query=first+name+last+name+album+title&type=album&offset=0&limit=10
Weirdly, this contradicts what is in the Spotify API documentation where an example query value is given as such:
Example value:
"remaster%20track:Doxy+artist:Miles%20Davis"
https://developer.spotify.com/documentation/web-api/reference/#/operations/search
I am trying to add tracks to one of my Spotify playlists, and I'm pretty sure I have all of the code exactly right as described in the Spotipy documentation:
username = '*myusername*'
scope = 'playlist-modify-public'
playlist_id = '*myplaylistid*'
track_ids = *array of track ids*
token = util.prompt_for_user_token(username,
scope,
client_id='*myclientid*',
client_secret='*mysecretclientid*',
redirect_uri='http://localhost:8888/callback/')
spotify = spotipy.Spotify(auth=token)
results = spotify.user_playlist_add_tracks(username, playlist_id, track_ids)
However, these are the following errors two errors that I receive no matter what I try:
HTTPError: 400 Client Error: Bad Request for url: https://api.spotify.com/v1/users/*myusername*/playlists/*myplaylist*/tracks
During handling of the above exception, another exception occurred:
SpotifyException: http status: 400, code:-1 - https://api.spotify.com/v1/users/*myusername*/playlists/*myplaylist*/tracks:
Invalid track uri: spotify:track:*trackid*
It specifies Invalid track uri, however for each of the tracks in my list I have tested by searching the uri in Spotify and it is indeed valid.
Solutions I have tried to no avail:
1. Changing between ID and URIs for both playlists and track list
2. Authenticating using OAuth
3. Using different playlists and tracks
4. Using different redirect_uri
5 example track URIs for reference:
spotify:track:1rdHsnsGmleo6MRctkkFmm?si=7R0IKQ9xTgiwfLAJO7eFCw
spotify:track:70CMnzQ3FjMmUk5NPdQJBe?si=qL_WwgWVRTaSZ2oOBg2eCA
spotify:track:6bbx7nYlixYuElKMbYCzMm?si=Wu64S-obRaOOh3mFP3zWwA
spotify:track:6DZNQKNUskiWVSXs3cQPk3?si=SIW3hBU1SiWd_h1gpXwijg
spotify:track:2FMPIU8FdP9kCi5kUCSGnE?si=jtJOkQhsSF6GoD3otgtV3A
Would appreciate any help!! Thank you
The track URIs should not contain ?si= but only what's before that. See https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids
You can fix your code to only keep the first part:
track_uris = [uri.split("?si=")[0] for uri in track_uris]
I'm working on a program that checks if a song is already in a playlist, and then it will add the song if it is not in the playlist.
I am able to get all of the track IDs from the playlist, but then I am unable to add a new song to the playlist.
This is the code I use to get the playlist track IDs, which works without any issues:
def get_playlist_tracks(username_gpt, playlist_id_gpt, sp_gpt):
track_ids = []
try:
results_gpt = sp_gpt.user_playlist_tracks(username_gpt, playlist_id_gpt)
tracks = results_gpt['items']
while results_gpt['next']:
results_gpt = sp_gpt.next(results_gpt)
tracks.extend(results_gpt['items'])
for x in range(len(tracks)):
track_ids.append(tracks[x]['track']['id'])
except Exception as e_gpt:
print(e_gpt)
return track_ids
This is the code that is supposed to add a new track to the playlist, if the track ID isn't already in the playlist:
if not TrackInPlaylist:
try:
sp.user_playlist_add_tracks(username, playlist_id, track_id)
track_IDs.append(track_id[0])
print("Track Added to Playlist!")
except Exception as e:
print(e)
print("failed add")
The error I get when trying to add a track is this:
"error": {
"status": 401,
"message": "No token provided"
}
If I don't use the get_playlist_tracks() function, then I am able to add songs to the playlist without any issues.
I may be late but looks like the problem is the type of authorization you need to perform this, you will need to get an oauth2 access token with scopes as:
user-read-private
user-read-email
playlist-read-private
playlist-modify-public
playlist-modify-private
as explained in here https://developer.spotify.com/documentation/general/guides/authorization-guide/
and pass the access token in the call to add the track
I have this function in Python to get media id of the post from its URL provided:
def get_media_id(self):
req = requests.get('https://api.instagram.com/oembed/?url={}'.format(self.txtUrl.text()))
media_id = req.json()['media_id']
return media_id
When I open the result URL in the browser it returns data but in the code the result is "404 not found"
For example consider this link:
https://www.instagram.com/p/B05bitzp15CE8e3Idcl4DAb8fjsfxOsSUYvkDY0/
When I put it in the url the result is:
But when I run the same in this function it returns 404 error
I tried running your code and assuming that self.txtUrl.text() there is nothing wrong with your code. The problem is that you are trying to get access to a media id of a private account without the access token.
The reason that you are able to open that link in the browser is due to the fact that you are likely logged into that account or are following it. To use the method you have given, you would need a public instagram post, for example try setting txtUrl.text() = https://www.instagram.com/p/fA9uwTtkSN/. Your code should work just fine.
The problem is that your GET request doesn't have any authorisation token to gain access to the post. Other people have written answers to how to get the media_id if you have the access token here: Where do I find the Instagram media ID of a image (having access token and following the image owner)?
I am trying to create a set on Quizlet.com, using its API found here: https://quizlet.com/api/2.0/docs/sets#add
Here is my code of a set I am trying to create:
import requests
quizkey = my_client_id
authcode = my_secret_code # I'm not sure if I need this or not
data = {"client_id":quizkey, "whitespace":1, "title":"my-api-set",
"lang_terms":"it", "lang_definitions":"en",
"terms":['uno','due'], "definitions":["one","two"]}
apiPrefix = "https://api.quizlet.com/2.0/sets"
r = requests.post(url=apiPrefix, params=data)
print r.text
The response is:
{
"http_code": 401,
"error": "invalid_scope",
"error_title": "Not Allowed",
"error_description": "You do not have sufficient permissions to perform the requested action."
}
I also tried "access_token":authcode instead of "client_id":quizkey, but this resulted in the error: "You do not have sufficient permissions to perform the requested action."
How can I fix this and not get a 401 error?
Alright so 3 and a half years later (!!) I've looked into this again and here's what I've discovered.
To add a set you need an access token - this is different to the client_id (what I call quizkey in my code), and to be quite honest I don't remember what authcode in my code is.
This token is obtained by going through the user authentication flow. To summarise it:
Send a POST request to https://quizlet.com/authorize like so:
https://quizlet.com/authorize?response_type=code&client_id=MY_CLIENT_ID&scope=read&state=RANDOM_STRING
Keep the response_type as code, replace client_id with your client_id, keep the scope as read, and state can be anything
I believe this requires human intervention because you're literally authorising your own account? Not sure of another way...
You'll receive a response back with a code
Let's call this RESPONSE_CODE for now
Send a POST request to https://api.quizlet.com/oauth/token, specifying 4 mandatory parameters:
grant_type="authorization_code" (this never changes)
code=RESPONSE_CODE
redirect_uri=https://yourredirecturi.com (this can be found at your personal API dashboard)
client ID and secret token separated by a colon and then base64-encoded (the user authentication flow link above tells you what this is if you don't want to do any of the encoding)
You'll receive the access_token from this API call
Now you can use that access_token in your call to create a set like I've done above (just replace "client_id":quizkey with "access_token":access_token)
You will need to authenticate in order to make sets. This link gives an overview:
https://quizlet.com/api/2.0/docs/making_api_calls
And this one provides details about the authentication process:
https://quizlet.com/api/2.0/docs/authorization_code_flow