Getting tracks from a playlist using Spotipy is slow - python

I'm interacting with the Spotify Web API for a django project that allows users to upload their playlists for them to be ranked according to certain parameters, namely audio features spotify assigns to all tracks.
I'm using the Spotipy library to query the spotify API with python. It's lightning fast for user and playlist data, but following the Spotipy tutorials on how to get tracks from a playlist, I'm finding the response is extremely slow.
The wait time for tracks is about proportional to the length of the playlist in tracks.. I'm thinking it has something to do with an inefficiency in how the spotipy library packages up and sends requests.
Has anyone ever come across a similar bottle neck with regards to getting tracks and speed?
I'd be very grateful.. our project kind of hinges on it at this point.

Spotipy is not slow at all.
Anyway, you can try making requests yourself.
import requests
import json
then get your desired endpoint: (refer to: Spotify Web API Endpoint Reference)
SEARCH_PLAYLIST_ENDPOINT ='https://api.spotify.com/v1/search?type=playlist'
AUDIO_FEATURES_ENDPOINT = 'https://api.spotify.com/v1/audio-features/{id}'
And provided you have an access token, filter playlist by name:
def search_playlist(name):
path = 'token.json'
with open(path) as t:
token = json.load(t)
myparams = {'type': 'playlilst'}
myparams['q'] = name
resp = requests.get(SEARCH_PLAYLIST_ENDPOINT, params=myparams, headers={"Authorization": "Bearer {}".format(token)})
return resp.json()
obviously response time for querying playlist items depend on the number of playlist tracks, which can vary dramatically.
Then you can use this function to get audio features:
# https://developer.spotify.com/web-api/get-related-artists/
def get_audio_features(track_id):
path = 'token.json'
with open(path) as t:
token = json.load(t)
url = AUDIO_FEATURES_ENDPOINT.format(id=track_id)
resp = requests.get(url, headers={"Authorization": "Bearer {}".format(token)})
return resp.json()
Follow the same logic for other requests. Test this and compare with Spotipy speed.

Related

Google user listing with service account using Python

I have a Json service file, and a service account that already accesses translate and sheets, but it will not access user lists. The result is either 400 showing its confused or 401 saying its not authorized. Examples are usually about client involved OAuth processes, where I need server to server. I have enabled that "Enable G Suite domain-wide delegation" feature on the service account too.
I read and tried the JWT method, but I get the same error responses.
https://developers.google.com/identity/protocols/oauth2/service-account#python_2
My goal is to call either one of these end points
https://www.googleapis.com/admin/directory/v1/users
https://www.googleapis.com/admin/directory/v1/users.readonly
Any direction would be greatly appreciated.
UPDATE1:
This is using the Jwt token approach which yields error 401.
with open(CLIENT_SECRET_FILE, "r+") as fh:
config = json.load(fh)
iat = time.time()
exp = iat + 3600
payload = {'iss': config['client_email'],
'sub': config['client_email'],
'aud': 'https://www.googleapis.com/',
'iat': iat,
'exp': exp}
additional_headers = {'kid': config['private_key_id']}
signed_jwt = jwt.encode(payload, config['private_key'], headers=additional_headers,
algorithm='RS256')
url = 'https://www.googleapis.com/admin/directory/v1/users'
headers = {"Authorization": "Bearer " + signed_jwt}
r = requests.get(url, headers=headers)
I have also tried
scopes = ['https://www.googleapis.com/auth/admin.directory.user']
credentials = ServiceAccountCredentials.from_json_keyfile_name(CLIENT_SECRET_FILE, scopes=scopes)
service = build('admin', 'directory_v1', credentials=credentials)
results = service.users().list().execute()
UPDATE2:
This link has great information and simple code to review. As much as I tried to avoid impersonation, the AdminSDK requires it. That makes integrations a bit awkward in my view. In addition, the issue I also faced was the Domain-Wide-Delegation screen in the Google Workspace Admin can get messed up. Deleting the entry and recreating it fixed the forever 403 error I kept getting no matter what I had tried.
https://gist.github.com/lewisrodgers/fa766ebd37c1397d3a014eb73805edd1
You need to incorporate into your code impersonation, so that the service account acts on behalf of the admin
Because only admins have authroization to access Resource: users.
For impersonation in Python you need to implement the additional line
delegated_credentials = credentials.with_subject('admin#example.org')
The link below has great information and simple code to review. As much as I tried to avoid impersonation, the AdminSDK requires it. That makes integrations a bit awkward in my view.
In addition, the issue I also faced was the Domain-Wide-Delegation screen in the Google Workspace Admin that messed up. After much digging over weeks, I found a simple solution of deleting and recreating the client entry in that screen. It fixed the never ending 403 error that hit every test I tried that should have worked and did for many others.
This seems to be the only API set by Google that requires impersonation, and is annoying when attempting to create a SaaS solution.
Really basic, trimmed examples, and decent article references.
https://gist.github.com/lewisrodgers/fa766ebd37c1397d3a014eb73805edd1

Why can't I delete multiple tweets with this code? Python tweepy

