Skip to content

Instantly share code, notes, and snippets.

@rotaliator
Last active February 13, 2019 21:30
Show Gist options
  • Save rotaliator/95fc508199a7d1a7aab38f177425b739 to your computer and use it in GitHub Desktop.
Save rotaliator/95fc508199a7d1a7aab38f177425b739 to your computer and use it in GitHub Desktop.
import json
from functools import wraps
from hashlib import sha1
CACHE_DIR = '_cache/'
MAX_FILENAME_LENGTH = 40
class CacheNotFound(Exception):
pass
def _args_to_fname(name, args, kwargs)-> str:
arg_kw = str(args) + str(kwargs)
arg_kw = "".join(c if c.isalnum() else '_' for c in arg_kw)
fname = name + '_' + arg_kw
while '__' in fname:
fname = fname.replace('__', '_')
if len(fname) > MAX_FILENAME_LENGTH:
# name too long. using hash.
fname = sha1(fname.encode()).hexdigest()
return fname
def _save_result_to_file(fname, result):
mode = 'w'
if isinstance(result, dict):
result = json.dumps(result, indent=4)
if isinstance(result, bytes):
mode = 'wb'
with open(CACHE_DIR + fname, mode) as f:
f.write(result)
def _read_cache_from_file(fname):
mode = 'r'
if fname.startswith('fullimage'):
mode = 'rb'
try:
with open(CACHE_DIR + fname, mode) as f:
print(f"reading from cache: {fname}")
result = f.read()
if isinstance(result, str):
if result.startswith('{') or result.startswith('['):
result = json.loads(result)
return result
except FileNotFoundError:
raise CacheNotFound
def cache_local(f):
@wraps(f)
def decorated(*args, **kwargs):
fname = _args_to_fname(decorated.__name__, args, kwargs)
try:
result = _read_cache_from_file(fname)
except CacheNotFound:
result = f(*args, **kwargs)
print(f"saving cache: {fname}")
_save_result_to_file(fname, result)
return result
return decorated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment