### Install perscache
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Installation command for the package.
```bash
pip install perscache
```
--------------------------------
### Changing Default Serialization and Storage
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Illustrates how to configure a `Cache` instance with custom `serializer` and `storage` backends. This example sets up `JSONSerializer` and `GoogleCloudStorage` as defaults.
```python
# set up serialization format and storage backend
cache = Cache(
serializer=JSONSerializer(),
storage=GoogleCloudStorage("/bucket/folder")
)
...
# change the default serialization format
@cache(serialization=PickleSerializer())
def get_data(key):
...
```
--------------------------------
### Initialize Cache with Google Cloud Storage
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
Demonstrates how to initialize the Cache class with GoogleCloudStorage. Ensure 'gcsfs' is installed. The storage_options parameter is used to pass configuration to the underlying GCSFilesystem.
```python
from perscache import Cache
from perscache.storage import GoogleCloudStorage
cache = Cache(
storage=GoogleCloudStorage(
location="my-bucket/cache",
storage_options={"token": "my-token.json"}
)
)
@cache
def get_data():
...
```
--------------------------------
### Creating a Custom Serializer
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Provides an example of creating a custom serializer by inheriting from `perscache.serializers.Serializer`. This allows for custom data serialization and deserialization, with a specified file extension.
```python
from perscache.serializers import Serializer
class MySerializer(Serializer):
extension = "data"
def dumps(self, data: Any) -> bytes:
...
def loads(self, data: bytes) -> Any:
...
cache = Cache(serializer=MySerializer())
```
--------------------------------
### Custom In-Memory Storage Backend
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Implement a custom storage backend by extending the `Storage` base class. This example provides a simple in-memory storage for testing purposes, with `read` and `write` methods.
```python
import datetime as dt
from pathlib import Path
from typing import Union
from perscache import Cache
from perscache.storage import Storage, CacheExpired
class InMemoryStorage(Storage):
"""Simple in-memory storage for testing."""
def __init__(self):
self._store = {}
self._timestamps = {}
def read(self, path: Union[str, Path], deadline: dt.datetime) -> bytes:
key = str(path)
if key not in self._store:
raise FileNotFoundError(f"No cache entry for {key}")
if deadline and self._timestamps[key] < deadline:
raise CacheExpired()
return self._store[key]
def write(self, path: Union[str, Path], data: bytes) -> None:
key = str(path)
self._store[key] = data
self._timestamps[key] = dt.datetime.now(dt.timezone.utc)
cache = Cache(storage=InMemoryStorage())
@cache
def compute(x: int) -> int:
return x * 2
result = compute(5) # Cached in memory
```
--------------------------------
### Enable Debug Logging for Perscache
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Configure logging to view cache hits, misses, and hash generation details. This setup helps in debugging cache behavior.
```python
import logging
from perscache import Cache
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("perscache")
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)
cache = Cache()
@cache
def cached_function(x: int) -> int:
return x * 2
result = cached_function(5)
# Logs show: hash generation, cache miss/hit, file operations
```
--------------------------------
### Create Custom XML Serializer
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Use `make_serializer` to quickly define a custom serializer for XML data. This example shows how to specify dump and load functions for a simple XML format.
```python
XMLSerializer = make_serializer(
class_name="XMLSerializer",
ext="xml",
dumps_fn=lambda data: f"{data}".encode("utf-8"),
loads_fn=lambda data: data.decode("utf-8").replace("", "").replace("", "")
)
cache = Cache(serializer=XMLSerializer())
@cache
def get_message(key: str) -> str:
return f"Hello, {key}!"
result = get_message("world")
# File: .cache/get_message-.xml
# Contents: Hello, world!
```
--------------------------------
### Create Custom Compressed JSON Serializer
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Extend the `Serializer` base class to create a custom serializer for compressed JSON data. This example implements `dumps` and `loads` methods using `gzip` and `json` modules.
```python
from perscache import Cache
from perscache.serializers import Serializer
from typing import Any
class CompressedJSONSerializer(Serializer):
extension = "json.gz"
def dumps(self, data: Any) -> bytes:
import gzip
import json
json_bytes = json.dumps(data).encode("utf-8")
return gzip.compress(json_bytes)
def loads(self, data: bytes) -> Any:
import gzip
import json
json_bytes = gzip.decompress(data)
return json.loads(json_bytes.decode("utf-8"))
cache = Cache(serializer=CompressedJSONSerializer())
@cache
def get_large_data(key: str) -> dict:
return {"key": key, "payload": "x" * 10000}
result = get_large_data("test")
# File: .cache/get_large_data-.json.gz (compressed)
```
--------------------------------
### GoogleCloudStorage
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
Stores cache entries in separate files within a Google Cloud Storage Bucket. Requires the `gcsfs` module to be installed.
```APIDOC
## GoogleCloudStorage
### Description
Keeps cache entries in separate files in a Google Cloud Storage Bucket.
Relies on the [`gcsfs`](https://pypi.org/project/gcsfs/) module, which is not a part of the project dependencies and needs to to be installed by the user if he is to use this class.
### Parameters
#### Path Parameters
- **location** (str) - Required - A directory to store the cache files. Defaults to `".cache"`.
- **max_size** (int) - Optional - The maximum size for the cache. If set, then, before a new cache entry is written, the future size of the directory is calculated and the least recently used cache entries are removed. If `None`, the cache size grows indefinitely. Defaults to `None`.
- **storage_options** (dict) - Optional - A dictionary of parameters to pass to the constructor of the `GSCFilesystem` class of the [`gcsfs`](https://pypi.org/project/gcsfs/) module (see the module documentation for more information). Defaults to `None`.
### Request Example
```python
# supposing gcsfs is installed
from perscache import Cache
from perscache.storage import GoogleCloudStorage
cache = Cache(
storage=GoogleCloudStorage(
location="my-bucket/cache",
storage_options={"token": "my-token.json"}
)
)
@cache
def get_data():
...
```
```
--------------------------------
### Override Cache Serialization with Parquet
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Use the ParquetSerializer to cache DataFrame results. Ensure pandas is installed.
```python
from perscache import cache
from perscache.serializers import ParquetSerializer
@cache(serializer=ParquetSerializer())
def load_dataframe(source: str):
import pandas as pd
return pd.DataFrame({"col1": [1, 2, 3]})
```
--------------------------------
### Use basic caching
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Demonstrates function result persistence across calls.
```python
from perscache import Cache
cache = Cache()
counter = 0
@cache
def get_data():
print("Fetching data...")
global counter
counter += 1
return "abc"
print(get_data()) # the function is called
# Fetching data...
# abc
print(get_data()) # the cache is used
# abc
print(counter) # the function was called only once
# 1
```
--------------------------------
### Configure Instance Method Caching
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Demonstrates per-instance versus shared caching for class methods using the per_instance parameter.
```python
from perscache import Cache
cache = Cache()
class DataProcessor:
def __init__(self, name: str):
self.name = name
self.call_count = 0
@cache # Default: per_instance=True - each instance has separate cache
def process(self, value: int) -> int:
self.call_count += 1
print(f"{self.name} processing {value}...")
return value * 2
@cache(per_instance=False) # Shared cache across all instances
def compute_shared(self, value: int) -> int:
self.call_count += 1
print(f"{self.name} computing shared {value}...")
return value ** 2
# Per-instance caching (default)
proc1 = DataProcessor("Processor1")
proc2 = DataProcessor("Processor2")
result1 = proc1.process(10) # Output: Processor1 processing 10...
result2 = proc1.process(10) # No output - cache hit for proc1
result3 = proc2.process(10) # Output: Processor2 processing 10... (separate cache)
# Shared caching
result4 = proc1.compute_shared(5) # Output: Processor1 computing shared 5...
result5 = proc2.compute_shared(5) # No output - shared cache hit
```
--------------------------------
### Create Custom Serializer
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Initializes a custom serializer using the make_serializer factory function.
```python
from perscache import Cache
from perscache.serializers import make_serializer
```
--------------------------------
### Implement a custom storage back-end
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Define a custom storage class by implementing the read and write methods required by the Storage interface.
```python
class MyStorage(Storage):
def read(self, path, deadline: datetime.datetime) -> bytes:
"""Read the file at the given path and return its contents as bytes.
If the file does not exist, raise FileNotFoundError. If the file is
older than the given deadline, raise CacheExpired.
"""
...
def write(self, path, data: bytes) -> None:
"""Write the file at the given path."""
...
cache = Cache(storage=MyStorage())
```
--------------------------------
### Implement Basic Persistent Caching
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Use the Cache decorator to persist function results to the local filesystem using pickle serialization.
```python
from perscache import Cache
cache = Cache()
# Basic usage - cache results to local .cache directory using pickle serialization
@cache
def fetch_expensive_data(user_id: int) -> dict:
print(f"Fetching data for user {user_id}...")
# Simulate expensive operation
return {"user_id": user_id, "name": "John Doe", "balance": 1000}
# First call - function executes
result1 = fetch_expensive_data(42)
# Output: Fetching data for user 42...
# Second call - returns cached result without executing function
result2 = fetch_expensive_data(42)
# No output - cache hit
# Different arguments trigger new execution
result3 = fetch_expensive_data(99)
# Output: Fetching data for user 99...
```
--------------------------------
### Use YAML Serializer
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Configures the cache to use YAML serialization, which requires the yaml package.
```python
from perscache import Cache
from perscache.serializers import YAMLSerializer
cache = Cache(serializer=YAMLSerializer())
@cache
def get_schema(table_name: str) -> dict:
return {
"table": table_name,
"columns": ["id", "name", "created_at"],
"primary_key": "id"
}
# Result cached as .yaml file
schema = get_schema("users")
# File: .cache/get_schema-.yaml
```
--------------------------------
### Conditional Caching Based on Environment
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Shows how to dynamically configure caching based on environment variables. In debug mode, `NoCache` is used to disable caching; otherwise, it defaults to `GoogleCloudStorage` or `LocalFileStorage`.
```python
import os
from perscache import Cache, NoCache
from perscache.storage import LocalFileStorage
if os.environ.get["DEBUG"]:
cache = NoCache() # turn off caching in debug mode
else:
cache = (
GoogleCloudStorage("/bucket/folder")
if os.environ.get["GOOGLE_PROJECT_NAME"] # if running in the cloud
else LocalFileStorage()
)
@cache
def function():
...
```
--------------------------------
### Async Function Caching
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Demonstrates caching for asynchronous functions. The first call to `fetch_data` will execute the function body, while subsequent calls with the same arguments will retrieve the result from the cache.
```python
@cache
async def fetch_data(url: str):
print("Fetching data...")
response = await some_async_request(url)
return response
# First call fetches
data1 = await fetch_data("example.com")
# Second call uses cache
data2 = await fetch_data("example.com")
```
--------------------------------
### Mixed Serializer and Storage Configuration
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Configure default serializer and storage at the cache level, and override them on a per-function basis. This allows for flexible caching strategies.
```python
from perscache import Cache
from perscache.serializers import JSONSerializer, CloudPickleSerializer, ParquetSerializer
from perscache.storage import LocalFileStorage
# Default: CloudPickle serializer with local storage
cache = Cache(
serializer=CloudPickleSerializer(),
storage=LocalFileStorage(location=".cache", max_size=50 * 1024 * 1024)
)
# Use default settings
@cache
def complex_computation(data: list) -> object:
return {"result": sum(data), "type": "complex"}
# Override with JSON for human-readable output
@cache(serializer=JSONSerializer())
def get_config(name: str) -> dict:
return {"name": name, "enabled": True}
```
--------------------------------
### Local File Storage with Max Size
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Configure `LocalFileStorage` to save cache files to a specified directory with a maximum size limit. This enables automatic cleanup of least recently used entries when the cache exceeds the limit.
```python
from perscache import Cache
from perscache.storage import LocalFileStorage
# Cache with 100MB limit and automatic cleanup
storage = LocalFileStorage(
location=".my_cache", # Custom cache directory
max_size=100 * 1024 * 1024 # 100 MB limit
)
cache = Cache(storage=storage)
@cache
def download_file(url: str) -> bytes:
print(f"Downloading {url}...")
# Simulate download
return b"file contents" * 1000
# Files cached in .my_cache directory
# LRU cleanup happens automatically when cache exceeds 100MB
data = download_file("https://example.com/file.bin")
```
--------------------------------
### Create a custom serializer with make_serializer
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Use the factory function to define custom serialization and deserialization logic for specific data types.
```python
import pyrogram
from perscache.serializers import make_serializer
PyrogramSerializer = make_serializer(
"PyrogramSerializer",
"pyro",
dumps_fn = lambda data: str(data).encode("utf-8"),
loads_fn = lambda data: eval(data.decode("utf-8")),
)
cache = Cache(serializer=PyrogramSerializer())
@cache
async def some_pyrogram_func() -> pyrogram.Message:
...
```
--------------------------------
### Setting Cache Expiry Time
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Configures a cache with a time-to-live (TTL) of one day using `datetime.timedelta`. The cached data will be considered stale and recomputed after this period.
```python
import datetime as dt
@cache(ttl=dt.timedelta(days=1))
def get_data():
"""This function will be cached for 1 day
and called again after this period expires."""
...
```
--------------------------------
### Use JSON Serializer
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Configures the cache to use JSON serialization for human-readable cache files.
```python
from perscache import Cache
from perscache.serializers import JSONSerializer
cache = Cache(serializer=JSONSerializer())
@cache
def get_config(app_name: str) -> dict:
return {
"app_name": app_name,
"version": "1.0.0",
"settings": {"debug": False, "log_level": "INFO"}
}
# Result cached as .json file in .cache directory
config = get_config("myapp")
# File: .cache/get_config-.json
# Contents: {"app_name": "myapp", "version": "1.0.0", ...}
```
--------------------------------
### Create Custom Serializer
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
Use `make_serializer` to create a custom serializer class. Provide a class name, file extension, and functions for dumping and loading data. This allows integration with custom serialization logic.
```python
from perscache.serializers import make_serializer
from perscache import Cache
PyrogramSerializer = make_serializer(
class_name = 'PyrogramSerializer',
ext = 'pyrogram',
dumps_fn = lambda x: str(x).encode('utf-8'),
loads_fn = lambda x: eval(x.decode('utf-8')),
)
cache = Cache()
@cache(serializer=PyrogramSerializer())
def get_data():
...
```
--------------------------------
### Use Parquet and CSV Serializers for DataFrames
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Demonstrates caching pandas DataFrames using Parquet for performance or CSV for readability.
```python
import pandas as pd
from perscache import Cache
from perscache.serializers import ParquetSerializer, CSVSerializer
# Parquet serializer with compression (requires pyarrow)
cache_parquet = Cache(serializer=ParquetSerializer(compression="brotli"))
@cache_parquet
def load_large_dataset(source: str) -> pd.DataFrame:
print(f"Loading data from {source}...")
return pd.DataFrame({
"id": range(1000),
"value": [i * 2 for i in range(1000)]
})
# CSV serializer for human-readable cache (requires pandas)
cache_csv = Cache(serializer=CSVSerializer())
@cache_csv
def get_summary_stats(dataset_name: str) -> pd.DataFrame:
return pd.DataFrame({
"metric": ["mean", "median", "std"],
"value": [100.5, 98.0, 15.2]
})
df = load_large_dataset("database") # Cached as .parquet
stats = get_summary_stats("sales") # Cached as .csv
```
--------------------------------
### Cache with Shared Instance
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
Configure the Cache decorator with `per_instance=False` to share a cache across all instances of a class. This is useful for instance methods where you want a single cache for all objects.
```python
from perscache import Cache
class DataFetcher:
def __init__(self):
self.compute_count = 0
@cache(per_instance=False) # Share cache between instances
def fetch_data(self, key: str) -> str:
self.compute_count += 1
return f"Fetched data for key: {key}"
fetcher1 = DataFetcher()
fetcher2 = DataFetcher()
# First instance computes and caches
result1 = fetcher1.fetch_data("test_key") # compute_count = 1
# Second instance uses the same cache
result2 = fetcher2.fetch_data("test_key") # compute_count still 1
```
--------------------------------
### Override Cache Storage with LocalFileStorage
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Specify a custom storage location using LocalFileStorage for the cache.
```python
from perscache import cache
from perscache.storage import LocalFileStorage
@cache(storage=LocalFileStorage(location=".api_cache"))
def call_api(endpoint: str) -> dict:
return {"endpoint": endpoint, "data": "response"}
```
--------------------------------
### Google Cloud Storage Backend
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Use `GoogleCloudStorage` to store cache files in a GCS bucket. This requires the `gcsfs` package and proper authentication.
```python
from perscache import Cache
from perscache.storage import GoogleCloudStorage
# GCS storage with authentication
storage = GoogleCloudStorage(
location="my-bucket/cache",
max_size=1024 * 1024 * 1024, # 1 GB limit
storage_options={"token": "path/to/credentials.json"}
)
cache = Cache(storage=storage)
@cache
def process_cloud_data(dataset_id: str) -> dict:
print(f"Processing dataset {dataset_id}...")
return {"id": dataset_id, "status": "processed"}
# Results cached to gs://my-bucket/cache/
result = process_cloud_data("dataset_001")
```
--------------------------------
### Cache instance methods
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Configures caching behavior for class methods with instance-specific or shared storage.
```python
class Calculator:
def __init__(self):
self.compute_count = 0
@cache # Default per_instance=True
def add(self, a: int, b: int) -> int:
self.compute_count += 1
return a + b
@cache(per_instance=False) # Share cache between instances
def multiply(self, a: int, b: int) -> int:
self.compute_count += 1
return a * b
calc1 = Calculator()
calc2 = Calculator()
# First call computes the result
result1 = calc1.add(5, 3) # compute_count = 1
# Second call uses cache
result2 = calc1.add(5, 3) # compute_count still 1
# Different instance gets its own cache
result3 = calc2.add(5, 3) # calc2.compute_count = 1
# Shared cache between instances
result4 = calc1.multiply(4, 2) # compute_count = 2
# Second instance uses the same cache
result5 = calc2.multiply(4, 2) # compute_count still 2
```
--------------------------------
### Disable Caching with NoCache
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Uses NoCache as a drop-in replacement to disable caching based on environment variables.
```python
import os
from perscache import Cache, NoCache
# Toggle caching based on environment
if os.environ.get("DEBUG"):
cache = NoCache() # Disable caching in debug mode
else:
cache = Cache()
@cache
def expensive_calculation(x: int) -> int:
print(f"Computing {x}...")
return x ** 2
# With NoCache: function always executes
# With Cache: function result is cached after first call
result = expensive_calculation(5)
```
--------------------------------
### perscache.serializers.make_serializer Function
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
Creates a custom serializer class derived from perscache.serializers.Serializer.
```APIDOC
### function `perscache.serializers.make_serializer()`
#### Description
This function is used to create a serializer class.
#### Arguments
- **class_name** (str) - The name of the serializer class.
- **ext** (str) - The extension of the serialized file.
- **dumps_fn** (Callable) - The function used to serialize an object into bytes. Accepts a single argument, the object to serialize, and returns a bytes object.
- **loads_fn** (Callable) - The function used to deserialize bytes into an object. Accepts a single argument, the bytes to deserialize, and returns an object.
#### Returns
A serializer class derived from `perscache.serializers.Serializer` that can be used with `perscache.Cache`.
#### Example
```python
from perscache.serializers import make_serializer
from perscache import Cache
PyrogramSerializer = make_serializer(
class_name = 'PyrogramSerializer',
ext = 'pyrogram',
dumps_fn = lambda x: str(x).encode('utf-8'),
loads_fn = lambda x: eval(x.decode('utf-8')),
)
cache = Cache()
@cache(serializer=PyrogramSerializer())
def get_data():
...
```
```
--------------------------------
### Ignoring Function Arguments for Cache
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Demonstrates how to ignore specific arguments when caching. The cache will not be invalidated even if the value of the `ignore_this` argument changes.
```python
@cache(ignore="ignore_this")
def get_data(key, ignore_this):
print("The function has been called...")
return key
print(get_data("abc", "ignore_1")) # the function has been called
# The function has been called...
# abc
# using the cache although the the second argument is different
print(get_data("abc", "ignore_2"))
# abc
```
--------------------------------
### LocalFileStorage
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
Stores cache entries in separate files within a specified file system directory. This is the default storage class for Cache.
```APIDOC
## LocalFileStorage
### Description
Keeps cache entries in separate files in a file system directory.
This is the default storage class used by `Cache`.
### Parameters
#### Path Parameters
- **location** (str) - Required - A directory to store the cache files. Defaults to `".cache"`.
- **max_size** (int) - Optional - The maximum size for the cache. If set, then, before a new cache entry is written, the future size of the directory is calculated and the least recently used cache entries are removed. If `None`, the cache grows indefinitely. Defaults to `None`.
```
--------------------------------
### Serializer Classes
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
Available serializer classes for perscache.
```APIDOC
## Serializers
Serializers are imported from the `perscache.serializers` module.
### class `perscache.serializers.Serializer`
#### Description
The abstract base serializer class.
See also [how to make your own serializer](/README.md#make-your-own-serialization-and-storage-backends).
### class `perscache.serializers.CloudPickleSerializer`
#### Description
Uses the `cloudpickle` module. It's the most capable serializer of all, able to process most of the data types.
It's the default serializer for the `Cache` class.
### class `perscache.serializers.JSONSerializer`
#### Description
Uses the `json` module.
### class `perscache.serializers.YAMLSerializer`
#### Description
Uses the `yaml` module.
### class `perscache.serializers.PickleSerializer`
#### Description
Uses the `pickle` module.
```
--------------------------------
### Configure Cache TTL
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Set an expiration time for cached results using the ttl parameter with a timedelta object.
```python
import datetime as dt
from perscache import Cache
cache = Cache()
@cache(ttl=dt.timedelta(hours=1))
def get_exchange_rate(currency: str) -> float:
"""Fetch exchange rate - cached for 1 hour."""
print(f"Fetching live rate for {currency}...")
# Simulate API call
return 1.12 if currency == "EUR" else 0.85
# First call fetches fresh data
rate = get_exchange_rate("EUR")
# Output: Fetching live rate for EUR...
# Within 1 hour - uses cached value
rate = get_exchange_rate("EUR")
# No output - cache hit
# After TTL expires, function executes again automatically
```
--------------------------------
### Basic Cache Usage
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
Use the Cache decorator to cache function results. The cache is invalidated if the function code, arguments, or serializer change.
```python
from perscache import Cache
cache = Cache()
@cache
def get_data():
...
```
--------------------------------
### Logging Cache Operations
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
Add a StreamHandler to the 'perscache' logger to view log messages related to cache operations.
```python
import logging
logging.getLogger('perscache').addHandler(logging.StreamHandler())
```
--------------------------------
### Exclude Arguments from Cache Key
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Use the ignore parameter to prevent specific arguments from affecting the cache key, useful for session-specific or non-functional data.
```python
from perscache import Cache
cache = Cache()
@cache(ignore=["request_id", "timestamp"])
def fetch_user_profile(user_id: int, request_id: str, timestamp: float) -> dict:
print(f"Fetching profile for user {user_id}...")
return {"user_id": user_id, "name": "Alice", "email": "alice@example.com"}
# First call - executes function
profile1 = fetch_user_profile(1, "req-abc", 1699900000.0)
# Output: Fetching profile for user 1...
# Different request_id and timestamp - still uses cache because they're ignored
profile2 = fetch_user_profile(1, "req-xyz", 1699900999.0)
# No output - cache hit (request_id and timestamp are ignored)
# Different user_id - cache miss
profile3 = fetch_user_profile(2, "req-abc", 1699900000.0)
# Output: Fetching profile for user 2...
```
--------------------------------
### Cache Invalidation by Function Changes
Source: https://github.com/leshchenko1979/perscache/blob/master/README.md
Shows how changing the code of a decorated function invalidates the cache. The cache is recomputed when the function's implementation is modified.
```python
@cache
def get_data(key):
print("The function has been called...")
return key
print(get_data("abc")) # the function has been called
# The function has been called...
# abc
print(get_data("fgh")) # the function has been called again
# The function has been called...
# fgh
print(get_data("abc")) # using the cache
# abc
@cache
def get_data(key):
print("This function has been changed...")
return key
print(get_data("abc")) # the function has been called again
# This function has been changed...
# abc
```
--------------------------------
### perscache.NoCache Class
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
A class that disables caching. Useful for alternating cache behavior based on environment.
```APIDOC
## class `perscache.NoCache()`
### Description
This class has no parameters. It is useful to [alternate cache behaviour depending on the environment](../README.md#alternating-cache-settings-depending-on-the-environment).
### decorator `perscache.NoCache().__call__()`
#### Description
The underlying function will be called every time the decorated function has been called and no caching will take place.
This decorator will ignore any parameters it has been given.
```
--------------------------------
### NoCache Decorator
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
Use the `NoCache` decorator to ensure a function is always called without any caching. This decorator ignores any parameters passed to it.
```python
from perscache import NoCache
@NoCache()
def always_compute_data():
...
```
--------------------------------
### Cache Asynchronous Functions
Source: https://context7.com/leshchenko1979/perscache/llms.txt
Apply the cache decorator to async functions to maintain persistent caching for coroutines.
```python
import asyncio
from perscache import Cache
cache = Cache()
@cache
async def fetch_data_async(endpoint: str) -> dict:
print(f"Fetching from {endpoint}...")
await asyncio.sleep(0.1) # Simulate network delay
return {"endpoint": endpoint, "data": "response"}
async def main():
# First call - executes async function
result1 = await fetch_data_async("/api/users")
# Output: Fetching from /api/users...
# Second call - returns cached result
result2 = await fetch_data_async("/api/users")
# No output - cache hit
asyncio.run(main())
```
--------------------------------
### perscache.Cache Class
Source: https://github.com/leshchenko1979/perscache/blob/master/docs/api_reference.md
The main Cache class for managing cached data. It can be used as a decorator to cache function results.
```APIDOC
## class `perscache.Cache()`
### Description
Initializes a Cache object with optional serializer and storage back-ends.
### Parameters
- **serializer** (perscache.serializers.Serializer) - Optional - A serializer class to use for converting stored data. Defaults to `perscache.serlializers.PickleSerializer`.
- **storage** (perscache.storage.Storage) - Optional - A storage back-end used to save and load data. Defaults to `perscache.storage.LocalFileStorage`.
### decorator `perscache.Cache().__call__()`
#### Description
Tries to find a cached result of the decorated function in persistent storage. Returns the saved result if it was found, or calls the decorated function and caches its result.
#### Arguments
- **ignore** (str | Iterable[str]) - Optional - Arguments of the decorated function that will not be used in making the cache key. Defaults to `None`.
- **serializer** (perscache.serializers.Serializer) - Optional - Overrides the default `Cache()` serializer. Defaults to `None`.
- **storage** (perscache.storage.Storage) - Optional - Overrides the default `Cache()` storage. Defaults to `None`.
- **ttl** (datetime.timedelta) - Optional - The time-to-live of the cache for the decorated function. If `None`, the cache never expires. Defaults to `None`.
- **per_instance** (bool) - Optional - Whether to create a separate cache for each instance of a class. Defaults to `True`.
#### Usage Example
```python
from perscache import Cache
cache = Cache()
@cache
def get_data():
...
```
#### Example with shared cache
```python
class DataFetcher:
def __init__(self):
self.compute_count = 0
@cache(per_instance=False) # Share cache between instances
def fetch_data(self, key: str) -> str:
self.compute_count += 1
return f"Fetched data for key: {key}"
fetcher1 = DataFetcher()
fetcher2 = DataFetcher()
# First instance computes and caches
result1 = fetcher1.fetch_data("test_key") # compute_count = 1
# Second instance uses the same cache
result2 = fetcher2.fetch_data("test_key") # compute_count still 1
```
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.