Shelved Cache

0.5.0 · active · verified Thu Apr 09

Shelved Cache (version 0.5.0) is a Python library that provides a persistent cache implementation for `cachetools` objects, storing entries to disk using Python's `shelve` module. It allows for fast, persistent caching of function results across program executions. The library is actively maintained, integrating with standard Python caching mechanisms.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use `shelved-cache` to make a `cachetools.LRUCache` persistent. It shows a function being decorated, calls it multiple times to demonstrate caching, explicitly closes the cache, and then reopens it in a simulated new process to prove persistence. Ensure proper cleanup of the cache files created.

import cachetools
from shelved_cache import PersistentCache
from cachetools import LRUCache
import os

# Define a unique cache file path
cache_file = "my_function_cache.db"

# --- Cleanup any previous cache files for a clean run ---
# shelve can create multiple files (.db, .bak, .dir, .dat)
for ext in ["", ".bak", ".dir", ".dat"]:
    if os.path.exists(cache_file + ext):
        os.remove(cache_file + ext)

# Initialize a persistent LRU cache, linking it to a file
pc_for_square = PersistentCache(LRUCache, cache_file, maxsize=100)

@cachetools.cached(pc_for_square)
def square(x):
    print(f"Calculating square for {x}...")
    return x * x

# First call: calculation happens
result1 = square(5)
print(f"First call: square(5) = {result1}")

# Second call: result is retrieved from cache (no 'Calculating...' output)
result2 = square(5)
print(f"Second call: square(5) = {result2}")

# A different argument will trigger a new calculation and cache entry
result3 = square(10)
print(f"Third call: square(10) = {result3}")

# It's crucial to close the persistent cache to ensure data is written to disk.
pc_for_square.close()

print("\n--- Cache closed and reopened to demonstrate persistence ---")

# Simulate a new application run or process by creating a new PersistentCache instance
# linked to the *same* file.
pc_reopened = PersistentCache(LRUCache, cache_file, maxsize=100)

@cachetools.cached(pc_reopened)
def square_reopened(x):
    # This should *not* print if the value was correctly persisted
    print(f"Calculating square (reopened) for {x}...")
    return x * x

# This call should retrieve from the persisted cache without recalculating
result_reopened = square_reopened(5)
print(f"Reopened call: square_reopened(5) = {result_reopened}")

pc_reopened.close()

# --- Final cleanup of created cache files ---
for ext in ["", ".bak", ".dir", ".dat"]:
    if os.path.exists(cache_file + ext):
        os.remove(cache_file + ext)

view raw JSON →