Spotify Authentication Flow (Spotify API) - python

I'm trying to allow users to login with Spotify (using the Spotipy library) to provide authentication for creating a playlist on their account and populating the playlist. After the user has logged in, I will display the playlist they have just created in the redirect template via an embedded Spotify player (using the playlist ID of the newly created playlist).
I have a form input box in my HTML template which takes input from the user (their Spotify username). I also have a list of Spotify URIs for tracks ready to populate the playlist with.
I followed Spotipy's documentation regarding obtaining a token for users for authentication as follows (I have removed my client-id & secret).. I'm not sure why it isn't working:
import os
import spotipy
import spotipy.util as util
from json.decoder import JSONDecodeError
from datetime import date
#login_required
def save_playlist(request, data='Default_Data'):
username = data.split('/')[0] #spotify username
track_ids = data.split('/')[1:11] #list of spotify IDs for playlist tracks
client_id = '****'
client_secret = '****'
scope = 'playlist-modify-public, playlist-modify-private'
redirect_uri = 'http://127.0.0.1:8000/save_playlist/'
#check if username is already in cache, if not, create cache
try:
token = util.prompt_for_user_token(username,
scope=scope,client_id=client_id,
client_secret=client_secret,redirect_uri=redirect_uri)
except (AttributeError, JSONDecodeError):
os.remove(f".cache-{username}")
token = util.prompt_for_user_token(username,
scope=scope,client_id=client_id,
client_secret=client_secret,redirect_uri=redirect_uri)
sp=spotipy.Spotify(auth=token)
today = date.today()
date_string = (str(today.day) + ' - ' + str(today.month) + ' - ' + str(today.year))
#playlist title
playlist_name = f"GENIE - " + username + ' | ' + date_string
#create a new public playlist to be populated
sp.user_playlist_create(username, name=playlist_name, public=True)
#id of playlist we just created
playlist_id = sp.current_user_playlists(limit=1)['items'][0]['id']
#add playlist tracks to this playlist
sp.user_playlist_add_tracks(username,playlist_id,tracks=track_ids)
return render(request, 'blog/save_playlist.html', {'playlist_id':playlist_id})
When a user enters their username and logins to Spotify, multiple windows keep popping up rather than just one (see terminal below). I believe the issue is somewhere in obtaining the token.
terminal output when attempting to login
I have set the redirect URI in the Spotify developer console to be the same as above ('http://127.0.0.1:8000/save_playlist/').
Thanks in advance!

util.prompt_for_user_token should not be used in a web app that would allow any user to sign in, since we don't know the user's ID/name in advance. It's just a helper to get started quickly locally.
Instead you should use spotipy.oauth2.SpotifyOAuth directly, by specifying a unique cache path for your user. In the case of a web app it would be a session ID.
Here is a complete example made for Flask which you can adapt to your needs https://github.com/plamere/spotipy/blob/master/examples/app.py

Give a try to the OAuth requests-oauthlib
https://requests-oauthlib.readthedocs.io/en/latest/examples/spotify.html
It works like a charm.

Instead of using Spotipy, a quick solution is to go to https://pypi.org/project/spotify-token/ ,it is a Python script that can generate a Spotify token if a Spotify username and password is provided.
With that said, just keep in mind that not everyone will provide their username and password willingly. Cheers!

Related

Authenticating other Users from my App - Tweepy

I've created an app in python to like tweets by hitting the POST endpoint -very simple.
Next I'd like to have an account different than mine able to login and authenticate to use the feature.
I have no clue how to do that and would appreciate any advice
I'm a junior dev, just starting to mess around with an API
for background: I'm going to implement this in flask but for now, just have a python like.py file with basic logic in it for my dev account authentication
import tweepy
import config
import time
client = tweepy.Client(
bearer_token=config.bearer_token,
consumer_key=config.consumer_key,
consumer_secret=config.consumer_secret,
access_token=config.access_token,
access_token_secret=config.access_token_secret
)
print('Sup Loser, what you wanna like? \n')
search = input('query: ')
query= f'{search} -is:retweet -has:media -is:reply'
response = client.search_recent_tweets(query=query, max_results=42)
for tweets in response.data:
id = tweets.id
print(f"searching '{search}' liking tweet -- ID# {id} -- URL https://twitter.com/twitter/statuses/{id}")
time.sleep(1)
client.like(id)

Box SDK Refresh Token method (python)

