{"id":16199840,"url":"https://github.com/huntfx/supercache","last_synced_at":"2025-03-19T05:30:52.632Z","repository":{"id":57481347,"uuid":"244196609","full_name":"huntfx/supercache","owner":"huntfx","description":"Easy to use caching for functions and methods.","archived":false,"fork":false,"pushed_at":"2021-08-06T10:06:13.000Z","size":108,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-17T04:05:54.897Z","etag":null,"topics":["cache","caching","memoization","memoize","memoize-decorator","pypi","pypi-package","python"],"latest_commit_sha":null,"homepage":"","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/huntfx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-01T17:52:20.000Z","updated_at":"2021-08-06T10:03:07.000Z","dependencies_parsed_at":"2022-09-26T17:50:29.158Z","dependency_job_id":null,"html_url":"https://github.com/huntfx/supercache","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huntfx%2Fsupercache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huntfx%2Fsupercache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huntfx%2Fsupercache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huntfx%2Fsupercache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/huntfx","download_url":"https://codeload.github.com/huntfx/supercache/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244364685,"owners_count":20441458,"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":["cache","caching","memoization","memoize","memoize-decorator","pypi","pypi-package","python"],"created_at":"2024-10-10T09:28:27.321Z","updated_at":"2025-03-19T05:30:52.387Z","avatar_url":"https://github.com/huntfx.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# supercache\nEasy to use caching for functions and methods.\n\nSupercache has been designed as a decorator to work with functions and methods, to provide almost instant repeat executions with only a single extra line of code. It acts as an interface to the cache engine, which can be anything from caching in memory to using Redis (provided it's been coded).\n\nPlease note that using the decorator adds a small amount of overhead as it was designed for conveniance and stability over performance. It's possible that caching a very simple function could result in worse performance (it roughly takes 1 second per 40,000 executions).\n\n## Installation\n    pip install supercache\n\n## Usage\n```python\nfrom supercache import cache\n\n# Basic cache\n@cache()\ndef function(x, y=None):\n    return(x, y)\n\n# Set timeout\n@cache(ttl=60)\ndef function(x, y=None):\n    return(x, y)\n\n# Ignore the y argument\n@cache(ignore=['y'])\ndef function(x, y=None):\n    return(x, y)\n\n# Ignore anything after the first 2 arguments\n@cache(keys=[0, 1])\ndef function(x, y=None, *args, **kwargs):\n    return(x, y)\n\n\n# Set up a custom cache engine\nfrom supercache.engine import Memory\n\ncache = Cache(engine=Memory(mode=Memory.FIFO, ttl=600, count=100000, size=100000))\n\n\n# Manually handle cache to reduce the decorator overhead\n# This is in danger of collisions if the key is not unique\nfrom supercache.exceptions import CacheError\n\ndef function(x, y=None):\n    key = 'function;{};{}'.format(x, y)\n    try:\n        return cache.get(key)\n    except CacheError:\n        value = (x, y)\n        cache.put(key, value)\n        return value\n```\n\n### Supported Types\n```python\n# Functions\n@cache()\ndef function():\n    pass\n\n# Methods\nclass Class(object):\n    @cache()\n    def method(self):\n        pass\n\n# Generators/iterators\n@cache()\ndef generator():\n    yield\n\n# Lambdas\nfunc = cache()(lambda: None)\n```\n\n## API Reference\n\n### @cache(_keys=None, ignore=None, ttl=None, precalculate=False_)\n\n#### keys\nSet which parameters of the function to use in generating the cache key. All available parameters will be used by default.\n\nThese can be in the format of `int`, `str`, `slice` (useful for `*args`), or `regex` (useful for `**kwargs`)\n\n#### ignore\nSet which parameters to ignore when generating the cache key. This will override any settings provided in `keys`.\n\nThese can also be in the format of `int`, `str`, `slice` or `regex`\n\n#### ttl\nOverride the engine ttl setting to set how many seconds until the cache is invalidated.\n\n#### precalculate\nIf the function being cached is a generator, setting this to `True` will convert the output to a `tuple` when first called, instead of returning the iterator.\n\nThe reason for this is the generator caching has a lot of overhead, which could become very noticable when calling a simple generator thousands of times.\n\n### cache.get(_key_):\n__Alias:__ `cache[key]`\n\nRead an item of cache, or raise an error if it doesn't exist.\n\n### cache.put(_key, value, **kwargs_):\n__Alias:__ `cache[key] = value`\n\nSet a new item of cache.\n\n### cache.delete(_key=None, *args, **kwargs_)\n__Alias:__ `del cache[key]`\n\nDelete cache for a key or function.\n- `cache.delete()`: Delete all cached data.\n- `cache.delete(key)`: Delete cached data for a specific `key`.\n- `cache.delete(func)`: Delete cached data for every execution of `func`.\n- `cache.delete(func, 1, b=2)`: Delete the cached data for `func(1, b=2)`.\n\n### cache.hits(_key=None, *args, **kwargs_)\nReturn a count of how many times the cache was read for a key or function.\n\n- `cache.hits()`: Number of total cache hits.\n- `cache.hits(key)`: Number of hits for a specific `key`.\n- `cache.hits(func)`: Number of cache hits for every execution of `func`.\n- `cache.hits(func, 1, b=2)`: Number of cache hits specifically for `func(1, b=2)`.\n\n### cache.misses(_key=None, *args, **kwargs_)\nReturn a count of how many times the cache was generated for a key or function.\n\n- `cache.misses()`: Number of total cache misses.\n- `cache.misses(key)`: Number of misses for a specific `key`.\n- `cache.misses(func)`: Number of cache misses for every execution of `func`.\n- `cache.misses(func, 1, b=2)`: Number of cache misses specifically for `func(1, b=2)`.\n\n### cache.exists(_key=None, *args, **kwargs_)\nGet if the cache exists for a key or function.\n\n- `cache.exists()`: If any cache exists.\n- `cache.exists(key)`: If `key` exists in cache.\n- `cache.exists(func)`: If any execution of `func` exists in cache.\n- `cache.exists(func, 1, b=2)`: If `func(1, b=2)` exists in cache.\n\n### engine.Memory(_mode=LRU, ttl=None, count=None, size=None_)\n\n#### Mode\nSet the mode for purging cache. Options are FIFO (first in first out), FILO (first in last out), LRU (least recently used), MRU (most recently used) or LFU (least frequently used).\n\n#### ttl\nSet how many seconds until the cache is invalidated.\n\n#### count\nSet the maximum amount of cached results.\n\n#### size\nSet the maximum size of the cache in bytes. This a soft limit, where the memory will be allocated first, then older cache will be deleted until it is back under the limit.\n\nThe latest execution will always be cached, even if the maximum size is set to smaller than the result.\n\n## Planned\n- Support for SQLite\n- Support for memcached\n- Support for Redis\n\n## Limitations\n- Unable to cache if unhashable arguments are used\n- Python will assign the same hash to two classes with the same inheritance if they are both initialised on the same line (fortunately this shouldn't ever happen outside of testing)\n- `classmethods`, `staticmethods` and `properties` can only be cached if the cache decorator is executed first\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhuntfx%2Fsupercache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhuntfx%2Fsupercache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhuntfx%2Fsupercache/lists"}