Skip to main content

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 level warning.
  • UCROE_BACKEND: (default: ucroe.cache_backend.cachetools.LRUBackend) the cache backend to use
  • UCROE_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 to True, a warning log will emit when the wrapped function raises an exception
    from 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 raises
    import 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ucroe-0.1.0.tar.gz (7.5 kB view details)

Uploaded Source

Built Distribution

ucroe-0.1.0-py3-none-any.whl (8.2 kB view details)

Uploaded Python 3

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

Hashes for ucroe-0.1.0.tar.gz
Algorithm Hash digest
SHA256 21d49a49553b18bd121978d22abf683dcff41d9e7641562d9c6797e1398d7301
MD5 4254f1dfa05803cde6209b5d70484293
BLAKE2b-256 88aa98f86cd25cdd33dcdca30ca60ace2b93e9eeeaaa892e92c89ac99e2d7262

See more details on using hashes here.

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

Hashes for ucroe-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 79f95c032c385e19ec5fc425f545910cf97650740ad82aa84575aaa2c65b769c
MD5 8b98c74aa954faf2b1ce92c760c723aa
BLAKE2b-256 40e7698e6458f281ae2f535b15933e0cf3337b01513cac3ce3a5a83686249bcc

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page