{"id":24639665,"url":"https://github.com/jpleorx/omoide-cache","last_synced_at":"2025-05-09T03:39:51.480Z","repository":{"id":57448612,"uuid":"387622560","full_name":"JPLeoRX/omoide-cache","owner":"JPLeoRX","description":"Robust, highly tunable and easy-to-integrate in-memory cache solution written in pure Python, with no dependencies.","archived":false,"fork":false,"pushed_at":"2023-04-25T20:27:21.000Z","size":543,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-31T21:42:31.320Z","etag":null,"topics":["annotation","cache","cache-service","caching","caching-library","caching-memory","decorator","inmemory-cache","library","pip","pypi-package","python","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JPLeoRX.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}},"created_at":"2021-07-19T23:57:44.000Z","updated_at":"2023-05-26T18:28:14.000Z","dependencies_parsed_at":"2022-09-26T17:31:04.426Z","dependency_job_id":null,"html_url":"https://github.com/JPLeoRX/omoide-cache","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JPLeoRX%2Fomoide-cache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JPLeoRX%2Fomoide-cache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JPLeoRX%2Fomoide-cache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JPLeoRX%2Fomoide-cache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JPLeoRX","download_url":"https://codeload.github.com/JPLeoRX/omoide-cache/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253186688,"owners_count":21868064,"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":["annotation","cache","cache-service","caching","caching-library","caching-memory","decorator","inmemory-cache","library","pip","pypi-package","python","python3"],"created_at":"2025-01-25T11:12:22.834Z","updated_at":"2025-05-09T03:39:51.457Z","avatar_url":"https://github.com/JPLeoRX.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/JPLeoRX/omoide-cache\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/JPLeoRX/omoide-cache/master/logo_400x400.png\" alt=\"Omoide Cache\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# Omoide Cache - Simple in-memory cache solution\nCaching doesn't need to be hard anymore. With just a few lines of code **Omoide Cache** will instantly bring your Python services to the next level!\n\n---\n\n**Released Library**: [PyPI](https://pypi.org/project/omoide-cache/)\n\n**Source Code**: [GitHub](https://github.com/JPLeoRX/omoide-cache)\n\n**Tutorial №1**: [my blog](https://tekleo.net/blog/omoide-cache-introduction-quick-and-easy-caching-in-python) or [Medium](https://medium.com/@leo.ertuna/omoide-cache-introduction-quick-and-easy-caching-in-python-13389b41bbfd) \n\n---\n\n# Description\nThis is a robust, highly tunable and easy-to-integrate in-memory cache solution written in pure Python, with no dependencies.\n\nIt is designed to be a method level cache, wrapping around a single class method, using method call arguments as cache key and storing its return value. \n\nCustomizable to suit your specific use-case, provides various expiry and refresh options.\n\nVery user-friendly, super easy to integrate with a simple decorator (i.e. annotation, for those coming from Java), no need to add complicated logic into your code, just use `@omoide_cache()` on top of any method in your services. It will auto-generate a cache for your method with default settings. You can further adjust these settings through decorator parameters.\n\n### When to use?\n- You got a heavy call to the data source, where the data is read way more often than it is updated.\n- You have CPU intensive computation logic, that takes a few seconds to complete, but can is frequently called with same input parameters.\n\n### When not to use?\n- On methods that are not expected to be frequently called with the same arguments (e.g. image processing / OCR / ML models with image inputs)\n- On methods that return new values each time they are called, even with the same arguments.\n- When you expect argument objects or returned objects to take-up a lot of memory. Cache will quickly eat up your ram if you don't setup expiry modes properly.\n- Functions that are declared outside of class is a no go.  \n\nFair warning - this project is in the earliest stage of its lifecycle, there will be a lot of improvement and bug fixes in the future. All suggestions and bug reports are highly welcome!\n\n# Installation\n \n## Normal installation\n```bash\npip install omoide-cache\n```\n\n## Development installation\n```bash\ngit clone https://github.com/jpleorx/omoide-cache.git\ncd omoide-cache\npip install --editable .\n```\n\n# Examples\n#### 1 - Basic usage example\n```python\nimport time\nfrom omoide_cache import omoide_cache\n\n\n# A class where cache was added to a simulated long running method\nclass ExampleService:\n    @omoide_cache()\n    def time_consuming_method(self, x: int) -\u003e int:\n        time.sleep(2.0)\n        return x * x\n\n\nservice = ExampleService()\n\n# The first call will execute real logic and store the result in cache\nservice.time_consuming_method(1)\n\n# The second call will get results from cache\nservice.time_consuming_method(1)\n```\n\n#### 2 - Example with size limit\nHere we add a cache that will drop an item least frequently accessed when the cache becomes too large.\n```python\nimport time\nfrom omoide_cache import omoide_cache, ExpireMode\n\n\nclass ExampleService:\n    @omoide_cache(max_allowed_size=10, size_expire_mode=ExpireMode.ACCESS_COUNT_BASED)\n    def time_consuming_method(self, x: int) -\u003e int:\n        time.sleep(2.0)\n        return x * x\n```\n\n#### 3 - Example with timed expiry\nHere the cache will automatically remove items that were last accessed more than 2 minutes ago.\n```python\nimport time\nfrom omoide_cache import omoide_cache\n\n\nclass ExampleService:\n    @omoide_cache(expire_by_access_duration_s=120)\n    def time_consuming_method(self, x: int) -\u003e int:\n        time.sleep(2.0)\n        return x * x\n```\nAlternatively we can remove items that were computed more than 2 minutes ago.\n```python\nimport time\nfrom omoide_cache import omoide_cache\n\n\nclass ExampleService:\n    @omoide_cache(expire_by_computed_duration_s=120)\n    def time_consuming_method(self, x: int) -\u003e int:\n        time.sleep(2.0)\n        return x * x\n```\n\n#### 4 - Example with async refresh\nHere the cache will asynchronously refresh items that were computed more than 2 minutes ago. Attempt to refresh will be performed every 10 seconds.\n```python\nimport time\nfrom omoide_cache import omoide_cache, RefreshMode\n\n\nclass ExampleService:\n    @omoide_cache(refresh_duration_s=120, refresh_period_s=10, refresh_mode=RefreshMode.INDEPENDENT)\n    def time_consuming_method(self, x: int) -\u003e int:\n        time.sleep(2.0)\n        return x * x\n```\n\n# Known bugs\n* You need to use the decorator with parentheses all the time, even when you don't specify any arguments, so use `@omoide_cache()`, but not `@omoide_cache`. I honestly have no fucking idea why there's this weird behaviour in decorators, will do my best to fix it in future updates.\n\n# Links\nIn case you’d like to check my other work or contact me:\n* [Personal website](https://tekleo.net/)\n* [GitHub](https://github.com/jpleorx)\n* [PyPI](https://pypi.org/user/JPLeoRX/)\n* [DockerHub](https://hub.docker.com/u/jpleorx)\n* [Articles on Medium](https://medium.com/@leo.ertuna)\n* [LinkedIn (feel free to connect)](https://www.linkedin.com/in/leo-ertuna-14b539187/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpleorx%2Fomoide-cache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjpleorx%2Fomoide-cache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpleorx%2Fomoide-cache/lists"}