I am trying to implement python-sdk to drop a file (that exists in a local folder) into a shared Box folder.
The method I tried is to put Redirect URI into my Box developer configuration page and use Client ID/Secret to get authorization_URL and then extract authenticate code extract access token and refresh token.
However, I can only get to the part of getting the auth_url and I can only get auth_code manually from the redirecting to the page after clicking "granting" the access.
Using that auth_code I can get the refresh token but I don't know how to automate that part.
Is there another approach to this?
If so, can you please give me an example how?
I have literally read every search related to this and so far I haven't found a solution to my problem.
Redirect_URi = 'https://api.box.com/oauth2/token'
def save_tokens(access_token,refresh_token):
print("Refreshing tokens...")
target = open("AdminToken.txt", 'w')
target.truncate()
tokens = access_token+'#'+refresh_token
target.write(tokens)
target.close()
oauth = OAuth2(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
store_tokens=save_tokens
)
oauth.access_token
auth_url, csrf_token = oauth.get_authorization_url(Redirect_URi)
# GET "auth_code" from auth_url #
getTokens = requests.get(auth_url)
# trouble starts here
auth_code = 'exctracted from linked webpages manually' # expires in 30 seconds after creation
access_token, refresh_token = oauth.authenticate(auth_code)
oauth2 = OAuth2(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
store_tokens=save_tokens,
access_token=access_token,
refresh_token=refresh_token
)
client = Client(oauth)
# Testing if it is authorized
me = client.user(user_id= user_id).get()
print ('user_login: ' + me['login'])`
I should be able to run this script and the file I extracted from DB should be picked up as xlsx (which I already did) and dropped into Box folder.
I think I am stuck here with this refresh tokens and everyone is directing me to Github official Box sdk page without giving any more information like any example on it.

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.

Spotipy not verifying via Oauth?

I'm attempting to write a Python script to create a Spotify playlist via the Spotipy application. I've successfully created an application in Spotify's Dev center and input the necessary variables into Spotipy's example (see below). However, the script is not authorizing properly. I've tried with and without a server running, but to no avail. There are similar questions on Stack but they do not offer complete solutions. Any suggestions would be very helpful.
Here is the message I am receiving via command prompt:
User authentication requires interaction with your
web browser. Once you enter your credentials and
give authorization, you will be redirected to
a url. Paste that url you were directed to to
complete the authorization.
Please navigate here:
https://accounts.spotify.com/authorize?scope=user-library-read&redirect_uri=None&response_type=code&client_id=xxxxx
Enter the URL you were redirected to:
And here is the script that's running. It's nearly identical to that example provided by Spotipy, with a change made for setting os variables for my Windows machine.
import pprint
import sys
import os
import subprocess
import spotipy
import spotipy.util as util
import requests
clientId = 'client id here'
clientSecret = 'client secret here'
clientRedirect = 'http://localhost:8888/callback'
username = 'username here'
scope='user-library-read'
os.environ["SPOTIPY_CLIENT_ID"] = clientId
os.environ["SPOTIPY_CLIENT_SECRET"] = clientSecret
os.environ["POTIPY_REDIRECT_URI"] = clientRedirect
token = util.prompt_for_user_token(username, scope)
if token:
sp = spotipy.Spotify(auth=token)
results = sp.current_user_saved_tracks()
for item in results['items']:
track = item['track']
print track['name'] + ' - ' + track['artists'][0]['name']
else:
print "Can't get token for", username
The application is asking a URL that should contain a "code" which will then be used to exchange with access_token as mentioned in Step.3 in https://developer.spotify.com/web-api/authorization-guide/ and the URL should look like this https://example.com/callback?code=NApCCg..BkWtQ&state=profile%2Factivity. I hope you are entering your credentials properly otherwise you will never get the code to proceed further.

401 and 403 Errors with google base API

I built a wiki using Google App engine and the Data APIs. The wiki pages are stored as Google Base 'Reference Articles.' I want users to be able to view, edit, and delete the items, so when a request is made to the server, client login uses my username and password, and retrieves or edits the data on the user's behalf. The login code:
client = gdata.base.service.GBaseService()
client.ssl = False
gdata.alt.appengine.run_on_appengine(client)
#EMAIL, API_KEY and PASSWORD are constants stored on the server
client.email = EMAIL
client.password = PASSWORD
client.api_key = API_KEY
client.ProgrammaticLogin()
q = gdata.base.service.BaseQuery()
q.feed = '/base/feeds/items/' + self.base_id
item = base_client.GetItem(q.ToUri())
This works fine for me, but if I log out of my google account, it returns the following error:
'status': 401L, 'body': '<HTML>\n<HEAD>\n<TITLE>Authorization required</TITLE>
All I want is for the users to be able to CRUD my data stored on Base. What am I doing wrong?
Thanks in advance
It sounds like logging out in your client is invalidating all sessions for your account. Your best bet is probably to create a role account specifically for your app to use.

Categories

Resources