Persistent, Stale-Free Caching for Python Functions
Cachier is a Python library that provides persistent, stale-free memoization decorators for Python functions. It supports various storage backends including local filesystem (pickle), in-memory, MongoDB, Redis, SQL, and S3, offering configurable cache expiration and automatic invalidation. The library is actively maintained with frequent releases, currently at version 4.2.0, and supports both synchronous and asynchronous functions.
Warnings
- breaking Starting with v3.0.0, cache keys now consider the function's name. If you upgrade from versions prior to 3.0.0 and relied on cache keys being agnostic to function names (e.g., if you copied and renamed functions), your existing cache entries might not be found or could cause collisions.
- breaking In v4.0.0, the `enable_caching()` and `disable_caching()` global functions now correctly affect *all* existing `@cachier` decorators. Previously, they might not have had an effect on decorators already applied. Additionally, `cachier` adopted the XDG Base Directory Specification for cache file locations, which might change the default cache directory (e.g., from `~/.cachier` to `~/.cache/cachier` on Linux).
- gotcha By default, `cachier` will raise a `TypeError` when decorating an instance method (a method whose first parameter is named `self`). This is to prevent unintended cross-instance cache sharing. If you explicitly want cross-instance cache sharing for a method, you must pass `allow_non_static_methods=True` to the decorator.
- gotcha Functions decorated with `cachier` require all positional and keyword arguments to be hashable Python objects. If an unhashable argument is passed (e.g., a list or dictionary), a `TypeError` will be raised.
- gotcha Asynchronous functions decorated with `cachier` will have their operations delegated to the synchronous implementation for many backends. Starting with v4.2.0, decorating async methods with sync-only engines of Redis, Mongo, and SQL cores is restricted and may lead to errors or unexpected behavior.
- gotcha By default, `cachier` does not cache `None` values returned by a function. If your function can legitimately return `None` and you wish to cache it, you must explicitly enable this behavior.
Install
-
pip install cachier -
pip install cachier[redis,mongo,sql,s3]
Imports
- cachier
from cachier import cachier
- set_global_params
from cachier import set_default_params
from cachier import set_global_params
Quickstart
from cachier import cachier
from datetime import timedelta
@cachier(stale_after=timedelta(days=1))
def long_running_function(arg1, arg2):
"""This function's result will be cached for 1 day."""
print(f"Calculating result for {arg1}, {arg2}...")
# Simulate a long computation
import time
time.sleep(1)
return arg1 + arg2
# First call: calculates and caches the result
print(f"Result 1: {long_running_function(10, 20)}")
# Second call (within 1 day): returns from cache instantly
print(f"Result 2: {long_running_function(10, 20)}")
# To clear the cache for a specific function:
long_running_function.clear_cache()