I'd like to retrieve the follower count of my Spotify playlist using Python. I've been searching https://developer.spotify.com/documentation/web-api/reference-beta/#category-playlists but haven't found a way to do so yet. However, I found a working code on how to retrieve the track IDs of a playlist, how could I tweak it to get the followers instead?
def getTrackIDs(user, playlist_id):
ids = []
playlist = sp.user_playlist(user, playlist_id)
for item in playlist['tracks']['items']:
track = item['track']
ids.append(track['id'])
return ids
ids = getTrackIDs('User', 'Playlist_Id')
print(len(ids))
print(ids)
Take a look at the playlist object that should be returned by getting a playlist.
https://developer.spotify.com/documentation/web-api/reference/object-model/#playlist-object-full.
It has the followers property which is a followers object which is located here
https://developer.spotify.com/documentation/web-api/reference/object-model/#followers-object.
The followers object contains the total property, which should be what you are looking for.
Although I cannot run your code, I imagine the result should look like the following. Let me know if this works for you (I can't run the code).
def getPlaylistFollowerCount(user, playlist_id):
playlist = sp.user_playlist(user, playlist_id)
return playlist['followers']['total']
Related
On spotipy's docs I can see that the only way it seems to be possible to search songs is by artist's name or title.
results = sp.search(q='weezer', limit=20)
for idx, track in enumerate(results['tracks']['items']):
print(idx, track['name'])
Is there any way to search by BPM,KEY and GENRE all togheter?
Yes there is! The endpoint https://api.spotify.com/v1/recommendations lets you get songs based on BPM, key and genre (and much more). You can provide Spotify with a target_key, target_tempo and up to 5 genres under seed_genres. Spotify then returns songs that fit the given parameters.
I'm trying to create a Python program to create Spotify playlists according to the user's "mood"; that is, the user chooses a specific mood and the program returns a playlist where the song's (taken from the user's saved tracks) features indicate that they match said mood. However, I'm running into the issue that the playlist is made up of the same song repeated 30 times, instead of 30 different songs. I'm fairly new to Python and programming in general, so maybe this isn't a very difficult problem, but I'm trying to see the issue and I am unable to.
Here is the route in my main code that refers to this issue (my full program has more routes, which all work fine so far). All other moods will be defined by other routes, but following the same logic. Any extra code that may be necessary in order to understand the issue better, I'll provide.
#app.route("/playlist_mood_angry")
def mood_playlist_angry():
# define mood and create empty track list
selected_mood = "Angry"
tracks_uris = [] # we need all the tracks uri to add to the future playlist
if 'auth_header' in session:
auth_header = session['auth_header']
# get user profile and saved tracks
user_profile_data = spotify.get_users_profile(auth_header)
user_id = user_profile_data["id"]
saved_tracks_data = spotify.get_user_saved_tracks(auth_header)
playlist_name = 'CSMoodlet: Angry'
playlist_description = "A playlist for when you're just pissed off and want a soundtrack to go with it. Automatically curated by CSMoodlet."
# go through saved tracks dictionary, get the tracks and for each one check if features average matches selected mood
for item in saved_tracks_data["items"]:
track = item["track"]
features = sp.audio_features(track['id'])
acousticness = features[0]['acousticness']
danceability = features[0]['danceability']
energy = features[0]['energy']
speechiness = features[0]['speechiness']
valence = features[0]['valence']
track_mood = spotify.define_mood(acousticness, danceability, energy, speechiness, valence)
# if the track's mood is "angry", if the list is not 30 tracks long yet, append it to the list
if track_mood == "Angry": #if track's mood is not Angry, it will go back to the for loop to check the next one (THIS DOESN'T WORK)
while len(tracks_uris) < 30:
track_uri = "spotify:track:{}".format(track['id'])
tracks_uris.append(track_uri)
# once it has gone through all saved tracks, create the playlist and add the tracks
new_playlist = spotify.create_playlist(auth_header, user_id, playlist_name, playlist_description)
new_playlist_id = new_playlist['id']
added_playlist = spotify.add_tracks_to_playlist(auth_header, new_playlist_id, tracks_uris)
playlist = spotify.get_playlist(auth_header, new_playlist_id)
tracks_data = []
for item in playlist["items"]:
track_data = item["track"]
tracks_data.append(track_data)
return render_template("created_playlist.html", selected_mood = selected_mood, playlist_tracks=tracks_data)
Any help would be deeply appreciated. Apologies if anything is badly explained, I am new to Stackoverflow and English is not my first language.
Found the error!
For anyone having issues with the same problem, I found that it was actually very simple. just substitute the while loop by an if loop, when checking the length of the playlist is less than 30.
Suppose I have a example Twitter account whose username is #testaccount and I want to grab the followers of the account #testaccount and with that also want to grab the followers of the users who follow #testaccount.
My problem is I don't know how to store this and map this into a database or into dict/list. If yes then how can I do it? Because I have to work with all data including the followers of followers.
For just an example say I have some data that looks like:
I want to store all these data in a way so that I can access each of them under each followers.
I would make a custom class, TwitterAccount:
class TwitterAccount:
def __init__(self, name):
this.name = name
this.followers = []
def addFollowers(self, followers):
this.followers.extend(followers)
# Will return a list of the followers.
def getFollowers(self):
return this.followers
# more functionality can be added
And you can use it like this:
acc0 = TwitterAccount("BradPitt")
acc1 = TwitterAccount("BradPittFan1")
acc2 = TwitterAccount("BradPittFan2")
acc3 = TwitterAccount("BradPittFan1Mother")
acc0.addFollowers([acc1,acc2])
acc1.addFollowers([acc3])
# more code
More on classes:
A nice tutorial and intro
Official docs
Miguel Grinberg has a very good tutorial on flask, where he also goes into detail on the follower/followed structure using SQL databases: https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-viii-followers
His solution is construct two tables, a user table which contains the user ID and posts, etc., and a auxiliary table, which maps user IDs (followed) to other user IDs (followers):
Image from https://blog.miguelgrinberg.com/static/images/mega-tutorial/ch08-followers-schema.png
On the Soundcloud API guide (https://developers.soundcloud.com/docs/api/guide#pagination)
the example given for reading more than 100 piece of data is as follows:
# get first 100 tracks
tracks = client.get('/tracks', order='created_at', limit=page_size)
for track in tracks:
print track.title
# start paging through results, 100 at a time
tracks = client.get('/tracks', order='created_at', limit=page_size,
linked_partitioning=1)
for track in tracks:
print track.title
I'm pretty certain this is wrong as I found that 'tracks.collection' needs referencing rather than just 'tracks'. Based on the GitHub python soundcloud API wiki it should look more like this:
tracks = client.get('/tracks', order='created_at',limit=10,linked_partitioning=1)
while tracks.collection != None:
for track in tracks.collection:
print(track.playback_count)
tracks = tracks.GetNextPartition()
Where I have removed the indent from the last line (I think there is an error on the wiki it is within the for loop which makes no sense to me). This works for the first loop. However, this doesn't work for successive pages because the "GetNextPartition()" function is not found. I've tried the last line as:
tracks = tracks.collection.GetNextPartition()
...but no success.
Maybe I'm getting versions mixed up? But I'm trying to run this with Python 3.4 after downloading the version from here: https://github.com/soundcloud/soundcloud-python
Any help much appreciated!
For anyone that cares, I found this solution on the SoundCloud developer forum. It is slightly modified from the original case (searching for tracks) to list my own followers. The trick is to call the client.get function repeatedly, passing the previously returned "users.next_href" as the request that points to the next page of results. Hooray!
pgsize=200
c=1
me = client.get('/me')
#first call to get a page of followers
users = client.get('/users/%d/followers' % me.id, limit=pgsize, order='id',
linked_partitioning=1)
for user in users.collection:
print(c,user.username)
c=c+1
#linked_partitioning means .next_href exists
while users.next_href != None:
#pass the contents of users.next_href that contains 'cursor=' to
#locate next page of results
users = client.get(users.next_href, limit=pgsize, order='id',
linked_partitioning=1)
for user in users.collection:
print(c,user.username)
c=c+1
I am using soundcloud api through python SDK.
When I get the tracks data through 'Search',
the track attribute 'playback_count' seems to be
smaller than the actual count seen on the web.
How can I avoid this problem and get the actual playback_count??
(ex.
this track's playback_count gives me 2700,
but its actually 15k when displayed on the web
https://soundcloud.com/drumandbassarena/ltj-bukem-soundcrash-mix-march-2016
)
note: this problem does not occur for comments or likes.
following is my code
##Search##
tracks = client.get('/tracks', q=querytext, created_at={'from':startdate},duration={'from':startdur},limit=200)
outputlist = []
trackinfo = {}
resultnum = 0
for t in tracks:
trackinfo = {}
resultnum += 1
trackinfo["id"] = resultnum
trackinfo["title"] =t.title
trackinfo["username"]= t.user["username"]
trackinfo["created_at"]= t.created_at[:-5]
trackinfo["genre"] = t.genre
trackinfo["plays"] = t.playback_count
trackinfo["comments"] = t.comment_count
trackinfo["likes"] =t.likes_count
trackinfo["url"] = t.permalink_url
outputlist.append(trackinfo)
There is an issue with the playback count being incorrect when reported via the API.
I have encountered this when getting data via the /me endpoint for activity and likes to mention a couple.
The first image shows the information returned when accessing the sound returned for the currently playing track in the soundcloud widget
Information returned via the api for the me/activities endpoint
Looking at the SoundCloud website, they actually call a second version of the API to populate the track list on the user page. It's similar to the documented version, but not quite the same.
If you issue a request to https://api-v2.soundcloud.com/stream/users/[userid]?limit=20&client_id=[clientid] then you'll get back a JSON object showing the same numbers you see on the web.
Since this is an undocumented version, I'm sure it'll change the next time they update their website.