Caching 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!
Released Library: PyPI
Source Code: GitHub
Tutorial №1: my blog or Medium
This is a robust, highly tunable and easy-to-integrate in-memory cache solution written in pure Python, with no dependencies.
It 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.
Customizable to suit your specific use-case, provides various expiry and refresh options.
Very 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.
Fair 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!
pip install omoide-cachegit clone https://github.com/jpleorx/omoide-cache.git
cd omoide-cache
pip install --editable .import time
from omoide_cache import omoide_cache
# A class where cache was added to a simulated long running method
class ExampleService:
@omoide_cache()
def time_consuming_method(self, x: int) -> int:
time.sleep(2.0)
return x * x
service = ExampleService()
# The first call will execute real logic and store the result in cache
service.time_consuming_method(1)
# The second call will get results from cache
service.time_consuming_method(1)Here we add a cache that will drop an item least frequently accessed when the cache becomes too large.
import time
from omoide_cache import omoide_cache, ExpireMode
class ExampleService:
@omoide_cache(max_allowed_size=10, size_expire_mode=ExpireMode.ACCESS_COUNT_BASED)
def time_consuming_method(self, x: int) -> int:
time.sleep(2.0)
return x * xHere the cache will automatically remove items that were last accessed more than 2 minutes ago.
import time
from omoide_cache import omoide_cache
class ExampleService:
@omoide_cache(expire_by_access_duration_s=120)
def time_consuming_method(self, x: int) -> int:
time.sleep(2.0)
return x * xAlternatively we can remove items that were computed more than 2 minutes ago.
import time
from omoide_cache import omoide_cache
class ExampleService:
@omoide_cache(expire_by_computed_duration_s=120)
def time_consuming_method(self, x: int) -> int:
time.sleep(2.0)
return x * xHere the cache will asynchronously refresh items that were computed more than 2 minutes ago. Attempt to refresh will be performed every 10 seconds.
import time
from omoide_cache import omoide_cache, RefreshMode
class ExampleService:
@omoide_cache(refresh_duration_s=120, refresh_period_s=10, refresh_mode=RefreshMode.INDEPENDENT)
def time_consuming_method(self, x: int) -> int:
time.sleep(2.0)
return x * x@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.In case you’d like to check my other work or contact me: