Spotify API Authorization to create a Playlist - python

I've been trying to write a code with the Spotify for Developers Tools that will read the audio features of all the songs in a user selected playlist and then create two new playlists to sort the songs in the original playlist depending on whether they are considered minor or major. I have gotten most of the program to work, it reads the playlist and creates a dictionary of the songs audio features and creates two lists for the songs that are minor and one for the major, however it will not let me create a new playlist due to the authorization and I can not figure out how to solve this issue. Below is my code, any help is greatly appreciated!
Here is what the beginning looks like with my account information:
################### Account Information ######################
cid ='*my client id*' # Client ID
secret = '*my secret id*' # Client Secret
client_credentials_manager = SpotifyClientCredentials(client_id=cid, client_secret=secret)
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
username = '*my username*'
token = util.prompt_for_user_token(username=username, scope='playlist-modify-public', client_id=cid, client_secret=secret, redirect_uri="http://localhost:8888/callback")
#############################################################
Then I try to create the playlists:
############### Create Playlist #################
created_playlist_minor = sp.user_playlist_create(username, "New Playlist Minor", description='Minor')
created_playlist_major = sp.user_playlist_create(username, "New Playlist Major", description='Major')
created_playlist_other = sp.user_playlist_create(username, "New Playlist Other", description='Other')
#################################################
And then it gives me an error
spotipy.client.SpotifyException: http status: 403, code:-1 - https://api.spotify.com/v1/users/*username*/playlists:
This request requires user authentication.

You are passing in a SpotifyClientCredentials object to your Spotify client. This authenticates spotipy.Spotify so that you can do anything that your developer API key gives you access to (e.g. getting info about songs in a public playlist). You haven't given your spotipy.Spotify a user's authentication token, so you can't do user-specific things like creating a playlist. You should do the following:
username = '*my username*'
token = util.prompt_for_user_token(
username=username,
scope='playlist-modify-public',
client_id=cid,
client_secret=secret,
redirect_uri="http://localhost:8888/callback"
)
sp = spotipy.Spotify(auth=token)
Note that you don't have to pass your Client ID & Secret to spotipy.Spotify, the token is sufficient

Related

Youtube Data API v3 My list of Subscriber is not complete

I'm trying to get a list of all my subscribers using Youtube Data Api. But a large amount of my public subscribers aren't appearing.
# Disable OAuthlib's HTTPS verification when running locally.
# *DO NOT* leave this option enabled in production.
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
api_service_name = "youtube"
api_version = "v3"
client_secrets_file = "YOUR_CLIENT_SECRET_FILE.json"
# Get credentials and create an API client
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(client_secrets_file, scopes)
credentials = flow.run_console()
youtube = googleapiclient.discovery.build(api_service_name, api_version, credentials=credentials)
curSubDicList = []
nextPageToken = ""
while TRUE: #Loop through all subs and fill out the curSubDicList var
request = youtube.subscriptions().list(part="subscriberSnippet", mySubscribers=True, maxResults=50, pageToken=nextPageToken, order="alphabetical")
response = request.execute()
for x in response["items"]:
print(x["subscriberSnippet"]["title"])
subDic = { "title" : x["subscriberSnippet"]["title"], "channelId" : x["subscriberSnippet"]["channelId"], "pfp" : x["subscriberSnippet"]["thumbnails"]["default"]["url"]}
curSubDicList.append(subDic)
if "nextPageToken" in response:
nextPageToken = response["nextPageToken"]
else:
break
I loop through using each new nextPageToken till there isn't one. But for some reason a lot of my public subscribers aren't appearing. I print out my subs to my file subs.json
jsonSubsTxt = open("subs.json", "w", encoding="utf-8")
curSubDicListJsonStr = json.dumps(curSubDicList)
jsonSubsTxt.write(curSubDicListJsonStr)
jsonSubsTxt.close()
I know that a lot of my public subs are missing by using Youtube Studio's built in subscriber viewer, and CTRL + Fing for them in the subs.json. I have a 2nd youtube account called "LowerLevelLemmy" I made sure that my subscriptions were public and subscribed to myself. I appear as a sub in YT Studio, but not in my subs.json. Here's images of what I mean:
My 2nd channel appears in YT Studio as a public sub.
But CTRL Fing for it shows no results.
Sometimes CTRL+Fing someone I see as a sub in YT Studio works but most times it doesn't. When their username doesn't come up with a match, I try searching with their channel ID, but that doesn't work either.
I'm new to Youtube Data Api and this is my first time submitting a question to Stack Over Flow. I hope I did everything right. Thank you for reading.

