{"id":16444909,"url":"https://github.com/jaymon/caches","last_synced_at":"2025-03-23T08:32:12.093Z","repository":{"id":10654165,"uuid":"12884773","full_name":"Jaymon/caches","owner":"Jaymon","description":"Python caching backed by Redis","archived":false,"fork":false,"pushed_at":"2023-07-12T20:33:52.000Z","size":118,"stargazers_count":5,"open_issues_count":3,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-18T19:29:02.104Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"davechurchill/ualbertabot","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Jaymon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-09-17T02:50:34.000Z","updated_at":"2024-11-28T16:27:55.000Z","dependencies_parsed_at":"2024-10-28T15:34:34.490Z","dependency_job_id":"da14388d-2de2-4730-aa52-949d0e4a1c42","html_url":"https://github.com/Jaymon/caches","commit_stats":{"total_commits":41,"total_committers":2,"mean_commits":20.5,"dds":0.04878048780487809,"last_synced_commit":"433c902f7ee7bbab2640e6e1cc05fab818752e1f"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jaymon%2Fcaches","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jaymon%2Fcaches/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jaymon%2Fcaches/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jaymon%2Fcaches/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Jaymon","download_url":"https://codeload.github.com/Jaymon/caches/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245078067,"owners_count":20557274,"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":[],"created_at":"2024-10-11T09:42:34.529Z","updated_at":"2025-03-23T08:32:11.815Z","avatar_url":"https://github.com/Jaymon.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Caches\n\nA Python caching library that gives a similar interface to standard Python data structures like Dict and Set but is backed by [Redis](https://redis.io).\n\nCaches has been used in production for years across many different products, handling millions of requests.\n\n\n## How to use\n\nCaches relies on setting the environment variable `CACHES_DSN`:\n\n    redis://localhost/0\n\nIf you want to cache things using more than one Redis server, you can actually set multiple environment variables and specify the `caches.interface.Redis` class you want to use:\n\n    # redis1 uses the standard Redis interface\n    export CACHES_DSN_1=redis://somedomain.com/0#redis1\n    \n    # redis2 uses a custom interface child class\n    export CACHES_DSN_2=custom.interface.Redis://someotherdomain.com/0#redis2\n\nAfter you've set the environment variable, then you just need to import caches in your code:\n\n```python\nimport caches\n```\n\nCaches will take care of parsing the and DSN urls and creating the associated Redis connections automatically, so after importing, Caches will be ready to use.\n\n\n### Interface\n\nAll Caches caching classes have a similar interface, their constructor takes a key and data:\n\n```python\nc = Cache(['foo', 'bar', 'che'])\nprint c.key # foo.bar.che\n```\n\nIf you would like to init your cache object with a value, use the `data` `**kwarg`:\n\n```python\nc = Cache('foo', data=\"boom!\")\nprint c.key # foo\nprint c # \"boom!\"\n```\n\nEach Caches base caching class is meant to be extended so you can set some parameters:\n\n* **serialize** -- boolean -- True if you want all values pickled, False if you don't (ie, you're caching ints or strings or something).\n\n* **prefix** -- string -- This will be prepended to the key args you pass into the constructor.\n\n* **ttl** -- integer -- time to live, how many seconds to cache the value. 0 (default) means cache forever.\n\n* **connection_name** -- string -- if you have more than one caches DSN then you can use this to set the name of the connection you want (the name of the connection is the `#connection_name` fragment of a DSN url).\n\n```python\nclass MyIntCache(Cache):\n  serialize = False # don't bother to serialize values since we're storing ints\n  prefix = \"MyIntCache\" # every key will have this prefix, change to invalidate all currently cached values\n  ttl = 7200 # store each int for 2 hours\n```\n\n### Cache Classes\n\n\n#### Cache\n\nThis is the traditional caching object, it sets a value into a key:\n\n```python\nc = Cache('foo')\nc.data = 5 # cache 5\nc += 10 # increment 5 by 10, store 15 in the cache\n\nc.clear()\nprint(c) # None\n```\n\n\n#### DictCache\n\nThis caching object acts more or less like a Python [dictionary](http://docs.python.org/3/library/stdtypes.html#mapping-types-dict):\n\n```python\nc = DictCache('foo')\nc['bar'] = 'b'\nc['che'] = 'c'\nfor key, val in c.items():\n  print(key, val) # will print \"bar b\" and then \"che c\"\n```\n\n\n#### SetCache\n\nThis caching object acts more or less like a Python [set](http://docs.python.org/2/library/stdtypes.html#set):\n\n```python\nc = SetCache('foo')\nc.add('bar')\nc.add('che')\nprint('che' in c) # True\n```\n\n\n#### SortedSetCache\n\nThis caching object acts more or less like a Python [set](http://docs.python.org/2/library/stdtypes.html#set) but has some changes:\n\n* The `add()` method takes a tuple `(score, elem)`\n* The `pop()` method will pop off the lowest score from the set, and pops a tuple `(score, elem)`\n* An `rpop()` method allows you to pop the highest score from the set.\n* Iterating through the set results in tuples of `(score, elem)`, not just elem like in a normal set or the `SetCache`.\n\n```python\nc = SortedSetCache('foo')\nc.add((1, 'bar'))\nc.add((10, 'che'))\nprint('che' in c) # True\nprint(c.pop()) # (1, bar)\n```\n\n\n#### SentinelCache\n\nHandy for gated access:\n\n```python\nc = SentinelCache('foo')\n\nif not c:\n    print(\"sentinel value isn't set so do this\")\n\nif not c:\n    print(\"sentinel value is now set so this will never run\")\n```\n\n\n### Decorator\n\nCaches exposes a decorator to make caching the return value of a function easy. This only works for `Cache` derived caching.\n\nThe `cached` decorator can accept a caching class and also a key function (similar to the python [built-in `sorted()` function](http://docs.python.org/2/library/functions.html#sorted) key argument), except caches key argument returns a list that can be passed to the constructor of the caching class as `*args`.\n\n```python\nimport functools\nfrom caches import Cache\n\n@Cache.cached(key=\"some_cache_key\")\ndef foo(*args):\n    return functools.reduce(lambda x, y: x+y, args)\n\nfoo(1, 2) # will compute the value and cache the return value\nfoo(1, 2) # return value from cache\n\nfoo(1, 2, 3) # uh-oh, wrong value, our key was too static\n```\n\nLet's try again, this time with a dynamic key\n\n```python\n@Cache.cached(key=lambda *args: args)\ndef foo(*args):\n    return functools.reduce(lambda x, y: x+y, args)\n\nfoo(1, 2) # compute and cache, key func returned [1, 2]\nfoo(1, 2) # grabbed from cache\nfoo(1, 2, 3) # compute and cache because our key func returned [1, 2, 3]\n```\n\nWhat about custom caches classes?\n\n```python\nclass CustomCache(Cache): pass\n\n@CustomCache.cached(key=lambda *args: args)\ndef foo(*args):\n    return functools.reduce(lambda x, y: x+y, args)\n```\n\n\n## Install\n\nUse pip from pypi:\n\n    pip install caches\n\nor from source using pip:\n\n    pip install -U \"git+https://github.com/jaymon/caches#egg=caches\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaymon%2Fcaches","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaymon%2Fcaches","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaymon%2Fcaches/lists"}