diff --git a/CHANGELOG.md b/CHANGELOG.md
index f328ff27..1b27c955 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/docs/index.rst b/docs/index.rst
index c4917954..c9622921 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -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.
diff --git a/examples/app.py b/examples/app.py
index aa6ad19a..f177fc39 100644
--- a/examples/app.py
+++ b/examples/app.py
@@ -27,7 +27,6 @@
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,57 +34,44 @@
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)
+ 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'
'
- # Step 4. Signed in, display data
+ # Step 3. Signed in, display data
spotify = spotipy.Spotify(auth_manager=auth_manager)
return f'Hi {spotify.me()["display_name"]}, ' \
f'[sign out]
' \
f'my playlists | ' \
f'currently playing | ' \
- f'me' \
+ f'me' \
+
@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('/')
diff --git a/spotipy/cache_handler.py b/spotipy/cache_handler.py
index cd4567fa..2645f25b 100644
--- a/spotipy/cache_handler.py
+++ b/spotipy/cache_handler.py
@@ -2,6 +2,7 @@
'CacheHandler',
'CacheFileHandler',
'DjangoSessionCacheHandler',
+ 'FlaskSessionCacheHandler',
'MemoryCacheHandler',
'RedisCacheHandler']
@@ -147,6 +148,31 @@ def save_token_to_cache(self, token_info):
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.