Skip to content

Backends

AbstractBackend

memory_reuse.backends.base.AbstractBackend

Bases: ABC

Interface that all cache backends must implement.

Every method is a coroutine so that network-bound backends (e.g. Redis) can be awaited without blocking the event loop, while the in-memory backend simply returns immediately.

Implementors should document their own connection-lifecycle behaviour (lazy vs eager connection, reconnect logic, etc.).

get abstractmethod async

get(key: str) -> bytes | None

Retrieve the raw bytes stored under key.

Parameters:

Name Type Description Default
key str

The cache key to look up.

required

Returns:

Type Description
bytes | None

The stored bytes, or None if the key does not exist or has

bytes | None

expired.

set abstractmethod async

set(key: str, value: bytes, ttl: int | None = None) -> None

Store value under key.

Parameters:

Name Type Description Default
key str

The cache key.

required
value bytes

Raw bytes to store (typically gzip-compressed JSON).

required
ttl int | None

Time-to-live in seconds. None means the entry never expires. A backend may ignore this if it does not support TTL.

None

delete abstractmethod async

delete(key: str) -> None

Remove the entry for key if it exists.

Parameters:

Name Type Description Default
key str

The cache key to remove. A no-op if the key does not exist.

required

exists abstractmethod async

exists(key: str) -> bool

Check whether a non-expired entry exists for key.

Parameters:

Name Type Description Default
key str

The cache key to check.

required

Returns:

Type Description
bool

True if the key exists and has not expired, False

bool

otherwise.

flush abstractmethod async

flush() -> None

Delete all entries managed by this backend instance.

Use with caution in production — this removes every cached value.

ping abstractmethod async

ping() -> bool

Check backend connectivity.

Returns:

Type Description
bool

True if the backend is reachable and functioning, False

bool

otherwise. Should not raise.

InMemoryBackend

memory_reuse.backends.memory.InMemoryBackend

InMemoryBackend(max_entries: int = _DEFAULT_MAX_ENTRIES)

Bases: AbstractBackend

Fully in-memory cache backend — no external dependencies required.

Features:

  • TTL — entries are lazily expired on access.
  • LRU eviction — when max_entries is reached the least-recently-used entry is dropped to make room for the new one.
  • Thread-safe — an :class:asyncio.Lock serialises all mutations.

Parameters:

Name Type Description Default
max_entries int

Maximum number of entries to hold before LRU eviction kicks in. Defaults to 10 000.

_DEFAULT_MAX_ENTRIES

Example::

backend = InMemoryBackend(max_entries=500)
await backend.set("key", b"value", ttl=60)
data = await backend.get("key")

size property

size: int

Current number of entries in the store (including not-yet-evicted expired ones).

Returns:

Type Description
int

Integer entry count.

get async

get(key: str) -> bytes | None

Return stored bytes for key, or None on miss/expiry.

Parameters:

Name Type Description Default
key str

Cache key to look up.

required

Returns:

Type Description
bytes | None

Stored bytes or None.

set async

set(key: str, value: bytes, ttl: int | None = None) -> None

Store value under key with an optional TTL.

If the store is at capacity, the LRU entry is evicted first.

Parameters:

Name Type Description Default
key str

Cache key.

required
value bytes

Bytes to store.

required
ttl int | None

Time-to-live in seconds. None means no expiry.

None

delete async

delete(key: str) -> None

Remove the entry for key.

Parameters:

Name Type Description Default
key str

Cache key to remove. No-op if the key does not exist.

required

exists async

exists(key: str) -> bool

Return True if key exists and has not expired.

Parameters:

Name Type Description Default
key str

Cache key to check.

required

Returns:

Type Description
bool

Boolean existence flag.

flush async

flush() -> None

Remove all entries from the store.

ping async

ping() -> bool

Always returns True — the in-memory backend is always available.

Returns:

Type Description
bool

True

RedisBackend

