Skip to main content

ddredis

pypi downloads versions codecov license

Redis helpers: generic JSON cache and distributed lock

Installation

Install the library using pip:

pip install ddredis

Development

The project runs entirely in Docker. Requires Docker and Fabric on the host:

fab build      # build the dev image
fab tests      # run pytest
fab linters    # run ruff (with --fix), ty and complexipy
fab shell      # IPython inside the container
fab bash       # bash inside the container

This project was generated from dd-lib-stub; run copier update to pull in template updates.

GenericCache

Caches domain objects in Redis as JSON. The domain class must provide model_validate_json and model_dump_json (pydantic models do), keys are prefixed with the snake-cased domain name, every entry gets the class ttl with ±10% jitter so a burst of writes does not expire at once, and Redis errors turn into "not found" instead of failing the caller.

from typing import ClassVar

from pydantic import BaseModel
from redis.asyncio import Redis

from ddredis.cache import GenericCache

redis_client = Redis.from_url('redis://localhost/0')


class Profile(BaseModel):
    profile_id: int
    name: str


class ProfileCache(GenericCache[Profile]):
    ttl = 10 * 60  # seconds
    redis_client: ClassVar[Redis] = redis_client


cache = ProfileCache()

await cache.create(key=1, value=Profile(profile_id=1, name='John'))   # SET :profile:1 ... EX ttl±10%
profile = await cache.get(key=1)                                       # Profile | None
await cache.update(key=1, value=profile)                               # alias for create
await cache.delete(key=1)

await cache.get_list(key_prefix='team-a')                              # every :profile:team-a* entry
await cache.delete_by_filters(key_prefix='team-a')

Redis errors are swallowed on purpose: for a cache, "unavailable" and "miss" lead to the same fallback. Do not use the cache for state where None has a meaning of its own. Transient failures (a worker that was just reloaded, a dropped connection) belong to the client, not to the cache: redis-py retries the errors listed in retry_on_error with its default Retry (3 attempts, exponential backoff with jitter), so a production client looks like this:

from redis.asyncio import Redis
from redis.exceptions import ConnectionError, TimeoutError

redis_client = Redis.from_url(
    'redis://localhost/0',
    max_connections=20,
    socket_connect_timeout=5,
    socket_timeout=1,
    retry_on_error=[ConnectionError, TimeoutError],
    decode_responses=True,
)

RedisLock

Distributed lock on SET NX PX with a Lua release (redis-py's Lock, thread_local=False). Acquiring a held lock raises AlreadyAcquiredError unless blocking=True, in which case it waits up to timeout.

from ddredis.lock import AlreadyAcquiredError, RedisLock

try:
    async with RedisLock(redis_client, 'sync-profiles', timeout=30):
        await sync_profiles()
except AlreadyAcquiredError:
    pass  # another worker is on it

timeout is the Redis-side TTL of the key, not a client-side cancellation: if the block runs longer, Redis drops the key and a competitor may enter while the first holder is still running. Pick a timeout that comfortably exceeds the worst-case runtime, or call extend() periodically as a heartbeat. extend() replaces the TTL with the full timeout counted from now rather than adding to the remaining time, so a long-lived holder beating steadily never pushes its expiry further out. release() tolerates a lock that already expired.

suppress_redis_errors

Decorator for async functions: RedisError subclasses become a None result, everything else propagates. GenericCache methods use it; apply it to your own Redis reads that should degrade instead of failing.

Metadata

Release files for ddredis 0.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ddredis 0.0.3
File Size Uploaded
ddredis-0.0.3.tar.gz 6.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ddredis 0.0.3
File Interpreter ABI Platform
ddredis-0.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 14.4 kB

Release files / ddredis-0.0.3.tar.gz

Download URL ddredis-0.0.3.tar.gz
Size 6.4 kB
Tags Source
SHA-256 checksum
How to use checksums
1aec795e184eced6cc6b399064c2532c431c108a542186b5bafe93e09cd8e7fa
BLAKE2b-256 checksum
How to use checksums
c0ead4e0d0ef22c7b0706e60e4fda97d6fdef4f4903249f563e0af7b31429f80
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / ddredis-0.0.3-py3-none-any.whl

Download URL ddredis-0.0.3-py3-none-any.whl
Size 8.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7adf4a8efcdab7c79f9fc277a5b3685b3fd465596a28e30c43abaf56bc127dda
BLAKE2b-256 checksum
How to use checksums
63093844edd5ecdc35f8603a50eedeb450a593b216368d08a5af0d2af52e1ecd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.0

2 release files

This release

0.0.3 This release

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page