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-cachifyYou 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.
 
