Skip to content

Commit

Permalink
convert docstings to reStructuredText format for cache_handler.py, ex…
Browse files Browse the repository at this point in the history
…ceptions.py, oauth2.py, scope.py, util.py
  • Loading branch information
dieser-niko committed Jan 24, 2025
1 parent 76ad4a6 commit f312d7a
Show file tree
Hide file tree
Showing 5 changed files with 387 additions and 138 deletions.
121 changes: 97 additions & 24 deletions spotipy/cache_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,25 @@ class CacheHandler(ABC):

@abstractmethod
def get_cached_token(self) -> TokenInfo | None:
"""Get and return a token_info dictionary object."""
"""
Get and return a token_info dictionary object.
:return: A token_info dictionary object or None if no token is cached.
"""

@abstractmethod
def save_token_to_cache(self, token_info: TokenInfo) -> None:
"""Save a token_info dictionary object to the cache and return None."""
"""
Save a token_info dictionary object to the cache.
:param token_info: A token_info dictionary object to be cached.
"""


class CacheFileHandler(CacheHandler):
"""Read and write cached Spotify authorization tokens as json files on disk."""
"""
Read and write cached Spotify authorization tokens as json files on disk.
"""

def __init__(
self,
Expand All @@ -82,7 +92,11 @@ def __init__(
self.cache_path = cache_path

def get_cached_token(self) -> TokenInfo | None:
"""Get cached token from file."""
"""
Get cached token from file.
:return: A token_info dictionary object or None if no token is cached.
"""
token_info: TokenInfo | None = None

try:
Expand All @@ -100,7 +114,11 @@ def get_cached_token(self) -> TokenInfo | None:
return token_info

def save_token_to_cache(self, token_info: TokenInfo) -> None:
"""Save token cache to file."""
"""
Save token cache to file.
:param token_info: A token_info dictionary object to be cached.
"""
try:
f = open(self.cache_path, "w")
f.write(json.dumps(token_info, cls=self.encoder_cls))
Expand All @@ -110,22 +128,32 @@ def save_token_to_cache(self, token_info: TokenInfo) -> None:


class MemoryCacheHandler(CacheHandler):
"""Cache handler that stores the token non-persistently as an instance attribute."""
"""
Cache handler that stores the token non-persistently as an instance attribute.
"""

def __init__(self, token_info: TokenInfo | None = None) -> None:
"""
Initialize MemoryCacheHandler instance.
:param token_info: Optional initial cached token
:param token_info: Optional initial cached token.
"""
self.token_info = token_info

def get_cached_token(self) -> TokenInfo | None:
"""Retrieve the cached token from the instance."""
"""
Retrieve the cached token from the instance.
:return: A token_info dictionary object or None if no token is cached.
"""
return self.token_info

def save_token_to_cache(self, token_info: TokenInfo) -> None:
"""Cache the token in this instance."""
"""
Cache the token in this instance.
:param token_info: A token_info dictionary object to be cached.
"""
self.token_info = token_info


Expand All @@ -139,13 +167,18 @@ class DjangoSessionCacheHandler(CacheHandler):

def __init__(self, request):
"""
Parameters:
* request: HttpRequest object provided by Django for every
incoming request
Initialize DjangoSessionCacheHandler instance.
:param request: HttpRequest object provided by Django for every incoming request.
"""
self.request = request

def get_cached_token(self):
"""
Retrieve the cached token from the Django session.
:return: A token_info dictionary object or None if no token is cached.
"""
token_info = None
try:
token_info = self.request.session["token_info"]
Expand All @@ -155,6 +188,11 @@ def get_cached_token(self):
return token_info

def save_token_to_cache(self, token_info):
"""
Cache the token in the Django session.
:param token_info: A token_info dictionary object to be cached.
"""
try:
self.request.session["token_info"] = token_info
except Exception as e:
Expand All @@ -164,13 +202,23 @@ def save_token_to_cache(self, token_info):
class FlaskSessionCacheHandler(CacheHandler):
"""
A cache handler that stores the token info in the session framework
provided by flask.
provided by Flask.
"""

def __init__(self, session):
"""
Initialize FlaskSessionCacheHandler instance.
:param session: Flask session object.
"""
self.session = session

def get_cached_token(self):
"""
Retrieve the cached token from the Flask session.
:return: A token_info dictionary object or None if no token is cached.
"""
token_info = None
try:
token_info = self.session["token_info"]
Expand All @@ -180,27 +228,38 @@ def get_cached_token(self):
return token_info

def save_token_to_cache(self, token_info):
"""
Cache the token in the Flask session.
:param token_info: A token_info dictionary object to be cached.
"""
try:
self.session["token_info"] = token_info
except Exception as e:
logger.warning(f"Error saving token to cache: {e}")


class RedisCacheHandler(CacheHandler):
"""A cache handler that stores the token info in the Redis."""
"""
A cache handler that stores the token info in Redis.
"""

def __init__(self, redis_obj: redis.client.Redis, key: str | None = None) -> None:
"""
Initialize RedisCacheHandler instance.
:param redis: The Redis object to function as the cache
:param key: (Optional) The key to used to store the token in the cache
:param redis_obj: The Redis object to function as the cache.
:param key: (Optional) The key to use to store the token in the cache.
"""
self.redis = redis_obj
self.key = key or "token_info"

def get_cached_token(self) -> TokenInfo | None:
"""Fetch cache token from the Redis."""
"""
Fetch cached token from Redis.
:return: A token_info dictionary object or None if no token is cached.
"""
token_info = None
try:
token_info = self.redis.get(self.key)
Expand All @@ -212,29 +271,38 @@ def get_cached_token(self) -> TokenInfo | None:
return token_info

def save_token_to_cache(self, token_info: TokenInfo) -> None:
"""Cache token in the Redis."""
"""
Cache token in Redis.
:param token_info: A token_info dictionary object to be cached.
"""
try:
self.redis.set(self.key, json.dumps(token_info))
except RedisError as e:
logger.warning(f"Error saving token to cache: {e}")


class MemcacheCacheHandler(CacheHandler):
"""A Cache handler that stores the token info in Memcache using the pymemcache client
"""
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`)
Initialize MemcacheCacheHandler instance.
:param memcache: Memcache client object provided by pymemcache.
:param key: (Optional) The key to use to store the token in the cache.
"""
self.memcache = memcache
self.key = key or "token_info"

def get_cached_token(self):
"""
Fetch cached token from Memcache.
:return: A token_info dictionary object or None if no token is cached.
"""
from pymemcache import MemcacheError

try:
Expand All @@ -245,6 +313,11 @@ def get_cached_token(self):
logger.warning(f"Error getting token to cache: {e}")

def save_token_to_cache(self, token_info):
"""
Cache token in Memcache.
:param token_info: A token_info dictionary object to be cached.
"""
from pymemcache import MemcacheError

try:
Expand Down
27 changes: 25 additions & 2 deletions spotipy/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ class SpotifyBaseException(Exception):


class SpotifyException(SpotifyBaseException):
"""
Exception raised for Spotify API errors.
:param http_status: The HTTP status code returned by the API.
:param code: The specific error code returned by the API.
:param msg: The error message returned by the API.
:param reason: (Optional) The reason for the error.
:param headers: (Optional) The headers returned by the API.
"""

def __init__(self, http_status, code, msg, reason=None, headers=None):
self.http_status = http_status
Expand All @@ -22,7 +31,13 @@ def __str__(self):


class SpotifyOauthError(SpotifyBaseException):
""" Error during Auth Code or Implicit Grant flow """
"""
Exception raised for errors during Auth Code or Implicit Grant flow.
:param message: The error message.
:param error: (Optional) The specific error code.
:param error_description: (Optional) A description of the error.
"""

def __init__(self, message, error=None, error_description=None, *args, **kwargs):
self.error = error
Expand All @@ -32,7 +47,15 @@ def __init__(self, message, error=None, error_description=None, *args, **kwargs)


class SpotifyStateError(SpotifyOauthError):
""" The state sent and state received were different """
"""
Exception raised when the state sent and state received are different.
:param local_state: The state sent.
:param remote_state: The state received.
:param message: (Optional) The error message.
:param error: (Optional) The specific error code.
:param error_description: (Optional) A description of the error.
"""

def __init__(self, local_state=None, remote_state=None, message=None,
error=None, error_description=None, *args, **kwargs):
Expand Down
Loading

0 comments on commit f312d7a

Please sign in to comment.