Caching

class alchemiq.CacheBackend(*args, **kwargs)[source]

Bases: Protocol

Structural protocol for cache backends.

Implemented by InMemoryCache (core, no extra) and RedisCache (requires the [redis] extra, built automatically by configure_cache() when a Redis url is supplied).

Any object that exposes default_ttl, namespace, and the five async methods below satisfies this protocol (isinstance check via @runtime_checkable).

See also

configure_cache() - register a backend process-globally.

async get(key)[source]

Return the cached string, or None on miss or expiry.

Parameters:

key (str)

Return type:

str | None

async set(key, value, *, ttl)[source]

Store value under key with a TTL in seconds.

Parameters:
Return type:

None

async delete(*keys)[source]

Delete one or more keys; no-ops on missing keys.

Parameters:

keys (str)

Return type:

None

async incr(key)[source]

Atomically increment an integer counter and return the new value.

Parameters:

key (str)

Return type:

int

async scan_delete(match)[source]

Delete all keys matching a glob pattern.

Parameters:

match (str)

Return type:

None

class alchemiq.InMemoryCache(*, default_ttl=60, namespace='aq')[source]

Bases: object

Pure-Python CacheBackend for tests and small single-process apps.

Backed by a plain dict; no external dependencies. TTL is enforced lazily on get. Counter keys (used by the version-invalidation scheme) never expire.

E.g.:

from alchemiq.cache import InMemoryCache, configure_cache

configure_cache(backend=InMemoryCache(default_ttl=120, namespace="myapp"))

Note

Not safe for use across multiple processes or workers - use configure_cache() with a Redis url for multi-process deployments.

Parameters:
  • default_ttl (int)

  • namespace (str)

async get(key)[source]

Return the cached value, or None on miss or TTL expiry (lazy eviction).

Parameters:

key (str)

Return type:

str | None

async set(key, value, *, ttl)[source]

Store value under key; a zero TTL means no expiry.

Parameters:
Return type:

None

async delete(*keys)[source]

Remove one or more keys; silently ignores missing keys.

Parameters:

keys (str)

Return type:

None

async incr(key)[source]

Increment an integer counter, starting at 1 for a new key; never expires.

Parameters:

key (str)

Return type:

int

async scan_delete(match)[source]

Delete all keys matching a glob pattern.

Parameters:

match (str)

Return type:

None

alchemiq.configure_cache(url=None, *, backend=None, default_ttl=60, namespace='aq', **redis_kw)[source]

Set the process-global cache backend.

Pass an explicit backend instance, or a Redis connection url (requires the [redis] extra). Only one may be provided. Call reset_cache() to clear the global backend (useful in tests).

E.g.:

from alchemiq.cache import InMemoryCache, configure_cache, reset_cache

# in-process cache (no dependencies):
configure_cache(backend=InMemoryCache(default_ttl=120))

# Redis (requires [redis] extra):
configure_cache(url="redis://localhost:6379/0")
Parameters:
  • url (str | None) – Redis connection URL; builds a CacheBackend backed by redis.asyncio. Requires pip install 'alchemiq[redis]'.

  • backend (CacheBackend | None) – A CacheBackend instance to use directly. When given, default_ttl and namespace are ignored.

  • default_ttl (int) – Default TTL in seconds for Redis-built backends (default 60).

  • namespace (str) – Key prefix for Redis-built backends (default "aq").

  • redis_kw (Any)

Raises:
  • ConfigError – if neither url nor backend is provided.

  • ImportError – if url is given but the [redis] extra is not installed.

Return type:

None

See also

InMemoryCache - zero-dependency backend for tests.

alchemiq.reset_cache()[source]

Clear the global cache backend.

Intended for teardown and test isolation. Mirrors runtime.dispose().

Return type:

None