Spotify - get and change user data with Implicit Flow

I'm trying to implement a simple python client for Spotify api. According to the Spotify's Authorization Guide, the app can be authorized in two ways:
App Authorization: Spotify authorizes your app to access the Spotify Platform (APIs, SDKs and Widgets).
User Authorization: Spotify, as well as the user, grant your app permission to access and/or modify the user’s own data. For information about User Authentication, see User Authentication with OAuth 2.0. Calls to the Spotify Web API require authorization by your application user. To get that authorization, your application generates a call to the Spotify Accounts Service /authorize endpoint, passing along a list of the scopes for which access permission is sought.
CLIENT CREDENTIALS
My first attempt used the app authorization using the oauth2 module from Spotipy, because it requires no token passed, but only client id and client secret, which belong to the app developer.
client.py
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
class SpotifyWrapper(spotipy.Spotify):
def category_playlists(self, category, limit=50, offset=0):
return self._get('browse/categories/%s/playlists' % category,
limit=limit,
offset=offset)
def get_api_client():
# create a client authentication request
client_cred = SpotifyClientCredentials(
client_id=DevelopmentConfig.SPOTIFY_CLIENT_ID,
client_secret=DevelopmentConfig.SPOTIFY_CLIENT_SECRET
)
# create a spotify client with a bearer token,
# dynamically re-created if necessary
return SpotifyWrapper(auth=client_cred.get_access_token())
Then I would import and declare it here:
spotify_utilities.py
from app.resources.spotify.client import get_api_client
sp = get_api_client()
And in order to make requests and get user playlists, pass it like so:
def get_user_playlist(username, sp):
ids=[]
playlists = sp.user_playlists(username)
for playlist in playlists['items']:
ids.append(playlist['id'])
print("Name: {}, Number of songs: {}, Playlist ID: {} ".
format(playlist['name'].encode('utf8'),
playlist['tracks']['total'],
playlist['id']))
return ids
This works and will get user content, where the user is the app developer.
IMPLICIT FLOW
Now I want to move on to Implicit Flow, whereby the app asks ANY user who uses for access and scopes, and for that a token will be required.
Once I fetch the token using Javascript, I know I can use it to get user data hitting the API with simple requests:
GET_USER_PROFILE_ENDPOINT = 'https://api.spotify.com/v1/users/{user_id}'
GET_USER_PLAYLISTS_ENDPOINT = 'https://api.spotify.com/v1/users/{user_id}/playlists'
def get_user_profile(token, user_id):
url = GET_USER_PROFILE_ENDPOINT.format(id=user_id)
resp = requests.get(url, headers={"Authorization": "Bearer {}".format(token)})
print (len(resp.json()))
return resp.json()
def get_user_playlists(token, user_id):
url = GET_USER_PLAYLISTS_ENDPOINT..format(id=user_id)
resp = requests.get(url, headers={"Authorization": "Bearer {}".format(token)})
print (len(resp.json()))
return resp.json()
but in order to get (and change) user data first I need to use this token to fetch user ID.
Also, by the following example form Spotipy docs, user must provide his username at terminal:
if __name__ == '__main__':
if len(sys.argv) > 1:
username = sys.argv[1]
else:
print("Whoops, need your username!")
print("usage: python user_playlists.py [username]")
sys.exit()
token = util.prompt_for_user_token(username)
if token:
sp = spotipy.Spotify(auth=token)
playlists = sp.user_playlists(username)
After reading the docs from Spotify and Spotify, some things that are still not clear:
Is it possible to get this USER ID from passing the token only?
Must the app user necessarily provide his Spotify username via a form in a browser, besides authorizing the app when authentication is prompted?
Is it possible to tweak the wrapper above and implement a client which contemplates the parameters required for implicit flow? Would simply spotify = spotipy.Spotify(auth=token) work and get current usr data?
Also, by the following example form Spotipy docs, user must provide
his username at terminal:
That's because Spotipy caches tokens on disk. When no cache path is specified by the user the username simply gets appended to the files file extension as seen here. So the username specified is never being transmitted to any Spotify API endpoint.
1) Is it possible to get this USER ID from passing the token only?
Yes, using /v1/me instead of /v1/users/{user_id} will do exactly that assuming you are using an access token generated by Authorization Code flow or Implicit Grant flow.
2) Must the app user necessarily provide his Spotify username via a
form in a browser, besides authorizing the app when authentication is
prompted?
No, as seen in the first paragraph of my answer.
3) Is it possible to tweak the wrapper above and implement a client
which contemplates the parameters required for implicit flow? Would
simply spotify = spotipy.Spotify(auth=token) work and get current usr
data?
Spotipy seems to only use Authorization Code Flow right now. Due to you said you are
trying to implement a simple python client for Spotify api.
you should just implement Implicit Grant flow in your application. This has examples for all three Spotify authorization flows.

