{"id":13738012,"url":"https://github.com/dgilland/cacheout","last_synced_at":"2025-04-08T02:42:05.281Z","repository":{"id":28792640,"uuid":"117295087","full_name":"dgilland/cacheout","owner":"dgilland","description":"A caching library for Python","archived":false,"fork":false,"pushed_at":"2023-12-22T17:41:59.000Z","size":231,"stargazers_count":425,"open_issues_count":4,"forks_count":44,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-10-29T16:55:59.312Z","etag":null,"topics":["caching","fifo","lfu","lifo","lru","memoization","mru","python","python3","rr"],"latest_commit_sha":null,"homepage":"https://cacheout.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dgilland.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE.rst","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.rst"}},"created_at":"2018-01-12T22:46:58.000Z","updated_at":"2024-10-22T07:40:04.000Z","dependencies_parsed_at":"2023-11-17T03:28:49.970Z","dependency_job_id":"2eb4f43c-f8e3-4fcb-a320-0ef61e6cf8c4","html_url":"https://github.com/dgilland/cacheout","commit_stats":{"total_commits":172,"total_committers":6,"mean_commits":"28.666666666666668","dds":0.03488372093023251,"last_synced_commit":"11ba7fdb6bce909bc2bcbfa50cfc172463199d6d"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgilland%2Fcacheout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgilland%2Fcacheout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgilland%2Fcacheout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgilland%2Fcacheout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dgilland","download_url":"https://codeload.github.com/dgilland/cacheout/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247767232,"owners_count":20992538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["caching","fifo","lfu","lifo","lru","memoization","mru","python","python3","rr"],"created_at":"2024-08-03T03:02:08.878Z","updated_at":"2025-04-08T02:42:05.253Z","avatar_url":"https://github.com/dgilland.png","language":"Python","readme":"cacheout\n********\n\n|version| |build| |coveralls| |license|\n\n\nA caching library for Python.\n\n\nLinks\n=====\n\n- Project: https://github.com/dgilland/cacheout\n- Documentation: https://cacheout.readthedocs.io\n- PyPI: https://pypi.python.org/pypi/cacheout/\n- Github Actions: https://github.com/dgilland/cacheout/actions\n\n\nFeatures\n========\n\n- In-memory caching using dictionary backend\n- Cache manager for easily accessing multiple cache objects\n- Reconfigurable cache settings for runtime setup when using module-level cache objects\n- Maximum cache size enforcement\n- Default cache TTL (time-to-live) as well as custom TTLs per cache entry\n- Bulk set, get, and delete operations\n- Bulk get and delete operations filtered by string, regex, or function\n- Memoization decorators\n- Thread safe\n- Multiple cache implementations:\n\n  - FIFO (First In, First Out)\n  - LIFO (Last In, First Out)\n  - LRU (Least Recently Used)\n  - MRU (Most Recently Used)\n  - LFU (Least Frequently Used)\n  - RR (Random Replacement)\n\n\nRoadmap\n=======\n\n- Layered caching (multi-level caching)\n\n\nRequirements\n============\n\n- Python \u003e= 3.7\n\n\nQuickstart\n==========\n\nInstall using pip:\n\n\n::\n\n    pip install cacheout\n\n\nLet's start with some basic caching by creating a cache object:\n\n.. code-block:: python\n\n    from cacheout import Cache\n\n    cache = Cache()\n\n\nBy default the ``cache`` object will have a maximum size of ``256``, default TTL (time-to-live) expiration turned off, TTL timer that uses ``time.time`` (meaning TTL is in seconds), and the default for missing keys as ``None``. These values can be set with:\n\n.. code-block:: python\n\n    cache = Cache(maxsize=256, ttl=0, timer=time.time, default=None)  # defaults\n\n\nSet a cache key using ``cache.set()``:\n\n.. code-block:: python\n\n    cache.set(1, 'foobar')\n\n\nGet the value of a cache key with ``cache.get()``:\n\n.. code-block:: python\n\n    assert cache.get(1) == 'foobar'\n\n\nGet a default value when cache key isn't set:\n\n.. code-block:: python\n\n    assert cache.get(2) is None\n    assert cache.get(2, default=False) is False\n    assert 2 not in cache\n\n\nProvide cache values using a default callable:\n\n.. code-block:: python\n\n    assert 2 not in cache\n    assert cache.get(2, default=lambda key: key) == 2\n    assert cache.get(2) == 2\n    assert 2 in cache\n\n\nProvide a global default:\n\n.. code-block:: python\n\n    cache2 = Cache(default=True)\n    assert cache2.get('missing') is True\n    assert 'missing' not in cache2\n\n    cache3 = Cache(default=lambda key: key)\n    assert cache3.get('missing') == 'missing'\n    assert 'missing' in cache3\n\n\nSet the TTL (time-to-live) expiration per entry (default TTL units are in seconds when ``Cache.timer`` is set to the default ``time.time``; otherwise, the units are determined by the custom timer function):\n\n.. code-block:: python\n\n    cache.set(3, {'data': {}}, ttl=1)\n    assert cache.get(3) == {'data': {}}\n    time.sleep(1)\n    assert cache.get(3) is None\n\n\nMemoize a function where cache keys are generated from the called function parameters:\n\n.. code-block:: python\n\n    @cache.memoize()\n    def func(a, b):\n        pass\n\n\nProvide a TTL for the memoized function and incorporate argument types into generated cache keys:\n\n.. code-block:: python\n\n    @cache.memoize(ttl=5, typed=True)\n    def func(a, b):\n        pass\n\n    # func(1, 2) has different cache key than func(1.0, 2.0), whereas,\n    # with \"typed=False\" (the default), they would have the same key\n\n\nAccess the original memoized function:\n\n.. code-block:: python\n\n    @cache.memoize()\n    def func(a, b):\n        pass\n\n    func.uncached(1, 2)\n\n\nGet a copy of the entire cache with ``cache.copy()``:\n\n.. code-block:: python\n\n    assert cache.copy() == {1: 'foobar', 2: ('foo', 'bar', 'baz')}\n\n\nDelete a cache key with ``cache.delete()``:\n\n.. code-block:: python\n\n    cache.delete(1)\n    assert cache.get(1) is None\n\n\nClear the entire cache with ``cache.clear()``:\n\n.. code-block:: python\n\n    cache.clear()\n    assert len(cache) == 0\n\n\nPerform bulk operations with ``cache.set_many()``, ``cache.get_many()``, and ``cache.delete_many()``:\n\n.. code-block:: python\n\n    cache.set_many({'a': 1, 'b': 2, 'c': 3})\n    assert cache.get_many(['a', 'b', 'c']) == {'a': 1, 'b': 2, 'c': 3}\n    cache.delete_many(['a', 'b', 'c'])\n    assert cache.count() == 0\n\n\nUse complex filtering in ``cache.get_many()`` and ``cache.delete_many()``:\n\n.. code-block:: python\n\n    import re\n    cache.set_many({'a_1': 1, 'a_2': 2, '123': 3, 'b': 4})\n\n    cache.get_many('a_*') == {'a_1': 1, 'a_2': 2}\n    cache.get_many(re.compile(r'\\d')) == {'123': 3}\n    cache.get_many(lambda key: '2' in key) == {'a_2': 2, '123': 3}\n\n    cache.delete_many('a_*')\n    assert dict(cache.items()) == {'123': 3, 'b': 4}\n\n\nReconfigure the cache object after creation with ``cache.configure()``:\n\n.. code-block:: python\n\n    cache.configure(maxsize=1000, ttl=5 * 60)\n\n\nGet keys, values, and items from the cache with ``cache.keys()``, ``cache.values()``, and ``cache.items()``:\n\n.. code-block:: python\n\n    cache.set_many({'a': 1, 'b': 2, 'c': 3})\n    assert list(cache.keys()) == ['a', 'b', 'c']\n    assert list(cache.values()) == [1, 2, 3]\n    assert list(cache.items()) == [('a', 1), ('b', 2), ('c', 3)]\n\n\nIterate over cache keys:\n\n.. code-block:: python\n\n    for key in cache:\n        print(key, cache.get(key))\n        # 'a' 1\n        # 'b' 2\n        # 'c' 3\n\n\nCheck if key exists with ``cache.has()`` and ``key in cache``:\n\n.. code-block:: python\n\n    assert cache.has('a')\n    assert 'a' in cache\n\n\nUse callbacks to be notified of on-get, on-set, and on-delete events:\n\n.. code-block:: python\n\n    def on_get(key, value, exists):\n        pass\n\n    def on_set(key, new_value, old_value):\n        pass\n\n    def on_delete(key, value, cause):\n        pass\n\n\nEnable cache statistics:\n\n.. code-block:: python\n\n    cache_with_stats = Cache(enable_stats=True)\n\n    # Or via configure()\n    cache.configure(enable_stats=True)\n\n    # Or directly via Cache.stats\n    cache.stats.enable()\n\n\nGet cache statistics:\n\n.. code-block:: python\n\n    print(cache.stats.info())\n\n\nManage tracking of statistics:\n\n.. code-block:: python\n\n    # Pause tracking (collected stats will not be affected)\n    cache.stats.pause()\n\n    # Resume tracking\n    cache.stats.resume()\n\n    # Reset stats\n    cache.stats.reset()\n\n    # Disable stats (WARNING: This resets stats)\n    cache.stats.disable()\n\n    # Disable via configure() (WARNING: This resets stats)\n    cache.configure(enable_stats=False)\n\n\nManage multiple caches using ``CacheManager``:\n\n.. code-block:: python\n\n    from cacheout import CacheManager\n\n    cacheman = CacheManager({'a': {'maxsize': 100},\n                             'b': {'maxsize': 200, 'ttl': 900},\n                             'c': {})\n\n    cacheman['a'].set('key1', 'value1')\n    value = cacheman['a'].get('key')\n\n    cacheman['b'].set('key2', 'value2')\n    assert cacheman['b'].maxsize == 200\n    assert cacheman['b'].ttl == 900\n\n    cacheman['c'].set('key3', 'value3')\n\n    cacheman.clear_all()\n    for name, cache in cacheman:\n        assert name in cacheman\n        assert len(cache) == 0\n\n\nFor more details, see the full documentation at https://cacheout.readthedocs.io.\n\n\n\n.. |version| image:: https://img.shields.io/pypi/v/cacheout.svg?style=flat-square\n    :target: https://pypi.python.org/pypi/cacheout/\n\n.. |build| image:: https://img.shields.io/github/actions/workflow/status/dgilland/cacheout/main.yml?branch=master\u0026style=flat-square\n    :target: https://github.com/dgilland/cacheout/actions\n\n.. |coveralls| image:: https://img.shields.io/coveralls/dgilland/cacheout/master.svg?style=flat-square\n    :target: https://coveralls.io/r/dgilland/cacheout\n\n.. |license| image:: https://img.shields.io/pypi/l/cacheout.svg?style=flat-square\n    :target: https://pypi.python.org/pypi/cacheout/\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgilland%2Fcacheout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdgilland%2Fcacheout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgilland%2Fcacheout/lists"}