Requires the redis extra (pip install "memory-reuse[redis]").

memory_reuse.backends.redis.RedisBackend

RedisBackend(url: str, max_connections: int = _MAX_CONNECTIONS, *, key_prefix: str | None = None)

Bases: AbstractBackend

Cache backend that stores data in Redis.

Requires the optional redis extra::

pip install memory-reuse[redis]

The connection is established lazily on the first operation. Connection errors are converted to :exc:BackendConnectionError so callers do not need to handle redis-specific exceptions.

Parameters:

Name Type Description Default
url str

Redis connection URL (e.g. redis://localhost:6379/0). Prefer reading this from the MEMORY_REUSE_REDIS_URL environment variable rather than hardcoding it.

required
max_connections int

Maximum size of the underlying connection pool. Defaults to 20.

_MAX_CONNECTIONS

Example::

import os
backend = RedisBackend(url=os.environ["MEMORY_REUSE_REDIS_URL"])
await backend.set("key", b"value", ttl=300)
data = await backend.get("key")

get async

get(key: str) -> bytes | None

Retrieve raw bytes stored under key.

Parameters:

Name Type Description Default
key str

Cache key.

required

Returns:

Type Description
bytes | None

Stored bytes or None on miss.

Raises:

Type Description
BackendConnectionError

On Redis connectivity failure.

set async

set(key: str, value: bytes, ttl: int | None = None) -> None

Store value under key.

Parameters:

Name Type Description Default
key str

Cache key.

required
value bytes

Bytes to store.

required
ttl int | None

Time-to-live in seconds. None means no expiry.

None

Raises:

Type Description
BackendConnectionError

On Redis connectivity failure.

delete async

delete(key: str) -> None

Remove the entry for key.

Parameters:

Name Type Description Default
key str

Cache key to remove.

required

Raises:

Type Description
BackendConnectionError

On Redis connectivity failure.

exists async

exists(key: str) -> bool

Check whether key exists in Redis.

Parameters:

Name Type Description Default
key str

Cache key.

required

Returns:

Type Description
bool

True if the key exists (and has not expired in Redis).

Raises:

Type Description
BackendConnectionError

On Redis connectivity failure.

flush async

flush() -> None

Delete only this cache's keys from the current Redis database.

Unlike a raw FLUSHDB, this removes only keys under the configured key prefix (<key_prefix>:*), using a non-blocking SCAN cursor and batched DELETE / UNLINK so unrelated application keys — and the keys of another cache instance sharing the same database — are never touched. TTLs on surviving keys are unaffected.

When no key prefix was supplied to the backend this is a safe no-op (it refuses to guess a scope rather than risk deleting unrelated data); use :meth:flush_database for the explicit, unrestricted FLUSHDB.

Raises:

Type Description
BackendConnectionError

On Redis connectivity failure.

flush_database async

flush_database() -> None

Delete every key in the current Redis database via FLUSHDB.

Warning

This is the unrestricted, destructive flush — it removes all keys in the connected database, including unrelated application data. Prefer :meth:flush, which only clears this cache's namespace. Provided for callers that genuinely own a dedicated database and want the fast, atomic clear.

Raises:

Type Description
BackendConnectionError

On Redis connectivity failure.

ping async

ping() -> bool

Check Redis connectivity.

Returns:

Type Description
bool

True if Redis responds to PING, False on any error.

close async

close() -> None

Close the connection pool gracefully.

Call this during application shutdown to release Redis connections.

acquire_lock async

acquire_lock(key: str, token: str, ttl_ms: int) -> bool

Attempt to acquire a per-key lock with an expiry (SET NX PX).

Parameters:

Name Type Description Default
key str

The lock key.

required
token str

A unique token identifying this holder, checked on release.

required
ttl_ms int

Lock expiry in milliseconds so a crashed holder cannot deadlock other processes.

required

Returns:

Type Description
bool

True if the lock was acquired, False if already held.

Raises:

Type Description
BackendConnectionError

On Redis connectivity failure.

release_lock async

release_lock(key: str, token: str) -> None

Release a per-key lock, but only if this holder still owns it.

Uses a delete-if-owner Lua script so a lock that already expired and was re-acquired by a different holder is never released by mistake. Failures are swallowed — a lock left to expire on its own is safe.

Parameters:

Name Type Description Default
key str

The lock key.

required
token str

The token supplied at acquire time.

required

AgentCoreBackend

Requires the agentcore extra (pip install "memory-reuse[agentcore]").

memory_reuse.backends.agentcore.AgentCoreSettings dataclass

AgentCoreSettings(region: str | None = None, memory_id: str | None = None, key_prefix: str = 'memory-reuse:')

Resolved connection settings for the AgentCore backend.

Attributes:

Name Type Description
region str | None

The AWS region hosting the AgentCore store.

memory_id str | None

The AgentCore memory / store resource identifier.

key_prefix str

Optional namespace prepended to every managed item id so that flush only removes entries this backend manages. Defaults to "memory-reuse:".

memory_reuse.backends.agentcore.AgentCoreBackend

AgentCoreBackend(settings: AgentCoreSettings, *, client: Any | None = None)

Bases: AbstractBackend

:class:AbstractBackend backed by AWS AgentCore Memory.

Because storage is the managed AgentCore service, a value set in one execution environment is visible to a get in another (Req 8.2).

Values are stored as raw bytes, base64-encoded on write and decoded on read, so any 0..1_048_576-byte payload round-trips unchanged (Req 8.5). A ttl greater than zero is recorded as an absolute expiry and filtered lazily on read; a missing or zero ttl persists until the entry is explicitly deleted or flushed (Req 8.3).

Parameters:

Name Type Description Default
settings AgentCoreSettings

Resolved connection settings (region, memory id, key prefix).

required
client Any | None

An already-constructed AgentCore client. When None a real client is created lazily via :func:_require_agentcore. Tests inject an in-process fake client here.

None

Example::

backend = AgentCoreBackend(
    AgentCoreSettings(region="us-east-1", memory_id="mem-123")
)
await backend.set("key", b"value", ttl=300)
data = await backend.get("key")

get async

get(key: str) -> bytes | None

Return stored bytes for key or None on miss/expiry.

Parameters:

Name Type Description Default
key str

Cache key to look up.

required

Returns:

Type Description
bytes | None

The stored bytes, or None if absent or expired.

Raises:

Type Description
BackendConnectionError

If the AgentCore service is unreachable.

set async

set(key: str, value: bytes, ttl: int | None = None) -> None

Store value under key with an optional TTL.

Parameters:

Name Type Description Default
key str

Cache key.

required
value bytes

Raw bytes to store.

required
ttl int | None

Time-to-live in seconds. None or 0 means no expiry.

None

Raises:

Type Description
ValueError

If key is empty or larger than 512 bytes.

BackendConnectionError

If the AgentCore service is unreachable.

delete async

delete(key: str) -> None

Remove the entry for key; a no-op when the key is absent.

Parameters:

Name Type Description Default
key str

Cache key to remove.

required

Raises:

Type Description
BackendConnectionError

If the AgentCore service is unreachable.

exists async

exists(key: str) -> bool

Return True only for an unexpired entry under key.

Parameters:

Name Type Description Default
key str

Cache key to check.

required

Returns:

Type Description
bool

True if an unexpired entry exists, False otherwise.

Raises:

Type Description
BackendConnectionError

If the AgentCore service is unreachable.

flush async

flush() -> None

Remove every entry this backend manages (namespaced by prefix).

Raises:

Type Description
BackendConnectionError

If the AgentCore service is unreachable.

ping async

ping() -> bool

Return True when the AgentCore service is reachable.

Returns:

Type Description
bool

True if reachable, False otherwise. Never raises.