Add FlaskSessionCacheHandler (#833)

Updated examples/app.py
Updated CHANGELOG.md and appropriate docs.
This commit is contained in:
Bryan Malyn 2022-06-25 14:00:08 -05:00 committed by GitHub
parent 7337bf9352
commit 7fc08809f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 26 deletions

View File

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added `market` parameter to `album` and `albums` to address ([#753](https://github.com/plamere/spotipy/issues/753)
* Added 'show_featured_artists.py' to 'examples'.
* Expanded contribution and license sections of the documentation.
* Added `FlaskSessionCacheHandler`, a cache handler that stores the token info in a flask session.
### Fixed

View File

@ -235,6 +235,7 @@ The following handlers are available and defined in the URL above.
- ``CacheFileHandler``
- ``MemoryCacheHandler``
- ``DjangoSessionCacheHandler``
- ``FlaskSessionCacheHandler``
- ``RedisCacheHandler``
Feel free to contribute new cache handlers to the repo.

View File

@ -27,7 +27,6 @@ import os
from flask import Flask, session, request, redirect
from flask_session import Session
import spotipy
import uuid
app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(64)
@ -35,35 +34,26 @@ app.config['SESSION_TYPE'] = 'filesystem'
app.config['SESSION_FILE_DIR'] = './.flask_session/'
Session(app)
caches_folder = './.spotify_caches/'
if not os.path.exists(caches_folder):
os.makedirs(caches_folder)
def session_cache_path():
return caches_folder + session.get('uuid')
@app.route('/')
def index():
if not session.get('uuid'):
# Step 1. Visitor is unknown, give random ID
session['uuid'] = str(uuid.uuid4())
cache_handler = spotipy.cache_handler.CacheFileHandler(cache_path=session_cache_path())
cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
auth_manager = spotipy.oauth2.SpotifyOAuth(scope='user-read-currently-playing playlist-modify-private',
cache_handler=cache_handler,
show_dialog=True)
if request.args.get("code"):
# Step 3. Being redirected from Spotify auth page
# Step 2. Being redirected from Spotify auth page
auth_manager.get_access_token(request.args.get("code"))
return redirect('/')
if not auth_manager.validate_token(cache_handler.get_cached_token()):
# Step 2. Display sign in link when no token
# Step 1. Display sign in link when no token
auth_url = auth_manager.get_authorize_url()
return f'<h2><a href="{auth_url}">Sign in</a></h2>'
# Step 4. Signed in, display data
# Step 3. Signed in, display data
spotify = spotipy.Spotify(auth_manager=auth_manager)
return f'<h2>Hi {spotify.me()["display_name"]}, ' \
f'<small><a href="/sign_out">[sign out]<a/></small></h2>' \
@ -72,20 +62,16 @@ def index():
f'<a href="/current_user">me</a>' \
@app.route('/sign_out')
def sign_out():
try:
# Remove the CACHE file (.cache-test) so that a new user can authorize.
os.remove(session_cache_path())
session.clear()
except OSError as e:
print ("Error: %s - %s." % (e.filename, e.strerror))
session.pop("token_info", None)
return redirect('/')
@app.route('/playlists')
def playlists():
cache_handler = spotipy.cache_handler.CacheFileHandler(cache_path=session_cache_path())
cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
if not auth_manager.validate_token(cache_handler.get_cached_token()):
return redirect('/')
@ -96,7 +82,7 @@ def playlists():
@app.route('/currently_playing')
def currently_playing():
cache_handler = spotipy.cache_handler.CacheFileHandler(cache_path=session_cache_path())
cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
if not auth_manager.validate_token(cache_handler.get_cached_token()):
return redirect('/')
@ -109,7 +95,7 @@ def currently_playing():
@app.route('/current_user')
def current_user():
cache_handler = spotipy.cache_handler.CacheFileHandler(cache_path=session_cache_path())
cache_handler = spotipy.cache_handler.FlaskSessionCacheHandler(session)
auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
if not auth_manager.validate_token(cache_handler.get_cached_token()):
return redirect('/')

View File

@ -2,6 +2,7 @@ __all__ = [
'CacheHandler',
'CacheFileHandler',
'DjangoSessionCacheHandler',
'FlaskSessionCacheHandler',
'MemoryCacheHandler',
'RedisCacheHandler']
@ -147,6 +148,31 @@ class DjangoSessionCacheHandler(CacheHandler):
logger.warning("Error saving token to cache: " + str(e))
class FlaskSessionCacheHandler(CacheHandler):
"""
A cache handler that stores the token info in the session framework
provided by flask.
"""
def __init__(self, session):
self.session = session
def get_cached_token(self):
token_info = None
try:
token_info = self.session["token_info"]
except KeyError:
logger.debug("Token not found in the session")
return token_info
def save_token_to_cache(self, token_info):
try:
self.session["token_info"] = token_info
except Exception as e:
logger.warning("Error saving token to cache: " + str(e))
class RedisCacheHandler(CacheHandler):
"""
A cache handler that stores the token info in the Redis.