a Python decorator that caches a function’s return value and reuses it if the function raises an exception on subsequent calls
Project description
UCROE (Use Cached Results On Exception)
UCROE (Use Cached Results On Exception) provides Python decorators that cache a function’s return value and reuse it if the function raises an exception on subsequent calls.
Features:
- decorators to cache function return values and return them if subsequent calls raise an exception
- multiple built-in cache backends (supports cachetools, Django)
- compatible with tenacity, a retry library
- configurable via decorator parameters, environment variables, and Django settings (if available)
UCROE is a standalone library. It doesn't require Django but works well with it.
To be implemented:
- support async functions
- support methods
Getting Started
Installation
pip install ucroe
Basic Usage
from ucroe import cached_result_on_exception
@cached_result_on_exception
def f1(): ...
Expected Behaviour When Cached Value Is Present
from ucroe import cached_result_on_exception
from unittest.mock import MagicMock
mock_http_call = MagicMock(side_effect=[1, 2, ValueError, 3, 4])
@cached_result_on_exception
def f():
return mock_http_call()
assert f() == 1
assert f() == 2
assert f() == 2 # cached value is returned
assert f() == 3
assert f() == 4
Expected Behaviour When There Is No Cached Value
from unittest.mock import MagicMock
from ucroe import cached_result_on_exception
gen_fn = MagicMock(side_effect=[ValueError]) # raises during the 1st invocation
@cached_result_on_exception
def f():
return gen_fn()
f() # raises ValueError
Supported Configuration
UCROE supports the following configs, they can be configured as environment variables or Django settings, if available. In case of conflict, Django settings will take precedence.
UCROE_LOG_EXCEPTION_BY_DEFAULT
: (default:False
) when set, exception raised within the wrapped function will be logged with log levelwarning
.UCROE_BACKEND
: (default:ucroe.cache_backend.cachetools.LRUBackend
) the cache backend to useUCROE_BACKEND_CONFIG
: (default:'{"maxsize": 100}'
) JSON serialized string that will be used to instantiate the cache backend
Configuring Cache Backend
By default, @cached_result_on_exception
uses ucroe.cache_backend.cachetools.LRUBackend
, which itself is a wrapper
of cachetools.LRUCache
.
UCROE comes with a set of built-in backends:
ucroe.cache_backend.cachetools.FIFOBackend
ucroe.cache_backend.cachetools.LFUBackend
ucroe.cache_backend.cachetools.LRUBackend
ucroe.cache_backend.cachetools.RRBackend
ucroe.cache_backend.cachetools.TTLBackend
ucroe.cache_backend.cachetools.TLRUBackend
ucroe.cache_backend.django.DjangoBackend
Each cachetools backend is merely a wrapper to the corresponding cache provided by cachetools.
Using Django Backend
This library can be configured to use Django cache framework.
To do so, simple specify ucroe.cache_backend.django.DjangoBackend
as the cache backend. Eg:
# in your Django settings
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
},
"ucroe": {
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
"KEY_PREFIX": "ucroe_",
},
}
# Add the following settings:
UCROE_BACKEND = "ucroe.cache_backend.django.DjangoBackend"
# Optionally, you can also specify the Django cache to use.
# When unspecified, the `default` cache will be used
UCROE_BACKEND_CONFIG = {"cache_name": "ucroe"}
In other parts of your code, simple import and decorate your functions with @cached_results_on_exception
:
from ucroe import cached_result_on_exception
@cached_result_on_exception
def my_func(*args):
...
Using the decorators
It can be used with or without parenthesis
from ucroe import cached_result_on_exception
@cached_result_on_exception
def f1(): ...
@cached_result_on_exception()
def f2(): ...
It also accepts the following parameters:
log_exception: bool
: when set toTrue
, a warning log will emit when the wrapped function raises an exceptionfrom ucroe import cached_result_on_exception @cached_result_on_exception(log_exception=True) def f1(): ...
on_exception: Callable[[Exception], None]
: a hook that will be called when the wrapped function raisesimport logging from ucroe import cached_result_on_exception logger = logging.getLogger(__name__) def on_exception(exc): logger.error("BOOM!", exc_info=exc) @cached_result_on_exception(on_exception=on_exception) def f1(): ... f1() # If f1() raises, a log with message `error: BOOM!` and the stack trace will be emitted.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file ucroe-0.1.0.tar.gz
.
File metadata
- Download URL: ucroe-0.1.0.tar.gz
- Upload date:
- Size: 7.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.4 CPython/3.10.12 Linux/6.5.0-1025-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 21d49a49553b18bd121978d22abf683dcff41d9e7641562d9c6797e1398d7301 |
|
MD5 | 4254f1dfa05803cde6209b5d70484293 |
|
BLAKE2b-256 | 88aa98f86cd25cdd33dcdca30ca60ace2b93e9eeeaaa892e92c89ac99e2d7262 |
File details
Details for the file ucroe-0.1.0-py3-none-any.whl
.
File metadata
- Download URL: ucroe-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.4 CPython/3.10.12 Linux/6.5.0-1025-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 79f95c032c385e19ec5fc425f545910cf97650740ad82aa84575aaa2c65b769c |
|
MD5 | 8b98c74aa954faf2b1ce92c760c723aa |
|
BLAKE2b-256 | 40e7698e6458f281ae2f535b15933e0cf3337b01513cac3ce3a5a83686249bcc |