### Handling PluginNotFound Exception Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/errors.md This exception is raised when a specified backend name does not exist or cannot be loaded. The example shows how to trigger this error and provides examples of valid backend configurations. ```python # This raises PluginNotFound region = make_region().configure('dogpile.cache.nonexistent') ``` ```python # Valid backends region = make_region().configure('dogpile.cache.memory') region = make_region().configure('dogpile.cache.redis') region = make_region().configure('dogpile.cache.dbm', arguments={'filename': '/tmp/cache.dbm'}) ``` -------------------------------- ### Implementing a Logging Proxy Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/backends.md Example of creating a custom ProxyBackend to add logging functionality to an existing cache backend. This demonstrates how to intercept and modify backend operations. ```python from dogpile.cache.proxy import ProxyBackend class LoggingProxy(ProxyBackend): def get(self, key): print(f"Getting {key}") return self.proxied.get(key) def set(self, key, value): print(f"Setting {key}") self.proxied.set(key, value) def delete(self, key): print(f"Deleting {key}") self.proxied.delete(key) ``` -------------------------------- ### Rudimentary Lock Usage Example Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/docs/build/core_usage.rst Demonstrates the basic usage of the dogpile.Lock object as a context manager for mutexing, value creation, and value retrieval. This example shows how to define creation and retrieval functions and use the Lock to manage access to a shared resource. ```python from dogpile import Lock, NeedRegenerationException import threading import time # store a reference to a "resource", some # object that is expensive to create. the_resource = [None] def some_creation_function(): # call a value creation function value = create_some_resource() # get creationtime using time.time() creationtime = time.time() # keep track of the value and creation time in the "cache" the_resource[0] = tup = (value, creationtime) # return the tuple of (value, creationtime) return tup def retrieve_resource(): # function that retrieves the resource and # creation time. # if no resource, then raise NeedRegenerationException if the_resource[0] is None: raise NeedRegenerationException() # else return the tuple of (value, creationtime) return the_resource[0] # a mutex, which needs here to be shared across all invocations # of this particular creation function mutex = threading.Lock() with Lock(mutex, some_creation_function, retrieve_resource, 3600) as value: # some function that uses # the resource. Won't reach # here until some_creation_function() # has completed at least once. value.do_something() ``` -------------------------------- ### Creating a Custom Cache Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/backends.md Demonstrates how to create a custom cache backend by subclassing CacheBackend and implementing core methods like get, set, and delete. This is useful for integrating with custom storage solutions. ```python from dogpile.cache.api import CacheBackend, NO_VALUE class MyBackend(CacheBackend): def __init__(self, arguments): # Parse arguments dict self.host = arguments.get('host', 'localhost') self.port = arguments.get('port', 9999) def get(self, key): # Retrieve from storage # Return value or NO_VALUE pass def set(self, key, value): # Store the value pass def delete(self, key): # Delete the key (must be idempotent) pass def get_multi(self, keys): # Return list of values return [self.get(k) for k in keys] def set_multi(self, mapping): # Store multiple values for k, v in mapping.items(): self.set(k, v) def delete_multi(self, keys): # Delete multiple keys for k in keys: self.delete(k) def get_mutex(self, key): # Optional: return a mutex for distributed locking return None ``` -------------------------------- ### Manual Lock Usage Example Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/lock.md Demonstrates manual usage of the Lock class as a context manager to coordinate value creation and retrieval. ```python from dogpile import Lock, NeedRegenerationException import time import threading # Example with manual lock usage def create_value(): print("Creating value...") return ("expensive result", time.time()) def get_cached_value(): # This would normally fetch from cache # If not found or expired, raise NeedRegenerationException raise NeedRegenerationException() mutex = threading.Lock() lock = Lock(mutex, create_value, get_cached_value, expiretime=3600) # Use as context manager with lock as value: print(f"Got value: {value}") ``` -------------------------------- ### Configure and Use a Custom Cache Region Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/docs/build/usage.rst Create a cache region and configure it to use a custom backend. This example uses the 'dictionary' backend registered previously. ```python from dogpile.cache import make_region region = make_region("myregion") region.configure("dictionary") data = region.set("somekey", "somevalue") ``` -------------------------------- ### Direct Cache Operations Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/README.md Provides examples of performing basic cache operations directly on a configured region. This includes setting, getting, deleting single keys, and performing these operations on multiple keys simultaneously. ```python region.set('key', value) value = region.get('key') region.delete('key') region.set_multi({'k1': v1, 'k2': v2}) values = region.get_multi(['k1', 'k2']) region.invalidate() # Invalidate all ``` -------------------------------- ### Implement a Logging Proxy for Cache Operations Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/docs/build/usage.rst Create a ProxyBackend subclass to log cache operations. This example specifically logs calls to the .set() method. ```python from dogpile.cache.proxy import ProxyBackend import logging log = logging.getLogger(__name__) class LoggingProxy(ProxyBackend): def set(self, key, value): log.debug('Setting Cache Key: %s' % key) self.proxied.set(key, value) ``` -------------------------------- ### Configure and Use CacheRegion with Redis Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/README.md Demonstrates how to create a CacheRegion, configure it to use the Redis backend, and perform basic set and get operations. It also shows how to use the cache_on_arguments decorator for caching function results. ```python from dogpile.cache import make_region region = make_region().configure( 'dogpile.cache.redis', expiration_time=3600, arguments={'host': 'localhost', 'port': 6379} ) # Use it region.set('key', 'value') value = region.get('key') # Or as a decorator @region.cache_on_arguments() def expensive_operation(x): return x ** 2 result = expensive_operation(5) ``` -------------------------------- ### Dogpile.cache Debug Log Output Examples Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/docs/build/usage.rst Illustrates typical debug log messages from dogpile.cache, showing key regeneration, cache misses, generation times, and hard invalidations. ```text DEBUG:dogpile.cache.region:No value present for key: '__main__:load_user_info|2' DEBUG:dogpile.cache.region:No value present for key: '__main__:load_user_info|1' DEBUG:dogpile.cache.region:Cache value generated in 0.501 seconds for keys: ['__main__:load_user_info|2', '__main__:load_user_info|3', '__main__:load_user_info|4', '__main__:load_user_info|5'] DEBUG:dogpile.cache.region:Hard invalidation detected for key: '__main__:load_user_info|3' DEBUG:dogpile.cache.region:Hard invalidation detected for key: '__main__:load_user_info|2' ``` -------------------------------- ### configure() Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Configures the cache region with a specified backend, expiration time, and optional arguments. This method allows for detailed setup of the caching backend and its behavior. ```APIDOC ## configure() ### Description Configure the cache region with a backend and expiration settings. ### Method `configure( self, backend: str, expiration_time: float | datetime.timedelta | None = None, arguments: BackendArguments | None = None, _config_argument_dict: Mapping[str, Any] | None = None, _config_prefix: str | None = None, wrap: Sequence[ProxyBackend | Type[ProxyBackend]] = (), replace_existing_backend: bool = False, region_invalidator: RegionInvalidationStrategy | None = None, ) -> CacheRegion ### Parameters #### Parameters - **backend** (str) - Required - Name of the backend to use (e.g., 'dogpile.cache.memory', 'dogpile.cache.redis'). - **expiration_time** (float | datetime.timedelta | None) - Optional - Time in seconds before cached values expire. Can be a float, timedelta, or None for no expiration. - **arguments** (BackendArguments | None) - Optional - Dictionary of backend-specific configuration arguments. - **wrap** (Sequence[ProxyBackend | Type[ProxyBackend]]) - Optional - List of proxy backends to wrap the main backend in a chain. - **replace_existing_backend** (bool) - Optional - Default: False - If True, replaces an existing backend configuration; otherwise raises RegionAlreadyConfigured. - **region_invalidator** (RegionInvalidationStrategy | None) - Optional - Custom invalidation strategy instance. ### Returns The configured `CacheRegion` instance (self), allowing method chaining. ### Raises - `RegionAlreadyConfigured` - If the region is already configured and replace_existing_backend is False. - `PluginNotFound` - If the specified backend cannot be loaded. - `ValidationError` - If expiration_time is not a number or timedelta. ### Usage Example ```python from dogpile.cache import make_region import datetime # Configure with simple arguments region = make_region().configure( 'dogpile.cache.memory' ) # Configure with expiration time region = make_region().configure( 'dogpile.cache.memory', expiration_time=3600 ) # Configure with timedelta region = make_region().configure( 'dogpile.cache.memory', expiration_time=datetime.timedelta(hours=1) ) # Configure with backend-specific arguments region = make_region().configure( 'dogpile.cache.redis', expiration_time=3600, arguments={ 'host': 'localhost', 'port': 6379, 'db': 0, 'redis_expiration_time': 7200 } ) ``` ``` -------------------------------- ### Configure Redis Sentinel Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/backends.md Configure the Redis Sentinel backend for high-availability Redis setups. Requires specifying sentinel connection details and the service name. ```python region = make_region().configure( 'dogpile.cache.redis_sentinel', expiration_time=3600, arguments={ 'sentinel_kwargs': { 'sentinels': [('sentinel1', 26379), ('sentinel2', 26379)], 'service_name': 'mymaster' } } ) ``` -------------------------------- ### Get or Create a Cached Value Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/README.md Shows how to use the get_or_create method to retrieve a value from the cache or, if it's not present, generate it using a provided creator function and then store it in the cache. ```python def creator(): return expensive_computation() value = region.get_or_create('key', creator) ``` -------------------------------- ### Msgpack Encoding ProxyBackend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/docs/build/recipes.rst Implement a custom ProxyBackend to encode and decode data using msgpack for smaller payloads. This example defines a base class and a Msgpack-specific implementation. ```python from dogpile.cache.proxy import ProxyBackend import msgpack class _EncodedProxy(ProxyBackend): """base class for building value-mangling proxies""" def value_decode(self, value): raise NotImplementedError("override me") def value_encode(self, value): raise NotImplementedError("override me") def set(self, k, v): v = self.value_encode(v) self.proxied.set(k, v) def get(self, key): v = self.proxied.get(key) return self.value_decode(v) def set_multi(self, mapping): """encode to a new dict to preserve unencoded values in-place when called by `get_or_create_multi` """ mapping_set = {} for (k, v) in mapping.iteritems(): mapping_set[k] = self.value_encode(v) return self.proxied.set_multi(mapping_set) def get_multi(self, keys): results = self.proxied.get_multi(keys) translated = [] for record in results: try: translated.append(self.value_decode(record)) except Exception as e: raise return translated class MsgpackProxy(_EncodedProxy): """custom decode/encode for value mangling""" def value_decode(self, v): if not v or v is NO_VALUE: return NO_VALUE # you probably want to specify a custom decoder via `object_hook` v = msgpack.unpackb(payload, encoding="utf-8") return CachedValue(*v) def value_encode(self, v): # you probably want to specify a custom encoder via `default` v = msgpack.packb(payload, use_bin_type=True) return v # extend our region configuration from above with a 'wrap' region = make_region().configure( 'dogpile.cache.pylibmc', expiration_time = 3600, arguments = { 'url': ["127.0.0.1"], }, wrap = [MsgpackProxy, ] ) ``` -------------------------------- ### Wrap Cache Backend with Proxy Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md The `wrap` method allows adding proxy backends to intercept and modify cache operations. `LoggingProxy` is an example that logs GET and SET operations. ```python from dogpile.cache.proxy import ProxyBackend region = make_region().configure('dogpile.cache.memory', expiration_time=3600) class LoggingProxy(ProxyBackend): def get(self, key): print(f"Cache GET: {key}") return self.proxied.get(key) def set(self, key, value): print(f"Cache SET: {key}") self.proxied.set(key, value) region.wrap(LoggingProxy) # Now all cache operations are logged ``` -------------------------------- ### Using the Cache Decorator Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/README.md Demonstrates how to apply the cache_on_arguments decorator to a function to automatically cache its results based on arguments. Includes examples for invalidating, refreshing, and getting cached values. ```python @region.cache_on_arguments() def my_function(arg1, arg2): return result # Invalidate my_function.invalidate(arg1, arg2) # Refresh my_function.refresh(arg1, arg2) # Get cached value my_function.get(arg1, arg2) ``` -------------------------------- ### Configure Memory Backend with Method Chaining Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/configuration.md Demonstrates configuring the memory backend using method chaining for a more fluent API. This can improve readability for complex configurations. ```python # Method chaining region = ( make_region() .configure('dogpile.cache.memory', expiration_time=3600) ) ``` -------------------------------- ### Define a Custom Dictionary Cache Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/docs/build/usage.rst Subclass CacheBackend to create a custom cache backend. Implement get, set, and delete methods. This example uses a simple Python dictionary. ```python from dogpile.cache.api import CacheBackend, NO_VALUE class DictionaryBackend(CacheBackend): def __init__(self, arguments): self.cache = {} def get(self, key): return self.cache.get(key, NO_VALUE) def set(self, key, value): self.cache[key] = value def delete(self, key): self.cache.pop(key) ``` -------------------------------- ### Configure Valkey Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/backends.md Configure the Valkey backend, a drop-in replacement for Redis using the 'valkey' library. Specify host, port, and database. ```python region = make_region().configure( 'dogpile.cache.valkey', expiration_time=3600, arguments={ 'host': 'localhost', 'port': 6379, 'db': 0 } ) ``` -------------------------------- ### Configure Cache Region with Proxy Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Demonstrates how to configure a cache region using a memory backend and wrap it with a custom proxy backend for logging. ```python from dogpile.cache.proxy import ProxyBackend class LoggingProxy(ProxyBackend): def get(self, key): print(f"Getting {key}") return self.proxied.get(key) region = make_region().configure( 'dogpile.cache.memory', expiration_time=3600, wrap=[LoggingProxy] ) ``` -------------------------------- ### PluginLoader Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/util.md Loads plugins from setuptools entry points, enabling the discovery and loading of external components or backends for the cache system. ```APIDOC ## PluginLoader ### Description Load plugins from setuptools entry points. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **group_name** (str) - Required - The entry point group name to load plugins from. ### Returns A PluginLoader instance. ### Usage Example ```python from dogpile.cache.util import PluginLoader loader = PluginLoader("dogpile.cache") # Load a backend class by name backend_cls = loader.load("dogpile.cache.memory") ``` ``` -------------------------------- ### Basic CacheRegion Operations Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-index.md Performs basic get, set, and delete operations on a cache region. ```python get() set() delete() ``` -------------------------------- ### Registering and Using Custom Backends Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/errors.md Demonstrates how to register a custom backend plugin with dogpile.cache and then use it to configure a region. This is useful when the PluginNotFound exception is encountered due to a non-standard backend. ```python from dogpile.cache import register_backend register_backend( 'dogpile.cache.mybackend', 'mymodule', 'MyBackend' ) # Now it can be used region = make_region().configure('dogpile.cache.mybackend') ``` -------------------------------- ### Applying Thread-based Caching Decorator Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/docs/build/core_usage.rst Example of how to apply the `@cached` decorator to a function to enable memcached caching. ```Python @cached("some key", 3600) def generate_my_expensive_value(): return slow_database.lookup("stuff") ``` -------------------------------- ### Registering and Using a Custom Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/backends.md Shows how to register a custom backend with dogpile.cache and then configure a cache region to use it. This involves using register_backend and make_region. ```python from dogpile.cache import register_backend, make_region register_backend( "dogpile.cache.mybackend", "__main__", "MyBackend" ) region = make_region().configure( 'dogpile.cache.mybackend', arguments={'host': 'myhost', 'port': 9999} ) ``` -------------------------------- ### Get or Create Operations for CacheRegion Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-index.md Retrieves values from the cache or creates them if they do not exist, for single or multiple keys. ```python get_or_create() get_or_create_multi() ``` -------------------------------- ### Multi-value CacheRegion Operations Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-index.md Performs operations to get, set, or delete multiple values from the cache simultaneously. ```python get_multi() set_multi() delete_multi() ``` -------------------------------- ### Stacking Multiple Proxy Backends Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/backends.md Illustrates how to stack multiple proxy backends to add layered functionality to a cache region. Proxies are applied in a chain, with each proxy wrapping the previous one. ```python region = make_region().configure( 'dogpile.cache.memory', expiration_time=3600, wrap=[LoggingProxy, MetricsProxy, ValidationProxy] ) ``` -------------------------------- ### Get Cached Value Age Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/types.md Calculates the age of a cached value in seconds. Useful for determining cache staleness. ```python cached_value = region.get_value_metadata('key') if cached_value: print(f"Value is {cached_value.age} seconds old") ``` -------------------------------- ### Plugin Loader Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/util.md Loads plugins from setuptools entry points. This is used to dynamically discover and load components like cache backends. ```python from dogpile.cache.util import PluginLoader loader = PluginLoader("dogpile.cache") # Load a backend class by name backend_cls = loader.load("dogpile.cache.memory") ``` -------------------------------- ### CacheReturnType Alias Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/types.md The non-serialized form returned by backend 'get' methods, which can be either a `CachedValue` object or the `NO_VALUE` token. ```python CacheReturnType = CachedValue | NoValueType ``` -------------------------------- ### Import Valkey backends from dogpile.cache.backends.valkey Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-index.md Imports Valkey cache backend implementations. ```python from dogpile.cache.backends.valkey import ( ValkeyBackend, ValkeySentinelBackend, ValkeyClusterBackend, ) ``` -------------------------------- ### Batch Operations with get_multi, set_multi, and get_or_create_multi Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/README.md Illustrates how to perform efficient batch operations for retrieving multiple keys, setting multiple key-value pairs, and retrieving or creating multiple items using a provided fetch function. ```python from dogpile.cache import make_region region = make_region().configure('dogpile.cache.redis') # Batch get user_ids = [1, 2, 3, 4, 5] users = region.get_multi(user_ids) # Batch set region.set_multi({ 1: {'id': 1, 'name': 'Alice'}, 2: {'id': 2, 'name': 'Bob'} }) # Batch get_or_create def fetch_users(*user_ids): # Return list of users in same order as user_ids return [db.get_user(uid) for uid in user_ids] users = region.get_or_create_multi([1, 2, 3], fetch_users) ``` -------------------------------- ### get() Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Retrieves a value from the cache using its key. It supports overriding expiration times and ignoring expiration for specific operations. ```APIDOC ## get() ### Description Retrieve a value from the cache by key. ### Method GET (conceptual) ### Parameters #### Path Parameters - **key** (KeyType) - Required - The cache key to retrieve. Can be any type accepted by the backend. - **expiration_time** (float | None) - Optional - Override the region's configured expiration time for this operation only. Defaults to None. - **ignore_expiration** (bool) - Optional - If True, return cached value regardless of expiration or invalidation. Defaults to False. ### Returns The cached value, or the `NO_VALUE` token if the key is not in the cache or the value has expired. ### Usage Example ```python region = make_region().configure('dogpile.cache.memory') # Simple get value = region.get('mykey') if value is not NO_VALUE: print(f"Found: {value}") # Get with custom expiration time for this operation value = region.get('mykey', expiration_time=1800) # Get ignoring expiration value = region.get('mykey', ignore_expiration=True) ``` ``` -------------------------------- ### Get Cached Value Creation Time Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/types.md Retrieves the epoch timestamp when a value was cached. Useful for calculating cache age. ```python cached_value = region.get_value_metadata('key') if cached_value: print(f"Cached at: {cached_value.cached_time}") ``` -------------------------------- ### Configure Memory Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/configuration.md Basic configuration for the memory backend. Use this for simple in-memory caching. ```python from dogpile.cache import make_region import datetime # Memory backend region = make_region().configure('dogpile.cache.memory') ``` -------------------------------- ### Get Cache Value with Metadata Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Retrieve a `CachedValue` object containing the payload and metadata (like `cached_time` and `age`) using `get_value_metadata`. ```python region = make_region().configure('dogpile.cache.memory', expiration_time=3600) region.set('mykey', 'myvalue') cached = region.get_value_metadata('mykey') if cached: print(f"Value: {cached.payload}") print(f"Cached at: {cached.cached_time}") print(f"Age: {cached.age} seconds") ``` -------------------------------- ### Configure Region with Async Creation Runner Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/configuration.md Illustrates configuring a cache region to use an asynchronous runner for cache creation. ```python import threading from dogpile.cache import make_region def async_runner(cache_region, key, creator, mutex): def run(): try: value = creator() cache_region.set(key, value) finally: mutex.release() threading.Thread(target=run).start() region = make_region( async_creation_runner=async_runner ).configure('dogpile.cache.memory', expiration_time=3600) ``` -------------------------------- ### Single-Machine Caching with Memory Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/README.md Illustrates setting up a simple in-memory cache for single-machine applications using the 'dogpile.cache.memory' backend and caching function results with a decorator. ```python from dogpile.cache import make_region region = make_region().configure( 'dogpile.cache.memory', expiration_time=3600 ) @region.cache_on_arguments() def get_user(user_id): return db.query(f"SELECT * FROM users WHERE id={user_id}") ``` -------------------------------- ### CacheBackend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/types.md Abstract base class for all cache backends. It defines the core interface for cache operations like get, set, and delete. ```APIDOC ## Class CacheBackend ### Description Abstract base class for all cache backends. It defines the core interface for cache operations like get, set, and delete. ### Attributes - **key_mangler** (Callable[[KeyType], KeyType] | None) - Optional - A function to mangle keys. - **serializer** (Serializer | None) - Optional - The serializer to use. - **deserializer** (Deserializer | None) - Optional - The deserializer to use. ### Methods #### __init__(arguments: BackendArguments) Initializes the cache backend with provided arguments. #### get(key: KeyType) -> BackendFormatted Retrieves a value from the cache for the given key. #### set(key: KeyType, value: BackendSetType) -> None Stores a value in the cache for the given key. #### delete(key: KeyType) -> None Removes a value from the cache for the given key. #### get_multi(keys: Iterable[KeyType]) -> Sequence[BackendFormatted] Retrieves multiple values from the cache for the given keys. #### set_multi(mapping: Mapping[KeyType, BackendSetType]) -> None Stores multiple values in the cache. #### delete_multi(keys: Iterable[KeyType]) -> None Removes multiple values from the cache. #### get_mutex(key: KeyType) -> CacheMutex | None Returns a mutex object for the given key. ``` -------------------------------- ### Get Value from Cache Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Retrieves a value from the cache using a specified key. Supports overriding expiration time and ignoring expiration for the operation. ```python region = make_region().configure('dogpile.cache.memory') # Simple get value = region.get('mykey') if value is not NO_VALUE: print(f"Found: {value}") # Get with custom expiration time for this operation value = region.get('mykey', expiration_time=1800) # Get ignoring expiration value = region.get('mykey', ignore_expiration=True) ``` -------------------------------- ### Configure Cache Region from Dictionary Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Use `configure_from_config` to set up a cache region using a dictionary of configuration settings and a prefix. ```python config = { 'cache.local.backend': 'dogpile.cache.memory', 'cache.local.expiration_time': '3600', 'cache.redis.backend': 'dogpile.cache.redis', 'cache.redis.expiration_time': '7200', 'cache.redis.arguments.host': 'localhost', 'cache.redis.arguments.port': '6379', 'cache.redis.arguments.db': '0', } local_region = make_region() local_region.configure_from_config(config, 'cache.local.') redis_region = make_region() redis_region.configure_from_config(config, 'cache.redis.') ``` -------------------------------- ### cache_on_arguments Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Decorator to cache results of a function based on its arguments. It adds methods like `invalidate`, `set`, `refresh`, `get`, and `original` to the decorated function. ```APIDOC ## cache_on_arguments() ### Description Decorator to cache results of a function based on its arguments. It adds methods like `invalidate`, `set`, `refresh`, `get`, and `original` to the decorated function. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters for Decorator - **namespace** (str | None) - Optional - Optional string to disambiguate functions with the same name. - **expiration_time** (float | Callable[[], float] | None) - Optional - Expiration time or callable that returns expiration time dynamically. - **should_cache_fn** (Callable[[ValuePayload], bool] | None) - Optional - Predicate to decide if the result should be cached. - **to_str** (Callable[[Any], str]) - Not Optional - Function to convert arguments to cache key components. - **function_key_generator** (FunctionKeyGenerator | None) - Optional - Custom key generator function. ### Decorated Function Methods - `invalidate(*args, **kwargs)` - Delete the cached value for the given arguments. - `set(value, *args, **kwargs)` - Store a value without calling the function. - `refresh(*args, **kwargs)` - Regenerate the value and return it immediately. - `get(*args, **kwargs)` - Get the cached value without regenerating. - `original(*args, **kwargs)` - Call the original function without caching. ### Returns A decorated function that caches results. ### Usage Example ```python from dogpile.cache import make_region region = make_region().configure('dogpile.cache.memory', expiration_time=3600) @region.cache_on_arguments() def add(x, y): print(f"Computing {x} + {y}") return x + y # First call generates the value result = add(5, 3) # Prints "Computing 5 + 3", returns 8 # Second call returns cached value result = add(5, 3) # Returns 8 (no print) # Invalidate cached value add.invalidate(5, 3) # Set a value directly add.set(100, 5, 3) print(add(5, 3)) # Returns 100 # Refresh the value add.refresh(5, 3) # Calls the function and caches result # Get without regenerating value = add.get(5, 3) # Call original function without cache result = add.original(5, 3) # With namespace to disambiguate @region.cache_on_arguments(namespace='v1') def process_data(data): return data.upper() # With should_cache_fn def cache_if_not_none(value): return value is not None @region.cache_on_arguments(should_cache_fn=cache_if_not_none) def query_user(user_id): return None if user_id < 0 else {'id': user_id, 'name': 'Alice'} # With dynamic expiration time @region.cache_on_arguments(expiration_time=lambda: 3600 if is_peak_hours() else 7200) def get_data(): return fetch_from_api() ``` ``` -------------------------------- ### Custom Invalidation Strategy Implementation Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/types.md Example of a custom invalidation strategy that tracks soft and hard invalidations using timestamps. This strategy can be configured with a cache region. ```python from dogpile.cache.region import RegionInvalidationStrategy import time class CustomInvalidationStrategy(RegionInvalidationStrategy): def __init__(self): self._soft_invalidated = None self._hard_invalidated = None def invalidate(self, hard: bool = True) -> None: if hard: self._hard_invalidated = time.time() self._soft_invalidated = None else: self._soft_invalidated = time.time() self._hard_invalidated = None def is_invalidated(self, timestamp: float) -> bool: return ( (self._soft_invalidated and timestamp < self._soft_invalidated) or (self._hard_invalidated and timestamp < self._hard_invalidated) ) def is_hard_invalidated(self, timestamp: float) -> bool: return ( self._hard_invalidated and timestamp < self._hard_invalidated ) def is_soft_invalidated(self, timestamp: float) -> bool: return ( self._soft_invalidated and timestamp < self._soft_invalidated ) def was_hard_invalidated(self) -> bool: return self._hard_invalidated is not None def was_soft_invalidated(self) -> bool: return self._soft_invalidated is not None region = make_region() region.configure( 'dogpile.cache.memory', region_invalidator=CustomInvalidationStrategy() ) ``` -------------------------------- ### Import utility functions from dogpile.cache.util Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-index.md Imports utility functions for key generation, mangling, and configuration coercion. ```python from dogpile.cache.util import ( function_key_generator, kwarg_function_key_generator, function_multi_key_generator, sha1_mangle_key, length_conditional_mangler, repr_obj, coerce_string_conf, memoized_property, NameRegistry, PluginLoader, KeyReentrantMutex, to_list, ) ``` -------------------------------- ### Handling RegionNotConfigured Exception Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/errors.md This exception occurs when trying to use a cache region before it has been configured. The example shows the trigger condition and the solution by calling configure() first. ```python region = make_region() # This raises RegionNotConfigured value = region.get('key') ``` ```python region = make_region().configure('dogpile.cache.memory') # Now it works value = region.get('key') ``` -------------------------------- ### Import CacheBackend and BytesBackend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/backends.md Import the base classes for creating custom cache backends. ```python from dogpile.cache.api import CacheBackend, BytesBackend ``` -------------------------------- ### Configure Redis Backend (Basic) Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/configuration.md Basic configuration for the Redis backend. Specify host, port, and database number for connecting to a Redis server. ```python # Basic configuration region = make_region().configure( 'dogpile.cache.redis', expiration_time=3600, arguments={ 'host': 'localhost', 'port': 6379, 'db': 0 } ) ``` -------------------------------- ### Configure Region with Kwargs Support Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/configuration.md Demonstrates configuring a cache region with a custom function key generator that supports keyword arguments. ```python from dogpile.cache import make_region from dogpile.cache.util import kwarg_function_key_generator region = make_region( function_key_generator=kwarg_function_key_generator ).configure('dogpile.cache.memory', expiration_time=3600) ``` -------------------------------- ### Configure cache region with simple arguments Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Configure a cache region using the 'dogpile.cache.memory' backend without specific expiration. ```python from dogpile.cache import make_region # Configure with simple arguments region = make_region().configure( 'dogpile.cache.memory' ) ``` -------------------------------- ### Import CacheMutex Abstract Base Class Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/lock.md Import the CacheMutex abstract base class from dogpile.cache.api. ```python from dogpile.cache.api import CacheMutex ``` -------------------------------- ### Custom Distributed Mutex Implementation Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/lock.md Implement a custom CacheMutex for distributed locking using a Redis client. This example shows how to define acquire, release, and locked methods. ```python from dogpile.cache.api import CacheMutex, CacheBackend class DistributedMutex(CacheMutex): def __init__(self, redis_client, key): self.redis = redis_client self.key = f"lock:{key}" self.lock = None def acquire(self, wait=True): # Use Redis lock self.lock = self.redis.lock(self.key, timeout=30) return self.lock.acquire(blocking=wait) def release(self): if self.lock: self.lock.release() def locked(self): return self.redis.exists(self.key) class DistributedCacheBackend(CacheBackend): def __init__(self, arguments): self.redis = arguments['redis_client'] def get_mutex(self, key): # Return a custom mutex for distributed locking return DistributedMutex(self.redis, key) # ... other methods ``` -------------------------------- ### Wrap a Custom Proxy Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Demonstrates how to wrap a custom proxy backend around a dogpile.cache region. This is useful for adding custom logic to backend operations. ```python from dogpile.cache.proxy import ProxyBackend region = make_region().configure('dogpile.cache.memory') class MyProxy(ProxyBackend): pass region.wrap(MyProxy) actual = region.actual_backend print(type(actual)) # ``` -------------------------------- ### Get Multiple Values from Cache Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Retrieves multiple values from the cache using a list of keys. Returns NO_VALUE for keys not found. Can be converted to a dictionary for easier access. ```python region = make_region().configure('dogpile.cache.memory', expiration_time=3600) region.set('key1', 'value1') region.set('key2', 'value2') values = region.get_multi(['key1', 'key2', 'key3']) # Returns ['value1', 'value2', NO_VALUE] # Convert to dictionary keys = ['key1', 'key2', 'key3'] values = region.get_multi(keys) result = {k: v for k, v in zip(keys, values) if v is not NO_VALUE} # result = {'key1': 'value1', 'key2': 'value2'} ``` -------------------------------- ### Import DBMBackend from dogpile.cache.backends.file Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-index.md Imports the DBM file-based cache backend. ```python from dogpile.cache.backends.file import DBMBackend ``` -------------------------------- ### Configure DBM Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/configuration.md Configure the DBM backend for persistent on-disk caching. Requires specifying a filename for the DBM file. ```python region = make_region().configure( 'dogpile.cache.dbm', expiration_time=3600, arguments={ 'filename': '/var/cache/myapp.dbm' } ) ``` -------------------------------- ### Get or Create Value in Cache Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Retrieves a value from the cache, or creates it using a provided creator function if the value is missing or expired. Implements the dogpile lock pattern to manage concurrent access. ```python import time region = make_region().configure('dogpile.cache.memory', expiration_time=3600) def expensive_operation(x, y): print(f"Computing {x} + {y}") time.sleep(1) return x + y # Basic usage result = region.get_or_create('sum_key', expensive_operation, creator_args=((5, 3), {})) print(result) # 8 # With should_cache_fn to avoid caching None def is_valid_result(value): return value is not None def query_database(user_id): # Returns None if user not found return None if user_id == -1 else {'id': user_id, 'name': 'User'} result = region.get_or_create( 'user:123', query_database, should_cache_fn=is_valid_result, creator_args=((123,), {}) ) ``` -------------------------------- ### Import Memcached backends from dogpile.cache.backends.memcached Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-index.md Imports Memcached cache backend implementations. ```python from dogpile.cache.backends.memcached import ( MemcachedBackend, PylibmcBackend, BMemcachedBackend, PyMemcacheBackend, ) ``` -------------------------------- ### Basic Cache Region Configuration and Usage Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Configures a memory-based cache region and demonstrates caching function results based on arguments. Shows invalidation, direct setting, refreshing, and getting cached values. ```python from dogpile.cache import make_region region = make_region().configure('dogpile.cache.memory', expiration_time=3600) @region.cache_on_arguments() def add(x, y): print(f"Computing {x} + {y}") return x + y # First call generates the value result = add(5, 3) # Prints "Computing 5 + 3", returns 8 # Second call returns cached value result = add(5, 3) # Returns 8 (no print) # Invalidate cached value add.invalidate(5, 3) # Set a value directly add.set(100, 5, 3) print(add(5, 3)) # Returns 100 # Refresh the value add.refresh(5, 3) # Calls the function and caches result # Get without regenerating value = add.get(5, 3) # Call original function without cache result = add.original(5, 3) ``` -------------------------------- ### Custom Logging Proxy Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/README.md Illustrates creating a custom backend by subclassing ProxyBackend to add logging around cache operations. This is useful for debugging or monitoring cache interactions. ```python from dogpile.cache.proxy import ProxyBackend class LoggingProxy(ProxyBackend): def get(self, key): print(f"Cache GET {key}") return self.proxied.get(key) def set(self, key, value): print(f"Cache SET {key}") self.proxied.set(key, value) region = make_region().configure( 'dogpile.cache.redis', wrap=[LoggingProxy] ) ``` -------------------------------- ### Access Configured Backend Instance Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Shows how to access the configured backend instance of a dogpile.cache region. The returned backend may be wrapped by proxies. ```python region = make_region().configure('dogpile.cache.memory') backend = region.backend print(type(backend)) # MemoryBackend or proxy wrapping it ``` -------------------------------- ### Configure Redis Backend with Authentication Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/configuration.md Configure the Redis backend with authentication credentials. Supports username and password for secure Redis connections. ```python # With authentication region = make_region().configure( 'dogpile.cache.redis', expiration_time=3600, arguments={ 'url': 'redis://user:password@redis.example.com:6379/0' } ) ``` -------------------------------- ### Get or Create Multiple Values with Creator Function Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/cacheregion.md Retrieves multiple values from the cache, creating missing ones using a provided creator function. The creator function receives a sequence of keys and must return a sequence of values. ```python region = make_region().configure('dogpile.cache.memory', expiration_time=3600) def fetch_users(user_ids): print(f"Fetching users: {user_ids}") return [{'id': uid, 'name': f'User{uid}'} for uid in user_ids] users = region.get_or_create_multi([1, 2, 3], fetch_users) # Prints "Fetching users: (1, 2, 3)" # Returns [{'id': 1, ...}, {'id': 2, ...}, {'id': 3, ...}] # Second call returns cached values users = region.get_or_create_multi([1, 2, 3], fetch_users) # No print ``` -------------------------------- ### Graceful Degradation with Fallback Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/errors.md This snippet shows how to configure a dogpile.cache region and use a try-except block to catch cache exceptions. If the cache is unavailable, it falls back to executing the creator function directly. Ensure 'dogpile.cache.redis' is installed and configured. ```python from dogpile.cache import make_region from dogpile.cache.exception import DogpileCacheException def get_data_with_fallback(key, creator): region = make_region().configure('dogpile.cache.redis') try: return region.get_or_create(key, creator) except DogpileCacheException as e: # Cache failed, compute without caching print(f"Cache unavailable: {e}") return creator() result = get_data_with_fallback('mykey', expensive_operation) ``` -------------------------------- ### Configure Regions from Dictionary Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/configuration.md Load cache region configurations from a dictionary using `configure_from_config()`. Supports different prefixes for multiple regions. ```python from dogpile.cache import make_region config = { 'cache.local.backend': 'dogpile.cache.memory', 'cache.local.expiration_time': '3600', 'cache.redis.backend': 'dogpile.cache.redis', 'cache.redis.expiration_time': '7200', 'cache.redis.arguments.host': 'localhost', 'cache.redis.arguments.port': '6379', 'cache.redis.arguments.db': '0', 'cache.redis.arguments.distributed_lock': 'true', } local_region = make_region() local_region.configure_from_config(config, 'cache.local.') redis_region = make_region() redis_region.configure_from_config(config, 'cache.redis.') ``` -------------------------------- ### cache_multi_on_arguments with asdict=True Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/configuration.md Shows how to configure @region.cache_multi_on_arguments with 'asdict=True' so the function returns a dictionary. ```python from dogpile.cache import make_region region = make_region().configure('dogpile.cache.memory', expiration_time=3600) # Return dict with asdict=True @region.cache_multi_on_arguments(asdict=True) def get_user_data(user_ids): return {uid: {'id': uid, 'name': f'User{uid}'} for uid in user_ids} result = get_user_data(1, 2, 3) # Returns {'1': {'id': 1, ...}, '2': {'id': 2, ...}, '3': {'id': 3, ...}} ``` -------------------------------- ### Enable Dogpile.cache Debug Logging Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/docs/build/usage.rst Sets up Python's basic logging configuration and sets the log level for 'dogpile.cache' to DEBUG to capture detailed cache events. ```python logging.basicConfig() logging.getLogger("dogpile.cache").setLevel(logging.DEBUG) ``` -------------------------------- ### Register a Custom Backend with dogpile.cache Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/docs/build/usage.rst Register a custom backend using the register_backend function for in-process use. This avoids the need for setuptools entry points. ```python from dogpile.cache import register_backend register_backend("dictionary", "mypackage.mybackend", "DictionaryBackend") ``` -------------------------------- ### Create and Configure a Cache Region Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/README.md Shows the basic steps to create a cache region and configure it with a specific backend and expiration time. The arguments dictionary can be used for backend-specific settings. ```python from dogpile.cache import make_region region = make_region().configure( 'dogpile.cache.BACKEND_NAME', expiration_time=3600, arguments={...} ) ``` -------------------------------- ### Import Redis backends from dogpile.cache.backends.redis Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-index.md Imports Redis cache backend implementations. ```python from dogpile.cache.backends.redis import ( RedisBackend, RedisSentinelBackend, RedisClusterBackend, ) ``` -------------------------------- ### Configure DBM Backend Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/backends.md Configure a dogpile.cache region to use the file-based DBM backend for persistent local storage. Requires a filename argument for the DBM file path. ```python region = make_region().configure( 'dogpile.cache.dbm', expiration_time=3600, arguments={'filename': '/path/to/cache.dbm'} ) ``` -------------------------------- ### Registering Custom Backends Source: https://github.com/sqlalchemy/dogpile.cache/blob/main/_autodocs/api-reference/backends.md Demonstrates how to register a custom cache backend using the `register_backend` function. This allows you to use your custom backend by its registered name in region configuration. ```APIDOC ## Registering Custom Backends Custom backends can be registered using the `register_backend()` function. ```python from dogpile.cache import register_backend register_backend( "dogpile.cache.my_backend", "mymodule.backends", "MyBackend" ) ``` This makes the backend available via `region.configure('dogpile.cache.my_backend', ...)`. ```