AsyncCacheAdapter

class privex.helpers.cache.asyncx.base.AsyncCacheAdapter(*args, enter_reconnect: Optional[bool] = None, exit_close: Optional[bool] = None, **kwargs)[source]

AsyncCacheAdapter is an abstract base class based on CacheAdapter, but with all methods designated as coroutines.

Cache adapters which make use of AsyncIO, including via asyncio compatible libraries (e.g. aioredis), should use this class as their parent instead of CacheAdapter.

To retain the functionality of __getitem__() and __setitem__(), it obtains an event loop using asyncio.get_event_loop(), and then wraps get() or set() respectively using loop.run_until_complete to be able to run them within the synchronous get/setitem magic methods.

It overrides get_or_set() to convert it into an async method, and overrides get_or_set_async() so that get() and set() are correctly awaited within the method.

__init__(*args, enter_reconnect: Optional[bool] = None, exit_close: Optional[bool] = None, **kwargs)[source]

Initialize self. See help(type(self)) for accurate signature.

adapter_enter_reconnect: bool = True

Controls whether __aenter__() automatically calls reconnect() to clear and re-create any previous connections/instances for the adapter.

adapter_exit_close: bool = True

Controls whether __aexit__() automatically calls close() to close any connections/instances and destroy library class instances from the current adapter instance.

async close(*args, **kwargs) → Any[source]

Close any cache library connections, and destroy their local class instances by setting them to None.

async connect(*args, **kwargs) → Any[source]

Create an instance of the library used to interact with the caching system, ensure it’s connection is open, and store the instance on this class instance - only if not already connected.

Should return the class instance which was created.

abstract async get(key: str, default: Any = None, fail: bool = False) → Any[source]

Return the value of cache key key. If the key wasn’t found, or it was expired, then default will be returned.

Optionally, you may choose to pass fail=True, which will cause this method to raise CacheNotFound instead of returning default when a key is non-existent / expired.

Parameters
  • key (str) – The cache key (as a string) to get the value for, e.g. example:test

  • default (Any) – If the cache key key isn’t found / is expired, return this value (Default: None)

  • fail (bool) – If set to True, will raise CacheNotFound instead of returning default when a key is non-existent / expired.

Raises

CacheNotFound – Raised when fail=True and key was not found in cache / expired.

Return Any value

The value of the cache key key, or default if it wasn’t found.

async get_or_set(key: str, value: Union[Any, callable, Coroutine, Awaitable], timeout: int = 300) → Any[source]

Attempt to return the value of key in the cache. If key doesn’t exist or is expired, then it will be set to value, and value will be returned.

The value parameter can be any standard type such as str or dict - or it can be a callable function / method which returns the value to set and return.

Basic Usage:

>>> c = CacheAdapter()
>>> c.get('testing')
None
>>> c.get_or_set('testing', 'hello world')
'hello world'
>>> c.get('testing')
'hello world'

Set and get the value from a function if ``key`` didn’t exist / was expired:

>>> def my_func(key): return "hello {} world".format(key)
>>> c = CacheAdapter()
>>> c.get_or_set('example', my_func)
'hello example world'
>>> c.get('example')
'hello example world'
Parameters
  • key (str) – The cache key (as a string) to get/set the value for, e.g. example:test

  • value (Any) – The value to store in the cache key key. Can be a standard type, or a callable function.

  • timeout (int) – The amount of seconds to keep the data in cache. Pass None to disable expiration.

Return Any value

The value of the cache key key, or value if it wasn’t found.

async get_or_set_async(key: str, value: Union[Any, callable, Coroutine, Awaitable], timeout: int = 300) → Any[source]

Async coroutine compatible version of get_or_set().

Example with Async function:

>>> async def my_coro(key): return f"hello {key} world"
>>> c = CacheAdapter()
>>> await c.get_or_set_async('coro_example', my_coro)
'hello example world'
>>> c.get('coro_example')
'hello example world'

Also works with non-async functions:

>>> def my_func(key): return f"hello {key} world"
>>> await c.get_or_set_async('func_example', my_func)
'hello example world'
>>> c.get('func_example')
'hello example world'
Parameters
  • key (str) – The cache key (as a string) to get/set the value for, e.g. example:test

  • value (Any) – The value to store in the cache key key. Can be a standard type, a coroutine / awaitable, or a plain callable function.

  • timeout (int) – The amount of seconds to keep the data in cache. Pass None to disable expiration.

Return Any value

The value of the cache key key, or value if it wasn’t found.

ins_enter_reconnect: bool

Per-instance version of adapter_enter_reconnect, which is set via enter_reconnect the constructor. When __init__ enter_reconnect is empty, it inherits the class attribute value from adapter_enter_reconnect

ins_exit_close: bool

Per-instance version of adapter_exit_close, which is set via exit_close the constructor. When __init__ exit_close is empty, it inherits the class attribute value from adapter_exit_close

async reconnect(*args, **kwargs) → Any[source]

Calls close() to close any previous connections and cleanup instances, then re-create the connection(s)/instance(s) by calling connect()

abstract async remove(*key: str)bool[source]

Remove one or more keys from the cache.

If all cache keys existed before removal, True will be returned. If some didn’t exist (and thus couldn’t remove), then False will be returned.

Parameters

key (str) – The cache key(s) to remove

Return bool removed

True if key existed and was removed

Return bool removed

False if key didn’t exist, and no action was taken.

abstract async set(key: str, value: Any, timeout: Optional[int] = 300)[source]

Set the cache key key to the value value, and automatically expire the key after timeout seconds from now.

If timeout is None, then the key will never expire (unless the cache implementation loses it’s persistence, e.g. memory caches with no disk writes).

Parameters
  • key (str) – The cache key (as a string) to set the value for, e.g. example:test

  • value (Any) – The value to store in the cache key key

  • timeout (int) – The amount of seconds to keep the data in cache. Pass None to disable expiration.

abstract async update_timeout(key: str, timeout: int = 300) → Any[source]

Update the timeout for a given key to datetime.utcnow() + timedelta(seconds=timeout)

This method should accept keys which are already expired, allowing expired cache keys to have their timeout extended after expiry.

Example:

>>> c = CacheAdapter()
>>> c.set('example', 'test', timeout=60)
>>> sleep(70)
>>> c.update_timeout('example', timeout=60)   # Reset the timeout for ``'example'`` to ``now + 60 seconds``
>>> c.get('example')
'test'
Parameters
  • key (str) – The cache key to update the timeout for

  • timeout (int) – Reset the timeout to this many seconds from datetime.utcnow()

Raises

CacheNotFound – Raised when key was not found in cache (thus cannot extend timeout)

Return Any value

The value of the cache key