Skip to main content

cache tools with async power

Project description

CASHEWS 🥔

Async cache utils with simple api to build fast and reliable applications

pip install cashews[redis]

Why

Cache plays significant role in modern applications and everybody wanna use all power of async programming and cache.. There are a few advance techniques with cache and async programming that can help you to build simple, fast, scalable and reliable applications. Caches

Features

  • Decorator base api, just decorate and play
  • Cache invalidation by time, 'ttl' a required parameter to avoid storage overflow and endless cache
  • Support Multi backend (Memory, Redis, memcache by request)
  • Can cache any objects securely with pickle (use hash key).
  • Simple configuring and API

API

Usage

Configure

Cache object is a single object that can be configured in one place by url::

from cashews import cache

cache.setup("redis://0.0.0.0/?db=1&create_connection_timeout=0.5&safe=0&hash_key=my_sicret&enable=1")
or
cache.setup("redis://0.0.0.0/", db=1, create_connection_timeout=0.5, safe=False, hash_key=b"my_key", enable=True)
or
cache.setup("mem://") # for inmemory cache

if you dont like global objects or prefer more manageable way you can work with cache class

from cashews import Cache

cache = Cache()
cache.setup("mem://")

Simple cache

Typical cache strategy: execute, store and return cached value till expiration::

from cashews import cache
from datetime import timedelta

@cache(ttl=timedelta(hours=3))
def long_running_function(arg, kward):
    ...

:param ttl: seconds in int value or as timedelta object to define time to store objects :param func_args: arguments of call that will be used in key, can be tuple or dict with argument name as a key and callable object as a transform function for value of this argument

@cache(ttl=100, func_args=("arg", "token"))
def long_running_function(arg, user: User, token: str = "token"):
    ...

long_running_function("name", user=user, token="qdfrevt")  # key will be like "long_running_function:arg:name:token:qdfrevt

But what if we want to user argument define a cache key or want to hide token from cache

@cache(ttl=100, func_args={"arg": True, "token": get_md5, "user": attrgetter("uid")})
def long_running_function(arg, user: User, token: str = "token"):
    ...

long_running_function("name", user=user, token="qdfrevt")  # key will be like "long_running_function:arg:name:token:7ea802f0544ff108aace43e2d3752a28:user:51e6da60-2553-45ec-9e56-d9538b9614c8

:param key: custom cache key, may contain alias to args or kwargs passed to a call (like 'key_{token}/{arg}{user}') :param condition: callable object that determines whether the result will be saved or not :param prefix: custom prefix for key

Fail cache

Return cache result (at list 1 call of function call should be succeed) if call raised one of the given exceptions,

:param ttl: seconds in int or as timedelta object to store a result :param exceptions: exceptions at which returned cache result :param func_args: see simple cache params :param key: custom cache key, may contain alias to args or kwargs passed to a call :param prefix: custom prefix for key, default "fail"

Example

from cashews import cache  # or from cashews import fail

@cache.fail(ttl=timedelta(hours=2))
async def get(name):
    value = await api_call()
    return {"status": value}

Hit cache

Cache call results and drop cache after given numbers of call 'cache_hits'

:param ttl: seconds in int or as timedelta object to store a result :param cache_hits: number of cache hits till cache will dropped :param update_before: number of cache hits before cache will update :param func_args: see simple cache params :param key: custom cache key, may contain alias to args or kwargs passed to a call :param condition: callable object that determines whether the result will be saved or not :param prefix: custom prefix for key, default "hit"

Example

from cashews import cache  # or from cashews import hit

@cache.hit(ttl=timedelta(hours=2), cache_hits=100, update_before=2)
async def get(name):
    ...

Performance downgrade cache

Trace time execution of target and enable cache if it downgrade to given condition

:param ttl: seconds in int or as timedelta object to store a result :param func_args: see simple cache params :param key: custom cache key, may contain alias to args or kwargs passed to a call :param trace_size: the number of calls that are involved :param perf_condition: callable object that determines whether the result will be cached, default if doubled mean value of time execution less then current :param prefix: custom prefix for key, default 'perf'