Can't get all tags from Instagram API

I'm using the python-instagram client and I want to grab all the photos of a specific tag. In this example I want an instance of this URL: https://www.instagram.com/explore/tags/flowers/
Currently it only takes the photos with that tag, that I personally uploaded from my account.
This is my code:
# Instagram
ACCESS_TOKEN = 'X'
CLIENT_SECRET = 'X'
CLIENT_ID = 'X'
INSTAGRAM_API = InstagramAPI(access_token=ACCESS_TOKEN, client_id=CLIENT_ID, client_secret=CLIENT_SECRET, redirect_uri='http://localhost:8000/')
recent_instagram_media, next_ = settings.INSTAGRAM_API.tag_recent_media(count=5, max_tag_id=5, tag_name='flowers')
photos = []
for media in recent_instagram_media:
photos.append(media.images['standard_resolution'].url)
What do I do wrong here?
This behaviour can be explained by checking if your application is in sandbox mode. Every new application on Instagram starts at sandbox mode. In this mode you are only exposed to data from other sandbox users (restricted to 10 users) on your app.
From the API:
As another example, let's consider an endpoint that returns a list of media: /tags/{tag-name}/media/recent.
The response returned by this endpoint will contain only media with the given tag, as expected. But instead of returning media from any public Instagram user, it will return only media that belongs to your sandbox users, restricted to the last 20 for each user.

Facebook Access Token for Single User Application

I'm creating an application on Facebook that will only ever have one user: me. I'm not making a GUI for the application, which means that there's no client side auth.
Is there a way that I can use my username and password or some other app information to get an access token for myself?
I'm familiar with the refresh token flows and everything for OAuth applications for other people, but I've never done this without some sort of Facebook login button, especially on a one person application. I'm happy to hard code in my user information.
I've tried using this:
access_token_url = 'https://graph.facebook.com/oauth/access_token?type=client_cred&client_id=' + config['app_id'] + '&client_secret=' + config['app_secret']
token_response = urllib.urlopen(access_token_url).read()
access_token = token_response.replace('access_token=', '')
session = FacebookSession(
config['app_id'],
config['app_secret'],
access_token,
)
But that doesn't give me an access token specific to my own account, only one for the application itself.
I managed to figure this out. Here's what I did:
I went to the Graph API Explorer (https://developers.facebook.com/tools/explorer) and then got an access token from there for my application.
Once I had the token I used this URL to get a long lived token using that access token:
token_exchange_url = 'https://graph.facebook.com/oauth/access_token?
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=ACCESS_TOKEN'
exchange_response = urllib.urlopen(token_exchange_url).read()
access_token = exchange_response.replace('access_token=', '')
access_token = access_token[:access_token.index('&')]
I then saved that access_token and on any subsequent call I can update the access_token using that code whenever in order to make sure it's refreshed.

How to retrieve linkedin information of other people using python and oauth 2?

1) Followed the steps for keys creation on developer site of linkedin.
2) Works well to get my information using Python and oauth 2.0:
import oauth2 as oauth
import time
url = "http://api.linkedin.com/v1/people/~"
consumer_key = 'my_app_key'
consumer_secret = 'my_app_secret_key'
oath_key = 'oath_key'
oath_secret = 'oath_secret_key'
consumer = oauth.Consumer(
key=consumer_key,
secret=consumer_secret)
token = oauth.Token(
key=oath_key,
secret=oath_secret)
client = oauth.Client(consumer, token)
resp, content = client.request(url)
print resp
print content
But, I want to know the information of other people, e.g. to get the info based on first_name, last_name, and company.
There seems to be good information at https://developer.linkedin.com/documents/profile-api
but, cannot get through it.
What exactly is "id" value?
You can't do that. You can get public profile data of somebody if you know their public profile url or their unique member id, but you can't query on anything else.

Categories