diff --git a/CHANGELOG.md b/CHANGELOG.md index ee15d5c3..8e6684e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -// Add your changes here and then delete this line +### Added +* Added `RedisCacheHandler`, a cache handler that stores the token info in Redis. ## [2.19.0] - 2021-08-12 diff --git a/docs/index.rst b/docs/index.rst index edff1c3a..f65d0317 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -231,6 +231,11 @@ The custom cache handler would need to be a class that inherits from the base cache handler ``CacheHandler``. The default cache handler ``CacheFileHandler`` is a good example. An instance of that new class can then be passed as a parameter when creating ``SpotifyOAuth``, ``SpotifyPKCE`` or ``SpotifyImplicitGrant``. +The following handlers are available and defined in the URL above. + - ``CacheFileHandler`` + - ``MemoryCacheHandler`` + - ``DjangoSessionCacheHandler`` + - ``RedisCacheHandler`` Feel free to contribute new cache handlers to the repo. diff --git a/setup.py b/setup.py index af279e33..6085776b 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,7 @@ author_email="paul@echonest.com", url='https://spotipy.readthedocs.org/', install_requires=[ + 'redis>=3.5.3', 'requests>=2.25.0', 'six>=1.15.0', 'urllib3>=1.26.0' diff --git a/spotipy/cache_handler.py b/spotipy/cache_handler.py index eb9e5f28..4c0ef9f0 100644 --- a/spotipy/cache_handler.py +++ b/spotipy/cache_handler.py @@ -1,4 +1,9 @@ -__all__ = ['CacheHandler', 'CacheFileHandler', 'DjangoSessionCacheHandler', 'MemoryCacheHandler'] +__all__ = [ + 'CacheHandler', + 'CacheFileHandler', + 'DjangoSessionCacheHandler', + 'MemoryCacheHandler', + 'RedisCacheHandler'] import errno import json @@ -6,6 +11,8 @@ import os from spotipy.util import CLIENT_CREDS_ENV_VARS +from redis import RedisError + logger = logging.getLogger(__name__) @@ -138,3 +145,32 @@ def save_token_to_cache(self, token_info): self.request.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. + """ + + def __init__(self, redis): + """ + Parameters: + * redis: Redis object provided by redis-py library + (https://github.com/redis/redis-py) + """ + self.redis = redis + + def get_cached_token(self): + token_info = None + try: + token_info = json.loads(self.redis.get('token_info')) + except RedisError as e: + logger.warning('Error getting token from cache: ' + str(e)) + + return token_info + + def save_token_to_cache(self, token_info): + try: + self.redis.set('token_info', json.dumps(token_info)) + except RedisError as e: + logger.warning('Error saving token to cache: ' + str(e))