mirror of
https://github.com/spotipy-dev/spotipy.git
synced 2026-06-19 09:13:53 +00:00
Add FlaskSessionCacheHandler (#833)
Updated examples/app.py Updated CHANGELOG.md and appropriate docs.
This commit is contained in:
parent
7337bf9352
commit
7fc08809f0
@ -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 `market` parameter to `album` and `albums` to address ([#753](https://github.com/plamere/spotipy/issues/753)
|
||||||
* Added 'show_featured_artists.py' to 'examples'.
|
* Added 'show_featured_artists.py' to 'examples'.
|
||||||
* Expanded contribution and license sections of the documentation.
|
* Expanded contribution and license sections of the documentation.
|
||||||
|
* Added `FlaskSessionCacheHandler`, a cache handler that stores the token info in a flask session.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
@ -235,6 +235,7 @@ The following handlers are available and defined in the URL above.
|
|||||||
- ``CacheFileHandler``
|
- ``CacheFileHandler``
|
||||||
- ``MemoryCacheHandler``
|
- ``MemoryCacheHandler``
|
||||||
- ``DjangoSessionCacheHandler``
|
- ``DjangoSessionCacheHandler``
|
||||||
|
- ``FlaskSessionCacheHandler``
|
||||||
- ``RedisCacheHandler``
|
- ``RedisCacheHandler``
|
||||||
|
|
||||||
Feel free to contribute new cache handlers to the repo.
|
Feel free to contribute new cache handlers to the repo.
|
||||||
|
|||||||
@ -27,7 +27,6 @@ import os
|
|||||||
from flask import Flask, session, request, redirect
|
from flask import Flask, session, request, redirect
|
||||||
from flask_session import Session
|
from flask_session import Session
|
||||||
import spotipy
|
import spotipy
|
||||||
import uuid
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config['SECRET_KEY'] = os.urandom(64)
|
app.config['SECRET_KEY'] = os.urandom(64)
|
||||||
@ -35,35 +34,26 @@ app.config['SESSION_TYPE'] = 'filesystem'
|
|||||||
app.config['SESSION_FILE_DIR'] = './.flask_session/'
|
app.config['SESSION_FILE_DIR'] = './.flask_session/'
|
||||||
Session(app)
|
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('/')
|
@app.route('/')
|
||||||
def index():
|
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',
|
auth_manager = spotipy.oauth2.SpotifyOAuth(scope='user-read-currently-playing playlist-modify-private',
|
||||||
cache_handler=cache_handler,
|
cache_handler=cache_handler,
|
||||||
show_dialog=True)
|
show_dialog=True)
|
||||||
|
|
||||||
if request.args.get("code"):
|
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"))
|
auth_manager.get_access_token(request.args.get("code"))
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
|
|
||||||
if not auth_manager.validate_token(cache_handler.get_cached_token()):
|
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()
|
auth_url = auth_manager.get_authorize_url()
|
||||||
return f'<h2><a href="{auth_url}">Sign in</a></h2>'
|
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)
|
spotify = spotipy.Spotify(auth_manager=auth_manager)
|
||||||
return f'<h2>Hi {spotify.me()["display_name"]}, ' \
|
return f'<h2>Hi {spotify.me()["display_name"]}, ' \
|
||||||
f'<small><a href="/sign_out">[sign out]<a/></small></h2>' \
|
f'<small><a href="/sign_out">[sign out]<a/></small></h2>' \
|
||||||
@ -72,20 +62,16 @@ def index():
|
|||||||
f'<a href="/current_user">me</a>' \
|
f'<a href="/current_user">me</a>' \
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/sign_out')
|
@app.route('/sign_out')
|
||||||
def sign_out():
|
def sign_out():
|
||||||
try:
|
session.pop("token_info", None)
|
||||||
# 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))
|
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/playlists')
|
@app.route('/playlists')
|
||||||
def 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)
|
auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
|
||||||
if not auth_manager.validate_token(cache_handler.get_cached_token()):
|
if not auth_manager.validate_token(cache_handler.get_cached_token()):
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
@ -96,7 +82,7 @@ def playlists():
|
|||||||
|
|
||||||
@app.route('/currently_playing')
|
@app.route('/currently_playing')
|
||||||
def 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)
|
auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
|
||||||
if not auth_manager.validate_token(cache_handler.get_cached_token()):
|
if not auth_manager.validate_token(cache_handler.get_cached_token()):
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
@ -109,7 +95,7 @@ def currently_playing():
|
|||||||
|
|
||||||
@app.route('/current_user')
|
@app.route('/current_user')
|
||||||
def 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)
|
auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
|
||||||
if not auth_manager.validate_token(cache_handler.get_cached_token()):
|
if not auth_manager.validate_token(cache_handler.get_cached_token()):
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
|
|||||||
@ -2,6 +2,7 @@ __all__ = [
|
|||||||
'CacheHandler',
|
'CacheHandler',
|
||||||
'CacheFileHandler',
|
'CacheFileHandler',
|
||||||
'DjangoSessionCacheHandler',
|
'DjangoSessionCacheHandler',
|
||||||
|
'FlaskSessionCacheHandler',
|
||||||
'MemoryCacheHandler',
|
'MemoryCacheHandler',
|
||||||
'RedisCacheHandler']
|
'RedisCacheHandler']
|
||||||
|
|
||||||
@ -147,6 +148,31 @@ class DjangoSessionCacheHandler(CacheHandler):
|
|||||||
logger.warning("Error saving token to cache: " + str(e))
|
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):
|
class RedisCacheHandler(CacheHandler):
|
||||||
"""
|
"""
|
||||||
A cache handler that stores the token info in the Redis.
|
A cache handler that stores the token info in the Redis.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user