spotipy authorization code flow
Asked Answered
G

6

8

I am using the Spotipy python library to interact with the Spotify web api. I have worked through the API and docs but I do not see a clear example that shows how the library supports the Authorization code flow ( https://developer.spotify.com/web-api/authorization-guide/#authorization-code-flow ).

Gooden answered 7/9, 2014 at 15:13 Comment(0)
O
11

I implemented a simple Authorization Code flow with the help of Spotipy. Maybe this is helpful for other people as well. Also on github: https://github.com/perelin/spotipy_oauth_demo

Here is the code:

from bottle import route, run, request
import spotipy
from spotipy import oauth2

PORT_NUMBER = 8080
SPOTIPY_CLIENT_ID = 'your_client_id'
SPOTIPY_CLIENT_SECRET = 'your_client_secret'
SPOTIPY_REDIRECT_URI = 'http://localhost:8080'
SCOPE = 'user-library-read'
CACHE = '.spotipyoauthcache'

sp_oauth = oauth2.SpotifyOAuth( SPOTIPY_CLIENT_ID, SPOTIPY_CLIENT_SECRET,SPOTIPY_REDIRECT_URI,scope=SCOPE,cache_path=CACHE )

@route('/')
def index():

    access_token = ""

    token_info = sp_oauth.get_cached_token()

    if token_info:
        print "Found cached token!"
        access_token = token_info['access_token']
    else:
        url = request.url
        code = sp_oauth.parse_response_code(url)
        if code:
            print "Found Spotify auth code in Request URL! Trying to get valid access token..."
            token_info = sp_oauth.get_access_token(code)
            access_token = token_info['access_token']

    if access_token:
        print "Access token available! Trying to get user information..."
        sp = spotipy.Spotify(access_token)
        results = sp.current_user()
        return results

    else:
        return htmlForLoginButton()

def htmlForLoginButton():
    auth_url = getSPOauthURI()
    htmlLoginButton = "<a href='" + auth_url + "'>Login to Spotify</a>"
    return htmlLoginButton

def getSPOauthURI():
    auth_url = sp_oauth.get_authorize_url()
    return auth_url

run(host='', port=8080)
Osteoclasis answered 24/1, 2016 at 8:48 Comment(1)
Hi, Thank you for you example. Do you know how to refresh a token?Iorio
M
3

If someone needs the working code here is my current.

Just remember to change the client_id, etc. I put them in config.py.

import spotipy
import spotipy.util as util
from config import CLIENT_ID, CLIENT_SECRET, PLAY_LIST, USER
import random

token = util.oauth2.SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)

cache_token = token.get_access_token()
spotify = spotipy.Spotify(cache_token)

results1 = spotify.user_playlist_tracks(USER, PLAY_LIST, limit=100, offset=0)
Mistrustful answered 22/8, 2017 at 7:28 Comment(0)
O
1

The Spotipy library supports the Authorization Code flow, as documented here. For more information, you could also check out Spotipy's oAuth2 module and Util module.

Overweening answered 7/9, 2014 at 15:31 Comment(0)
E
1

When I was trying to do this none of these answers really got me there unfortunately. When I ended up figuring it out I detailed how in this post: https://mcmap.net/q/1324534/-what-do-i-do-with-a-spotify-api-authentication-redirect-uri-in-django I was using Django as my backend but all the spotify api oauth stuff is done in javascript so it should still be very useful for you.

Eparch answered 24/2, 2017 at 16:43 Comment(0)
A
0

I'm assuming you're asking about using the Authorization flow to give the server long-term access to an account without needing to refresh from the client or in the command-line?

You can take advantage of the Custom Token Caching that spotipy provides in order to create a Spotipy Client that is specific to a particular user. It's not too complicated, but you do need to sub a few levels down in the heirarchy.(Spotify -> SpotifyOAuth -> CacheHandler)

When you exchange the code (docs here), you'll receive a token_info object that you'll want to store and relate to that specific spotify user. Here's a quick in-memory example, (but you'll probably want to back it by saving to a DB):

from spotipy import CacheHandler, SpotifyOauth, Spotify


# for simplicity, using an in memory dict with the refresh_token as the key
tokens = {}

class CacheHandlerUserSpecific(CacheHandler):
    def __init__(self, refresh_token):
        self.refresh_token = refresh_token
        
    def get_cached_token(self):
        return tokens[self.refresh_token]
    
    def save_token_to_cache(self, token_info):
        tokens[self.refresh_token] = token_info

Then you can make a client specific to that user by plugging the new CacheHandler into an SpotifyOAuth, then finally plugging that SpotifyOAuth into a Spotify client:

cache_handler = CacheHandlerUserSpecific(refresh_token=token_info["refresh_token"])
oauth_manager = SpotifyOAuth(
    client_id="YOUR_SPOTIFY_API_CLIENT_ID",
    client_secret="YOUR_SPOTIFY_API_CLIENT_SECRET",
    redirect_uri="YOUR_SPOTIFY_REDIRECT_URI",
    cache_handler = cache_handler
)
sp = Spotify(oauth_manager=oath_manager)

# then use it
sp.current_user_top_tracks()
sp.current_user()
Aware answered 13/2 at 18:40 Comment(0)
B
0

You can simply use spotipy.oauth2.CacheFileHandler as follows:

o_auth: SpotifyOAuth = SpotifyOAuth(
    cache_handler=CacheFileHandler(cache_path=f".cache-{scope}"),
    client_id=client_id,
    client_secret=client_secret,
    redirect_uri="https://localhost:8080",
    scope=scope,
)

This will for example create a file .cache-playlist-modify-public that holds the relevant information to be used until expiration.

{
    "access_token": "abc123...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "def456...",
    "scope": "playlist-modify-public",
    "expires_at": 1712123123
}
Bifurcate answered 24/4 at 16:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.