Simple file based JSON cache in Python
Imagine your program needs something that takes a bit of time to retrieve, such as a token that is retrieved from an API call.
There are lots of caching options around, but sometimes you need something truly small and convenient;
- Get token or result from an API call (maybe this takes a second or two, so we don’t want to repeat it often)
- Store the result in a file cache.
Next time around:
3. Get token from cache, since the cache file now exists. Let’s use JSON as a serialization format.
Python decorators to the rescue.
A decorator is basically a callable Python object that’s used to modify a function or a class. We’re basically intercepting or hijacking existing functionality.
@cached_token('token-cache.json')
def get_token():
# imaginary API call to get token
import time; time.sleep(3)
return '7c5d3ca5-0088-49a7-ae30-011931a44075' # imaginary tokenOur thinking process now can be as follows;
Define decorator
def cached_token(jsonfile):
def decorator(fn):
def wrapped(*args, **kwargs):
print(f'TODO: We want to use {jsonfile} for caching!')
return fn(*args, **kwargs)
return wrapped
return decoratorAt this point, we’re not actually modifying anything. Running it, we’ll see this behavior:
>>> get_token()
TODO: We want to use token-cache.json for caching!
'7c5d3ca5-0088-49a7-ae30-011931a44075'
>>>Write caching logic
We want to basically do the following, which will be summarized in the full code listing below.
- Inside wrapped() (within the decorator), we check if cache file already exists.
- If it exists: we read from it using json.load(). We then return the token — appending the text “(cached!!)”
- If it did not exist: we execute the function (res = fn(*args, **kwargs) as it would have been done normally. Then we save that token to the cache file, and finally we return it.
Source code
Notes
Hope you enjoyed this little Python tutorial. There’s of course so much more stuff you can do, and stuff you absolutely must do like checking the cache file for age to determine whether it has expired.
