Documentation: https://py-cachify.readthedocs.io/latest/
Source Code: https://github.com/EzyGang/py-cachify
FastAPI Integration Guide: Repo
Py-Cachify is a robust library tailored for developers looking to enhance their Python applications with elegant caching and locking mechanisms. Whether you're building synchronous or asynchronous applications, Py-Cachify has you covered!
-
Flexible Caching: Effortlessly cache your function results, dramatically reducing execution time for expensive computations and I/O-bound tasks. Utilize customizable keys and time-to-live (TTL) parameters.
-
Distributed Locks: Ensure safe concurrent operation of functions with distributed locks. Prevent race conditions and manage shared resources effectively across both sync and async contexts.
-
Backend Agnostic: Easily integrate with different cache backends. Choose between in-memory, Redis, or any custom backend that adheres to the provided client interfaces.
-
Decorators for Ease: Use intuitive decorators like
@cached()
and@lock()
to wrap your functions, maintain clean code, and benefit from automatic cache management. -
Type Safety & Documentation: Fully type-annotated for enhanced IDE support and readability, featuring comprehensive documentation and examples to guide you through various use cases.
-
Production Ready: With 100% test coverage and usage in multiple commercial projects, Py-Cachify is trusted for production environments, ensuring reliability and stability for your applications.
$ pip install py-cachify
---> 100%
Successfully installed py-cachify
You can read more in-depth tutorials here.
First, to start working with the library, you will have to initialize it by using the provided init_cachify
function:
from py_cachify import init_cachify
init_cachify()
By default, it will use an in-memory cache.
If you want to use Redis:
from py_cachify import init_cachify
from redis.asyncio import from_url as async_from_url
from redis import from_url
init_cachify(sync_client=from_url(redis_url), async_client=async_from_url(async_redis_client))
Normally you wouldn't have to use both sync and async clients since an application usually works in a single mode i.e. sync/async.
Once initialized you can use everything that the library provides straight up without being worried about managing the cache yourself.
❗ If you forgot to call init_cachify
the CachifyInitError
will be raised during runtime.
Caching by using @cached
decorator utilizing the flexibility of a dynamic key:
# Cache the result of the following function with dynamic key
@cached(key='sum_two-{a}-{b}')
async def sum_two(a: int, b: int) -> int:
# Let's put print here to see what was the function called with
print(f'Called with {a} {b}')
return a + b
# Reset the cache for the call with arguments a=1, b=2
await sub_two.reset(a=1, b=2)
Read more about @cached
here.
Locking through context manager:
from py_cachify import lock
async_lock = lock('resource_key')
# Use it within an asynchronous context
async with async_lock:
# Your critical section here
print('Critical section code')
# Check if it's locked
await async_lock.is_alocked()
# Forcefully release
await async_lock.arelease()
# Use it within a synchronous context
with lock('resource_key'):
# Your critical section here
print('Critical section code')
Locking via decorator:
from py_cachify import lock
@lock(key='critical_function_lock-{arg}', nowait=False, timeout=10)
async def critical_function(arg: int) -> None:
# critical code
# Check if it's locked for arg=5
await critical_function.is_locked(arg=5)
# Forcefully release for arg=5
await critical_function.release(arg=5)
Read more about lock
here.
For a more detailed tutorial visit Tutorial or full API reference.
If you'd like to contribute, please first discuss the changes using Issues, and then don't hesitate to shoot a PR which will be reviewed shortly.
This project is licensed under the MIT License - see the LICENSE file for details.