Decorator to pickle function results
#!/usr/bin/python3.6
import pickle
import re
from os.path import join, exists
from typing import Callable
from decorator import decorator
def slugify(s: str):
""" Helper function.
Simplifies ugly strings into something URL-friendly.
https://blog.dolphm.com/slugify-a-string-in-python/
>>> print(slugify("[Some] _ Article's Title--"))
some-articles-title
"""
# "[Some] _ Article's Title--"
# "[some] _ article's title--"
s = s.lower()
# "[some] _ article's_title--"
# "[some]___article's_title__"
for c in [' ', '-', '.', '/']:
s = s.replace(c, '_')
# "[some]___article's_title__"
# "some___articles_title__"
s = re.sub('\W', '', s)
# "some___articles_title__"
# "some articles title "
s = s.replace('_', ' ')
# "some articles title "
# "some articles title "
s = re.sub('\s+', ' ', s)
# "some articles title "
# "some articles title"
s = s.strip()
# "some articles title"
# "some-articles-title"
s = s.replace(' ', '-')
return s
@decorator
def cache_pickle(func: Callable, path_to_cache: str = None, *args, **kwargs):
''' Caches function result to pickle file in directory provided in path_to_cache.
Args:
func: computationally heavy function
path_to_cache: path to cached pickle
'''
key = slugify(f'{func.__name__}_{args}_{kwargs}')
filename = f'_cached_{key}.pickle'
cache_filepath = join(path_to_cache, filename) if path_to_cache else key
if exists(cache_filepath):
with open(cache_filepath, 'rb') as fh:
result = pickle.load(fh)
else:
result = func(*args, **kwargs)
with open(cache_filepath, 'wb') as fh:
pickle.dump(result, fh)
return result
decorator==4.3.0