DiskCache
DiskCache is an Apache2 licensed disk and file backed cache library, written in pure-Python, and compatible with Django. It provides a dictionary-like interface for persistent caching, leveraging SQLite for storage. The current version is 5.6.3, and it follows a major.minor.micro versioning scheme, with major versions intended for significant new features and potential breaking changes, though not always guaranteed.
Warnings
- breaking Major version changes (e.g., 5.x.x to 6.x.x) are intended for significant new features and may introduce backward incompatibilities. It is recommended to pin at least the major version (e.g., `diskcache~=5.0`) in production to avoid unexpected issues during upgrades.
- gotcha By default, DiskCache uses Python's `pickle` module for serialization of both keys and values. This can lead to two issues: (1) Inconsistencies for container types (like tuples) used as keys, as `pickle` might serialize equal objects differently. (2) A significant security vulnerability (CVE-2025-69872) where an attacker with write access to the cache directory could execute arbitrary code upon deserialization.
- gotcha While DiskCache provides a dictionary-like interface, it does NOT use Python's standard `__hash__` and `__eq__` methods for key lookups. Instead, key equality is determined by the configured serialization method's byte representation. This can lead to unexpected behavior for complex objects or large integers that might be considered equal in Python but serialize differently.
- gotcha Using 'least-recently-used' (LRU) or 'least-frequently-used' (LFU) eviction policies causes every cache access to be a read *and* a write operation (to update access time/count). This can significantly slow down read-heavy workloads compared to the default 'least-recently-stored' (LRS) policy, which only involves a write on item storage.
- gotcha The cache directory and its contents are NOT automatically removed when the `Cache` object is closed or garbage collected. This means cached data will persist across application restarts.
- gotcha While `diskcache.Cache` is thread-safe and process-safe, for applications with many concurrent *writers*, a single `Cache` instance can become a bottleneck due to SQLite's writer-locks.
Install
-
pip install diskcache
Imports
- Cache
from diskcache import Cache
- FanoutCache
from diskcache import FanoutCache
- DjangoCache
from diskcache import DjangoCache
- Index
from diskcache import Index
- Deque
from diskcache import Deque
- JSONDisk
from diskcache import JSONDisk
Quickstart
import os
from diskcache import Cache
# Create a cache in a local directory (will be created if it doesn't exist)
# For production, specify a persistent path; for examples, a temporary path is fine.
cache_dir = os.path.join(os.getcwd(), 'my_diskcache_data')
cache = Cache(cache_dir)
try:
# Set items in the cache
cache['my_key'] = 'Hello, DiskCache!'
cache.set('another_key', {'data': [1, 2, 3]}, expire=300) # expires in 5 minutes
# Retrieve items from the cache
value1 = cache['my_key']
value2 = cache.get('another_key')
value3 = cache.get('non_existent_key', 'default_value') # with a default
print(f"Value for 'my_key': {value1}")
print(f"Value for 'another_key': {value2}")
print(f"Value for 'non_existent_key': {value3}")
# Check if a key exists
if 'my_key' in cache:
print("'my_key' is in the cache.")
# Delete an item
del cache['my_key']
print(f"'my_key' after deletion: {cache.get('my_key', 'DELETED')}")
finally:
# It's crucial to close the cache for proper shutdown and resource release.
cache.close()
# For examples, clean up the created directory. In production, you would not typically delete it.
if os.path.exists(cache_dir):
import shutil
shutil.rmtree(cache_dir)
print(f"Cleaned up cache directory: {cache_dir}")