Persistent, stale-free, local and cross-machine caching for Python functions.
npx @tessl/cli install tessl/pypi-cachier@4.1.0Cachier provides persistent, stale-free memoization decorators for Python functions, enabling comprehensive caching with multiple storage backends including memory, filesystem (pickle), MongoDB, Redis, and SQL databases. It offers configurable cache expiration through stale_after parameters, automatic cache invalidation, cross-machine caching capabilities for distributed computing environments, and supports both synchronous and asynchronous function caching.
pip install cachierimport cachierCommon usage pattern:
from cachier import cachier, set_global_params, enable_caching, disable_cachingAll public APIs are available from the main module:
from cachier import (
cachier, # Main decorator
set_global_params, # Global configuration
get_global_params, # Get global config
enable_caching, # Enable caching globally
disable_caching, # Disable caching globally
__version__ # Version string
)from cachier import cachier
from datetime import timedelta
# Simple persistent caching with default pickle backend
@cachier()
def expensive_computation(n):
# Simulate expensive computation
result = sum(i**2 for i in range(n))
return result
# Use the cached function
result1 = expensive_computation(1000) # Computed and cached
result2 = expensive_computation(1000) # Retrieved from cache
# Caching with expiration after 1 hour
@cachier(stale_after=timedelta(hours=1))
def fetch_data(url):
# Fetch data from API
import requests
return requests.get(url).json()
# Multi-backend example with MongoDB
@cachier(backend='mongo', mongetter=lambda: my_mongo_collection)
def cached_analysis(data_id):
# Perform analysis on data
return analyze_data(data_id)
# Clear cache when needed
expensive_computation.clear_cache()The main cachier decorator that provides persistent, stale-free memoization with multiple backend support and extensive configuration options.
def cachier(
hash_func: Optional[HashFunc] = None,
hash_params: Optional[HashFunc] = None, # Deprecated
backend: Optional[Backend] = None,
mongetter: Optional[Mongetter] = None,
sql_engine: Optional[Union[str, Any, Callable[[], Any]]] = None,
redis_client: Optional[RedisClient] = None,
stale_after: Optional[timedelta] = None,
next_time: Optional[bool] = None,
cache_dir: Optional[Union[str, os.PathLike]] = None,
pickle_reload: Optional[bool] = None,
separate_files: Optional[bool] = None,
wait_for_calc_timeout: Optional[int] = None,
allow_none: Optional[bool] = None,
cleanup_stale: Optional[bool] = None,
cleanup_interval: Optional[timedelta] = None,
):
"""
Wrap as a persistent, stale-free memoization decorator.
Parameters:
- hash_func: Custom hash function for arguments
- backend: Backend type ('pickle', 'mongo', 'memory', 'redis', 'sql')
- mongetter: MongoDB collection getter function
- sql_engine: SQLAlchemy engine
- redis_client: Redis client instance or callable
- stale_after: Time after which cache becomes stale
- next_time: Return stale result while recalculating in background
- cache_dir: Cache directory path
- pickle_reload: Reload in-memory cache on each read
- separate_files: Split cache into separate files per argument set
- wait_for_calc_timeout: Max wait time for ongoing calculations
- allow_none: Allow caching None values
- cleanup_stale: Automatically delete stale entries
- cleanup_interval: Minimum time between cleanup runs
Returns:
Decorated function with attached cache management methods
"""Functions for managing global caching parameters that apply to all memoized functions unless overridden by individual decorators.
def set_global_params(**params: Any) -> None:
"""
Configure global parameters applicable to all memoized functions.
Parameters:
- **params: Keyword parameters matching decorator parameters
"""
def get_global_params() -> Params:
"""
Get current set of global parameters.
Returns:
Params dataclass instance with current global settings
"""
def enable_caching() -> None:
"""Enable caching globally."""
def disable_caching() -> None:
"""Disable caching globally."""Built-in methods attached to decorated functions for managing cached data and controlling cache behavior.
# Methods attached to decorated functions
def clear_cache() -> None:
"""Clear all cached entries for this function."""
def clear_being_calculated() -> None:
"""Mark all entries as not being calculated."""
def cache_dpath() -> Optional[str]:
"""Return cache directory path if exists, None otherwise."""
def precache_value(*args, value_to_cache, **kwargs):
"""
Add an initial value to the cache.
Parameters:
- *args, **kwargs: Function arguments to cache value for
- value_to_cache: Entry to be written into the cache
"""Multiple storage backends for different caching requirements, from in-memory to distributed caching solutions.
# Available backend types
Backend = Literal["pickle", "mongo", "memory", "redis", "sql"]Core type definitions used throughout the cachier API:
from typing import Callable, Literal, Union, Optional
from datetime import timedelta
import os
HashFunc = Callable[..., str]
Mongetter = Callable[[], "pymongo.collection.Collection"]
RedisClient = Union["redis.Redis", Callable[[], "redis.Redis"]]
Backend = Literal["pickle", "mongo", "memory", "redis", "sql"]
class Params:
"""Global configuration parameters dataclass."""
caching_enabled: bool = True
hash_func: HashFunc = _default_hash_func
backend: Backend = "pickle"
mongetter: Optional[Mongetter] = None
stale_after: timedelta = timedelta.max
next_time: bool = False
cache_dir: Union[str, os.PathLike] = LazyCacheDir() # XDG-compliant cache directory or ~/.cachier/
pickle_reload: bool = True
separate_files: bool = False
wait_for_calc_timeout: int = 0
allow_none: bool = False
cleanup_stale: bool = False
cleanup_interval: timedelta = timedelta(days=1)Legacy functions maintained for backwards compatibility:
def set_default_params(**params: Any) -> None:
"""
Deprecated: Use set_global_params instead.
Configure default parameters applicable to all memoized functions.
"""
def get_default_params() -> Params:
"""
Deprecated: Use get_global_params instead.
Get current set of default parameters.
"""Cachier provides a command-line interface for managing cache behavior:
# Set maximum number of worker threads
python -m cachier set_max_workers 16cachier --help # Show help information
cachier set_max_workers <number> # Set maximum worker threads for background operationsThe CLI allows configuration of cachier's thread pool used for background cache operations like cleanup and refresh tasks.