# Shelved Cache
[](https://github.com/mariushelf/shelved_cache/actions/workflows/cicd.yaml)
[](https://codecov.io/gh/mariushelf/shelved_cache)
[](https://pypi.org/project/shelved_cache/)
[](https://pepy.tech/project/shelved-cache)
Persistent cache implementation for Python
[cachetools](https://github.com/tkem/cachetools/).
Behaves like any `Cache` implementation, but entries are persisted to disk.
Original repository: [https://github.com/mariushelf/shelved_cache](https://github.com/mariushelf/shelved_cache)
# Usage example
```python
from shelved_cache import PersistentCache
from cachetools import LRUCache
filename = 'mycache'
# create persistency around an LRUCache
pc = PersistentCache(LRUCache, filename=filename, maxsize=2)
# we can now use the cache like a normal LRUCache.
# But: the cache is persisted to disk.
pc["a"] = 42
pc["b"] = 43
assert pc["a"] == 42
assert pc["b"] == 43
# close the file
pc.close()
# Now in the same script or in another script, we can re-load the cache:
pc2 = PersistentCache(LRUCache, filename=filename, maxsize=2)
assert pc2["a"] == 42
assert pc2["b"] == 43
```
## Use as a decorator
Just like a regular `cachetools.Cache`, the `PersistentCache` can be used with
the `persistent_cached` decorator:
> [!WARNING]
> Do not use `cachetools`' `cached` decorator with the persistent cache, or you will experience functions with the same
> signature returning the wrong values.
```python
from shelved_cache.decorators import persistent_cached
from shelved_cache import PersistentCache
from cachetools import LRUCache
filename = 'mycache'
pc = PersistentCache(LRUCache, filename, maxsize=2)
@persistent_cached(pc)
def square(x):
print("called")
return x * x
assert square(3) == 9
# outputs "called"
assert square(3) == 9
# no output because the cache is used
```
# Features
## persistent cache
See usage examples above.
## Async decorators
The package contains equivalents for `cachetools`' `cached` and `cachedmethod`
decorators which support wrapping async methods. You can find them in the `decorators`
submodule.
They support both synchronous *and* asynchronous functions and methods.
Examples:
```python
from shelved_cache import cachedasyncmethod
from cachetools import LRUCache
class A:
# decorate an async method:
@cachedasyncmethod(lambda self: LRUCache(2))
async def asum(self, a, b):
return a + b
a = A()
assert await a.asum(1, 2) == 3
class S:
@cachedasyncmethod(lambda self: LRUCache(2))
def sum(self, a, b):
return a + b
s = S()
assert s.sum(1, 2) == 3
```
## Support for lists as function arguments
Using the `autotuple_hashkey` function, list arguments are automatically converted
to tuples, so that they support hashing.
Example:
```python
from cachetools import cached, LRUCache
from shelved_cache.keys import autotuple_hashkey
@cached(LRUCache(2), key=autotuple_hashkey)
def sum(values):
return values[0] + values[1]
# fill cache
assert sum([1, 2]) == 3
# access cache
assert sum([1, 2]) == 3
```
# Changelog
## 0.3.1
* fix for Windows users
* add Windows and MacOS to test suite
## 0.3.0
* add support for Python 3.10 and 3.11
* better error message when trying to use the same file for multiple caches
* CI/CD pipeline
* fixes for documentation
## 0.2.1
* improved error handling
# Acknowledgements
* [cachetools](https://github.com/tkem/cachetools/) by Thomas Kemmer
* [asyncache](https://github.com/hephex/asyncache) by hephex
# License
Author: Marius Helf ([helfsmarius@gmail.com](mailto:helfsmarius@gmail.com))
License: MIT -- see [LICENSE](LICENSE)
Raw data
{
"_id": null,
"home_page": "https://github.com/uninstall-your-browser/shelved_cache",
"name": "shelved_cache_fixed",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0.0,>=3.7.0",
"maintainer_email": null,
"keywords": null,
"author": "Marius Helf",
"author_email": "helfsmarius@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/78/f5/d3f4cddfaa3ca9b74d9a4dd48f9d13e8e7075b1692087ef4261c6c4b57df/shelved_cache_fixed-0.3.1.tar.gz",
"platform": null,
"description": "# Shelved Cache\n\n[](https://github.com/mariushelf/shelved_cache/actions/workflows/cicd.yaml)\n[](https://codecov.io/gh/mariushelf/shelved_cache)\n[](https://pypi.org/project/shelved_cache/)\n[](https://pepy.tech/project/shelved-cache)\n\nPersistent cache implementation for Python\n[cachetools](https://github.com/tkem/cachetools/).\n\nBehaves like any `Cache` implementation, but entries are persisted to disk.\n\nOriginal repository: [https://github.com/mariushelf/shelved_cache](https://github.com/mariushelf/shelved_cache)\n\n# Usage example\n\n```python\nfrom shelved_cache import PersistentCache\nfrom cachetools import LRUCache\n\nfilename = 'mycache'\n\n# create persistency around an LRUCache\npc = PersistentCache(LRUCache, filename=filename, maxsize=2)\n\n# we can now use the cache like a normal LRUCache.\n# But: the cache is persisted to disk.\npc[\"a\"] = 42\npc[\"b\"] = 43\n\nassert pc[\"a\"] == 42\nassert pc[\"b\"] == 43\n\n# close the file\npc.close()\n\n# Now in the same script or in another script, we can re-load the cache:\npc2 = PersistentCache(LRUCache, filename=filename, maxsize=2)\nassert pc2[\"a\"] == 42\nassert pc2[\"b\"] == 43\n```\n\n## Use as a decorator\n\nJust like a regular `cachetools.Cache`, the `PersistentCache` can be used with\nthe `persistent_cached` decorator:\n\n> [!WARNING]\n> Do not use `cachetools`' `cached` decorator with the persistent cache, or you will experience functions with the same \n> signature returning the wrong values.\n\n```python\nfrom shelved_cache.decorators import persistent_cached\nfrom shelved_cache import PersistentCache\nfrom cachetools import LRUCache\n\nfilename = 'mycache'\npc = PersistentCache(LRUCache, filename, maxsize=2)\n\n@persistent_cached(pc)\ndef square(x):\n print(\"called\")\n return x * x\n\nassert square(3) == 9\n# outputs \"called\"\nassert square(3) == 9\n# no output because the cache is used\n```\n\n\n# Features\n\n## persistent cache\n\nSee usage examples above.\n\n## Async decorators\n\nThe package contains equivalents for `cachetools`' `cached` and `cachedmethod`\ndecorators which support wrapping async methods. You can find them in the `decorators`\nsubmodule.\n\nThey support both synchronous *and* asynchronous functions and methods.\n\nExamples:\n```python\nfrom shelved_cache import cachedasyncmethod\nfrom cachetools import LRUCache\n\nclass A:\n # decorate an async method:\n @cachedasyncmethod(lambda self: LRUCache(2))\n async def asum(self, a, b):\n return a + b\n\na = A()\nassert await a.asum(1, 2) == 3\n \nclass S:\n @cachedasyncmethod(lambda self: LRUCache(2))\n def sum(self, a, b):\n return a + b\n\ns = S()\nassert s.sum(1, 2) == 3\n```\n\n\n## Support for lists as function arguments\n\nUsing the `autotuple_hashkey` function, list arguments are automatically converted\nto tuples, so that they support hashing.\n\nExample:\n```python\nfrom cachetools import cached, LRUCache\nfrom shelved_cache.keys import autotuple_hashkey\n\n@cached(LRUCache(2), key=autotuple_hashkey)\ndef sum(values):\n return values[0] + values[1]\n\n# fill cache\nassert sum([1, 2]) == 3\n\n# access cache\nassert sum([1, 2]) == 3\n```\n\n\n# Changelog\n\n## 0.3.1\n* fix for Windows users\n* add Windows and MacOS to test suite\n\n## 0.3.0\n\n* add support for Python 3.10 and 3.11\n* better error message when trying to use the same file for multiple caches\n* CI/CD pipeline\n* fixes for documentation\n\n## 0.2.1\n* improved error handling\n\n# Acknowledgements\n\n* [cachetools](https://github.com/tkem/cachetools/) by Thomas Kemmer\n* [asyncache](https://github.com/hephex/asyncache) by hephex\n\n\n# License\n\nAuthor: Marius Helf ([helfsmarius@gmail.com](mailto:helfsmarius@gmail.com))\n\nLicense: MIT -- see [LICENSE](LICENSE)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Persistent cache for Python cachetools with fixes to major issues.",
"version": "0.3.1",
"project_urls": {
"Documentation": "https://github.com/uninstall-your-browser/shelved_cache",
"Homepage": "https://github.com/uninstall-your-browser/shelved_cache",
"Repository": "https://github.com/uninstall-your-browser/shelved_cache"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "b6546d9e5869ea805a02f9ce8c5a6697196f0b9f903fae191401de9549cdcd28",
"md5": "943ba65c15916e07ccc65b1d65bc5fc2",
"sha256": "66b749df6ced86f8e7fd84aaf4e73388e8975cd936a2dec69ade5ccbe951a31b"
},
"downloads": -1,
"filename": "shelved_cache_fixed-0.3.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "943ba65c15916e07ccc65b1d65bc5fc2",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0.0,>=3.7.0",
"size": 8339,
"upload_time": "2024-10-19T03:15:17",
"upload_time_iso_8601": "2024-10-19T03:15:17.792667Z",
"url": "https://files.pythonhosted.org/packages/b6/54/6d9e5869ea805a02f9ce8c5a6697196f0b9f903fae191401de9549cdcd28/shelved_cache_fixed-0.3.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "78f5d3f4cddfaa3ca9b74d9a4dd48f9d13e8e7075b1692087ef4261c6c4b57df",
"md5": "80d522ae8288a3daf0e089bfdabe7df9",
"sha256": "4eaf078a9a3588d47720f463ed819028a2861de50a67bb0b86b2f5465248fe26"
},
"downloads": -1,
"filename": "shelved_cache_fixed-0.3.1.tar.gz",
"has_sig": false,
"md5_digest": "80d522ae8288a3daf0e089bfdabe7df9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0.0,>=3.7.0",
"size": 7029,
"upload_time": "2024-10-19T03:15:19",
"upload_time_iso_8601": "2024-10-19T03:15:19.443918Z",
"url": "https://files.pythonhosted.org/packages/78/f5/d3f4cddfaa3ca9b74d9a4dd48f9d13e8e7075b1692087ef4261c6c4b57df/shelved_cache_fixed-0.3.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-19 03:15:19",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "uninstall-your-browser",
"github_project": "shelved_cache",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "shelved_cache_fixed"
}