Name | ucroe JSON |
Version |
0.1.0
JSON |
| download |
home_page | None |
Summary | a Python decorator that caches a function’s return value and reuses it if the function raises an exception on subsequent calls |
upload_time | 2024-10-22 02:02:17 |
maintainer | None |
docs_url | None |
author | Melvin Koh |
requires_python | <4.0,>=3.10 |
license | MIT |
keywords |
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# 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](https://tenacity.readthedocs.io/en/latest/), 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
```shell
pip install ucroe
```
## Basic Usage
```python
from ucroe import cached_result_on_exception
@cached_result_on_exception
def f1(): ...
```
### Expected Behaviour When Cached Value Is Present
```python
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
```python
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`](https://cachetools.readthedocs.io/en/latest/#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:
```python
# 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`:
```python
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
```python
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
```python
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
```python
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.
```
Raw data
{
"_id": null,
"home_page": null,
"name": "ucroe",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.10",
"maintainer_email": null,
"keywords": null,
"author": "Melvin Koh",
"author_email": "melvinkcx@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/88/aa/98f86cd25cdd33dcdca30ca60ace2b93e9eeeaaa892e92c89ac99e2d7262/ucroe-0.1.0.tar.gz",
"platform": null,
"description": "# UCROE (Use Cached Results On Exception)\n\nUCROE (Use Cached Results On Exception) provides Python decorators that cache a function\u2019s return value and reuse it if\nthe\nfunction raises an exception on subsequent calls.\n\nFeatures:\n\n- decorators to cache function return values and return them if subsequent calls raise an exception\n- multiple built-in cache backends (supports cachetools, Django)\n- compatible with [tenacity](https://tenacity.readthedocs.io/en/latest/), a retry library\n- configurable via decorator parameters, environment variables, and Django settings (if available)\n\n> UCROE is a standalone library. It doesn't require Django but works well with it.\n\nTo be implemented:\n\n- support async functions\n- support methods\n\n---\n\n# Getting Started\n\n## Installation\n\n```shell\npip install ucroe\n```\n\n## Basic Usage\n\n```python\nfrom ucroe import cached_result_on_exception\n\n\n@cached_result_on_exception\ndef f1(): ...\n```\n\n### Expected Behaviour When Cached Value Is Present\n\n```python\nfrom ucroe import cached_result_on_exception\nfrom unittest.mock import MagicMock\n\nmock_http_call = MagicMock(side_effect=[1, 2, ValueError, 3, 4])\n\n\n@cached_result_on_exception\ndef f():\n return mock_http_call()\n\n\nassert f() == 1\nassert f() == 2\nassert f() == 2 # cached value is returned\nassert f() == 3\nassert f() == 4\n```\n\n### Expected Behaviour When There Is No Cached Value\n\n```python\nfrom unittest.mock import MagicMock\n\nfrom ucroe import cached_result_on_exception\n\ngen_fn = MagicMock(side_effect=[ValueError]) # raises during the 1st invocation\n\n\n@cached_result_on_exception\ndef f():\n return gen_fn()\n\n\nf() # raises ValueError\n```\n\n## Supported Configuration\n\nUCROE supports the following configs, they can be configured as environment variables or Django settings, if available.\nIn case of conflict, Django settings will take precedence.\n\n- `UCROE_LOG_EXCEPTION_BY_DEFAULT`: (default: `False`) when set, exception raised within the wrapped function will be\n logged with log level `warning`.\n- `UCROE_BACKEND`: (default: `ucroe.cache_backend.cachetools.LRUBackend`) the cache backend to use\n- `UCROE_BACKEND_CONFIG`: (default: `'{\"maxsize\": 100}'`) JSON serialized string that will be used to instantiate the\n cache backend\n\n## Configuring Cache Backend\n\nBy default, `@cached_result_on_exception` uses `ucroe.cache_backend.cachetools.LRUBackend`, which itself is a wrapper\nof [`cachetools.LRUCache`](https://cachetools.readthedocs.io/en/latest/#cachetools.LRUCache).\n\nUCROE comes with a set of built-in backends:\n\n- `ucroe.cache_backend.cachetools.FIFOBackend`\n- `ucroe.cache_backend.cachetools.LFUBackend`\n- `ucroe.cache_backend.cachetools.LRUBackend`\n- `ucroe.cache_backend.cachetools.RRBackend`\n- `ucroe.cache_backend.cachetools.TTLBackend`\n- `ucroe.cache_backend.cachetools.TLRUBackend`\n- `ucroe.cache_backend.django.DjangoBackend`\n\nEach cachetools backend is merely a wrapper to the corresponding cache provided by cachetools.\n\n### Using Django Backend\n\nThis library can be configured to use Django cache framework.\nTo do so, simple specify `ucroe.cache_backend.django.DjangoBackend` as the cache backend. Eg:\n\n```python\n# in your Django settings \nCACHES = {\n \"default\": {\n \"BACKEND\": \"django.core.cache.backends.locmem.LocMemCache\",\n },\n \"ucroe\": {\n \"BACKEND\": \"django.core.cache.backends.locmem.LocMemCache\",\n \"KEY_PREFIX\": \"ucroe_\",\n },\n}\n\n# Add the following settings:\nUCROE_BACKEND = \"ucroe.cache_backend.django.DjangoBackend\"\n# Optionally, you can also specify the Django cache to use.\n# When unspecified, the `default` cache will be used\nUCROE_BACKEND_CONFIG = {\"cache_name\": \"ucroe\"}\n```\n\nIn other parts of your code, simple import and decorate your functions with `@cached_results_on_exception`:\n\n```python\nfrom ucroe import cached_result_on_exception\n\n\n@cached_result_on_exception\ndef my_func(*args):\n ...\n```\n\n## Using the decorators\n\nIt can be used with or without parenthesis\n\n```python\nfrom ucroe import cached_result_on_exception\n\n\n@cached_result_on_exception\ndef f1(): ...\n\n\n@cached_result_on_exception()\ndef f2(): ...\n```\n\nIt also accepts the following parameters:\n\n- `log_exception: bool`: when set to `True`, a warning log will emit when the wrapped function raises an exception\n ```python\n from ucroe import cached_result_on_exception\n \n @cached_result_on_exception(log_exception=True)\n def f1(): ...\n ```\n- `on_exception: Callable[[Exception], None]`: a hook that will be called when the wrapped function raises\n ```python\n import logging\n from ucroe import cached_result_on_exception\n \n logger = logging.getLogger(__name__)\n \n \n def on_exception(exc):\n logger.error(\"BOOM!\", exc_info=exc)\n \n \n @cached_result_on_exception(on_exception=on_exception)\n def f1(): ...\n \n \n f1() # If f1() raises, a log with message `error: BOOM!` and the stack trace will be emitted.\n ```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "a Python decorator that caches a function\u2019s return value and reuses it if the function raises an exception on subsequent calls",
"version": "0.1.0",
"project_urls": null,
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "40e7698e6458f281ae2f535b15933e0cf3337b01513cac3ce3a5a83686249bcc",
"md5": "8b98c74aa954faf2b1ce92c760c723aa",
"sha256": "79f95c032c385e19ec5fc425f545910cf97650740ad82aa84575aaa2c65b769c"
},
"downloads": -1,
"filename": "ucroe-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8b98c74aa954faf2b1ce92c760c723aa",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.10",
"size": 8155,
"upload_time": "2024-10-22T02:02:15",
"upload_time_iso_8601": "2024-10-22T02:02:15.802639Z",
"url": "https://files.pythonhosted.org/packages/40/e7/698e6458f281ae2f535b15933e0cf3337b01513cac3ce3a5a83686249bcc/ucroe-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "88aa98f86cd25cdd33dcdca30ca60ace2b93e9eeeaaa892e92c89ac99e2d7262",
"md5": "4254f1dfa05803cde6209b5d70484293",
"sha256": "21d49a49553b18bd121978d22abf683dcff41d9e7641562d9c6797e1398d7301"
},
"downloads": -1,
"filename": "ucroe-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "4254f1dfa05803cde6209b5d70484293",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.10",
"size": 7492,
"upload_time": "2024-10-22T02:02:17",
"upload_time_iso_8601": "2024-10-22T02:02:17.246206Z",
"url": "https://files.pythonhosted.org/packages/88/aa/98f86cd25cdd33dcdca30ca60ace2b93e9eeeaaa892e92c89ac99e2d7262/ucroe-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-22 02:02:17",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "ucroe"
}