from cashews import cache   # or from cashews import perf

@cache.perf(ttl=timedelta(hours=2))
async def get(name):
    value = await api_call()
    return {"status": value}

Locked

Cache strategy that try to solve Cache stampede problem (https://en.wikipedia.org/wiki/Cache_stampede), Lock following function calls till it be cached Can guarantee one function call for given ttl

:param ttl: seconds in int or timedelta object to store a result :param func_args: see simple cache params :param key: custom cache key, may contain alias to args or kwargs passed to a call :param lock_ttl: seconds in int or timedelta object to lock wrapped function call (should be more than function execution time) :param prefix: custom prefix for key, default 'early'

from cashews import cache  # or from cashews import locked

@cache.locked(ttl=timedelta(minutes=10))
async def get(name):
    value = await api_call()
    return {"status": value}

Early

Cache strategy that try to solve Cache stampede problem (https://en.wikipedia.org/wiki/Cache_stampede), With a hot cache recalculate a result in background near expiration time Warning! Not good at cold cache

:param ttl: seconds in int or as timedelta object to store a result :param func_args: see simple cache params :param key: custom cache key, may contain alias to args or kwargs passed to a call :param condition: callable object that determines whether the result will be saved or not :param prefix: custom prefix for key, default 'early'

Rate limit

Rate limit for function call. Do not call function if rate limit is reached, and call given action

:param limit: number of calls :param period: Period :param ttl: time to ban, default == period :param func_args: see simple cache params :param action: call when rate limit reached, default raise RateLimitException :param prefix: custom prefix for key, default 'rate_limit'

from cashews import cache  # or from cashews import rate_limit

# no more then 10 calls per minute or ban for 10 minutes
@cache.rate_limit(limit=10, period=timedelta(minutes=1) ttl=timedelta(minutes=10))
async def get(name):
    return {"status": value}

Basic api

There are 11 basic methods to work with key-storage::

from cashews import cache

cache.setup("mem://")

await cache.set(key="key", value={"any": True}, expire=60, exist=None)  # -> bool
await cache.get("key")  # -> Any
await cache.incr("key") # -> int
await cache.delete("key")
await cache.expire("key", timeout=10)
await cache.ping(message=None)  # -> bytes
await cache.clear()
await cache.set_lock("key", value="value", expire=60)  # -> bool
await cache.is_locked("key", wait=60)  # -> bool
await cache.unlock("key", "value")  # -> bool
async with cache.lock("key", expire=10):

todos:

cache invalidation solution

Project details


Release history Release notifications | RSS feed

This version

0.2.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cashews-0.2.0.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cashews-0.2.0-py3-none-any.whl (24.0 kB view details)

Uploaded Python 3

File details

Details for the file cashews-0.2.0.tar.gz.

File metadata

  • Download URL: cashews-0.2.0.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/42.0.2 requests-toolbelt/0.9.1 tqdm/4.40.2 CPython/3.7.5

File hashes

Hashes for cashews-0.2.0.tar.gz
Algorithm Hash digest
SHA256 f96914c2dfa03668b38ec791ca63b22bd7bab3e43442f9fe4c5d397ee9671ab3
MD5 79d9990a414ef62e2bed72c6be8c9a8e
BLAKE2b-256 75fb41b0beab8d3c649a8f4370ccf7c98eed7c25021edd9440d65df95a4bea8c

See more details on using hashes here.

File details

Details for the file cashews-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: cashews-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 24.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/42.0.2 requests-toolbelt/0.9.1 tqdm/4.40.2 CPython/3.7.5

File hashes

Hashes for cashews-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 04ae14ce7e8dfacc4b65cbec040a2001ba8cb5ab07f2ddee30413dd9a869cea6
MD5 d8691e0f558378b5b81b7c59a2f6ec09
BLAKE2b-256 dd9b2e93ef35cb331a5722d4c989164efa4d2a01c18389c54c2df0c0fd58b540

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page