Added MemcacheCacheHandler (#1042)

* Added MemcacheCacheHandler

* Import MemcacheError where used

* Update index.rst

---------

Co-authored-by: Stéphane Bruckert <stephane.bruckert@gmail.com>
This commit is contained in:
andrewcara 2024-05-30 14:01:16 -04:00 committed by GitHub
parent 913ae57275
commit 62a27a20e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 44 additions and 4 deletions

View File

@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased ## Unreleased
### Added ### Added
- Added `MemcacheCacheHandler`, a cache handler that stores the token info using pymemcache.
- Added support for audiobook endpoints: get_audiobook, get_audiobooks, and get_audiobook_chapters. - Added support for audiobook endpoints: get_audiobook, get_audiobooks, and get_audiobook_chapters.
- Added integration tests for audiobook endpoints. - Added integration tests for audiobook endpoints.
- Removed `python 2.7` from GitHub Actions CI workflow. Python v2.7 reached end of life support and is no longer supported by Ubuntu 20.04. - Removed `python 2.7` from GitHub Actions CI workflow. Python v2.7 reached end of life support and is no longer supported by Ubuntu 20.04.

View File

@ -185,14 +185,17 @@ cache handler ``CacheHandler``. The default cache handler ``CacheFileHandler`` i
An instance of that new class can then be passed as a parameter when An instance of that new class can then be passed as a parameter when
creating ``SpotifyOAuth``, ``SpotifyPKCE`` or ``SpotifyImplicitGrant``. creating ``SpotifyOAuth``, ``SpotifyPKCE`` or ``SpotifyImplicitGrant``.
The following handlers are available and defined in the URL above. The following handlers are available and defined in the URL above.
- ``CacheFileHandler`` - ``CacheFileHandler``
- ``MemoryCacheHandler`` - ``MemoryCacheHandler``
- ``DjangoSessionCacheHandler`` - ``DjangoSessionCacheHandler``
- ``FlaskSessionCacheHandler`` - ``FlaskSessionCacheHandler``
- ``RedisCacheHandler`` - ``RedisCacheHandler``
- ``MemcacheCacheHandler``: install with dependency using ``pip install "spotipy[pymemcache]"``
Feel free to contribute new cache handlers to the repo. Feel free to contribute new cache handlers to the repo.
Examples Examples
======================= =======================

View File

@ -7,8 +7,13 @@ test_reqs = [
'mock==2.0.0' 'mock==2.0.0'
] ]
memcache_cache_reqs = [
'pymemcache>=3.5.2'
]
extra_reqs = { extra_reqs = {
'test': test_reqs 'test': test_reqs,
'memcache': memcache_cache_reqs
} }
setup( setup(
@ -25,7 +30,7 @@ setup(
}, },
python_requires='>3.8', python_requires='>3.8',
install_requires=[ install_requires=[
"redis>=3.5.3", "redis>=3.5.3", # TODO: Move to extras_require in v3
"requests>=2.25.0", "requests>=2.25.0",
"urllib3>=1.26.0" "urllib3>=1.26.0"
], ],

View File

@ -4,7 +4,8 @@ __all__ = [
'DjangoSessionCacheHandler', 'DjangoSessionCacheHandler',
'FlaskSessionCacheHandler', 'FlaskSessionCacheHandler',
'MemoryCacheHandler', 'MemoryCacheHandler',
'RedisCacheHandler'] 'RedisCacheHandler',
'MemcacheCacheHandler']
import errno import errno
import json import json
@ -208,3 +209,34 @@ class RedisCacheHandler(CacheHandler):
self.redis.set(self.key, json.dumps(token_info)) self.redis.set(self.key, json.dumps(token_info))
except RedisError as e: except RedisError as e:
logger.warning('Error saving token to cache: ' + str(e)) logger.warning('Error saving token to cache: ' + str(e))
class MemcacheCacheHandler(CacheHandler):
"""A Cache handler that stores the token info in Memcache using the pymemcache client
"""
def __init__(self, memcache, key=None) -> None:
"""
Parameters:
* memcache: memcache client object provided by pymemcache
(https://pymemcache.readthedocs.io/en/latest/getting_started.html)
* key: May be supplied, will otherwise be generated
(takes precedence over `token_info`)
"""
self.memcache = memcache
self.key = key if key else 'token_info'
def get_cached_token(self):
from pymemcache import MemcacheError
try:
token_info = self.memcache.get(self.key)
if token_info:
return json.loads(token_info.decode())
except MemcacheError as e:
logger.warning('Error getting token from cache' + str(e))
def save_token_to_cache(self, token_info):
from pymemcache import MemcacheError
try:
self.memcache.set(self.key, json.dumps(token_info))
except MemcacheError as e:
logger.warning('Error saving token to cache' + str(e))