I am trying to use this code to delete 550 tweets from my account, as I want to use it as my personal account again without the tweets from my bots:
import tweepy
import json
auth = tweepy.OAuthHandler("consumer_key", "consumer_secret")
auth.set_access_token("access_token", "access_token_secret")
api = tweepy.API(auth)
screen_name = "YOUR_TWITTER_HANDLE"
timelines = api.user_timeline(screen_name, count = 550, include_rts = False)
for status in timelines:
tweetid = status._json
api.destroy_status(tweetid)
But every time I run it, I get this error:
tweepy.error.TweepError: [{'message': 'Application cannot perform write actions. Contact Twitter Platform Operations through https://support.twitter.com/forms/platform', 'code': 261}]
When I print tweetid, it is successfully grabbing all my tweets. I can also tweet normally using api.update_status, so why is this not working? What am I doing wrong?
seems like you have made to many requests to the twitter api - from my little reasearch the error code 261 means the token was suspended. Check this links:
Why is the twitter API throwing this error?
https://blog.cotten.io/common-twitter-error-codes-6b324396042e
It sounds like your API key has been restricted (this can happen if you try to perform too many automated actions, see the automation rules https://help.twitter.com/en/rules-and-policies/twitter-automation). You will need to have the app restored via https://help.twitter.com/forms/automation

Google CSE Site Restricted API returns request throttle quota despite documentation saying no quota

I'm using they Google Python API Library to call the CSE Site Restrict search. According to the documentation, "this API is similar to the Custom Search JSON API except this version has no daily query limit."
However, after 100 searches I receive a 403 response from the Google API saying "Request throttled due to daily limit being reached." This doesn't seem to make sense, any idea if I'm doing something wrong? Code included below for how I'm calling the siterestrict function.
from googleapiclient.discovery import build
CSE_ID = "CSE_ID"
API_KEY = "API_KEY"
service = build("customsearch", "v1", developerKey=API_KEY)
def run_google_search(service, query, **kwargs):
try:
res = service.cse().siterestrict().list(q=query, cx=CSE_ID, **kwargs).execute()
except Exception as e:
print(e)
return []
return res['items']
run_google_search(service, "Test search")
Do you have billing set up for your API key? If not, then you'll be limited to the 100 free queries per day on either Custom Search API.

Retrieving all (Other) Contacts from Google Contacts API using gdata-python-client and OAuth2 token?

In the hunt to list all (to include Other) Contacts for a Gmail/GSuite user. The current People API does not support this functionality, noting the following threads:
Found this thread here, confirming such change in the API: Google Contacts API vs People API
Google team noting it here: https://groups.google.com/forum/#!topic/google-contacts-api/iLsrN23xF6g
Referencing ticket request for prioritization here: https://issuetracker.google.com/issues/36757468
When diving deeper, it seems the Contacts API is still functioning and can be used via gdata https://developers.google.com/contacts/v3/
However, based on the following repo (https://github.com/google/gdata-python-client), there's limited documentation on implementation using OAuth2 (userID, token, refreshToken), which is the current stumbling block to get the list of Other Contacts
Any help would be greatly appreciated, thanks!
I found this posting https://gist.github.com/jorilallo/3686737 from 7 years ago(?). The actual sample code below that I had to modify a bit to get it working:
import gdata
import gdata.gauth
import gdata.contacts.client
import json
import requests
GOOGLE_CLIENT_ID = 'GOOGLE_CLIENT_ID' # Provided in the APIs console
GOOGLE_CLIENT_SECRET = 'GOOGLE_CLIENT_SECRET' # Provided in the APIs console
ACCESS_TOKEN = 'ACCESS_TOKEN' # given from a prior OAuth2 workflow, along with userID and refreshToken
REFRESH_TOKEN = 'REFRESH_TOKEN'
# GData with access token
token = gdata.gauth.OAuth2Token(
client_id=GOOGLE_CLIENT_ID,
client_secret=GOOGLE_CLIENT_SECRET,
scope='https://www.google.com/m8/feeds',
user_agent='app.testing',
access_token=ACCESS_TOKEN,
refresh_token=REFRESH_TOKEN)
contact_client = gdata.contacts.client.ContactsClient()
token.authorize(contact_client)
feed = contact_client.GetContacts()
for entry in feed.entry:
entry.title.text
for e in entry.email:
e.address
# JSON with access token
r = requests.get('https://www.google.com/m8/feeds/contacts/default/full?access_token=%s&alt=json&max-results=50&start-index=0' % (access_token))
data = json.loads(r.text)
print data

How to apply Spotify API authentication on my current code which uses Spotify Search API?

Earlier I was using Spotify's Search API
without any kind of authentication. But just last week or so, they made their API usage with Authentication only.
So since the past 2-3 days I've not been able to figure how this authorization works for Search API where I as a developer can let users access responses from Search API without having them to login with their Spotify accounts.
Can someone help me with this authorization stuff(The docs from Spotify don't solve my problem :< )
So here's the python code that I was earlier using -
import requests
import json
def Spotify(keyword):
url = "https://api.spotify.com/v1/search?q="+keyword+"&type=track&limit=1"
headers = {
'accept': "application/json",
'access_token':''
}
r = requests.get(url=url,headers=headers).text
jsonwa = json.loads(r)
name = jsonwa["tracks"]["items"][0]["name"]
artists = jsonwa["tracks"]["items"][0]["artists"][0]["name"]
song_preview_url = jsonwa["tracks"]["items"][0]["preview_url"]
image = jsonwa["tracks"]["items"][0]["album"]["images"][1]["url"]
return_this = []
return_this.append(name)
return_this.append(artists)
return_this.append(song_preview_url)
return_this.append(image)
print return_this
return return_this
song = "hello"
Spotify(song)
Per the web authorization docs:
All requests to the Spotify Web API require authorization
You'll need your users to grant permission for your app in order to get an access token. The user must be logged in to gran permission.
Once your app is granted permission by the user, you can use the refresh_token from that point on, and the user shouldn't need to grant permission again unless they revoke permission for example. You'll need to manage the access_token expiration.

Categories

Resources