Skip to content

Feature/key builder - #427

Open
seracoder wants to merge 3 commits into
Krukov:masterfrom
seracoder:feature/key-builder
Open

Feature/key builder#427
seracoder wants to merge 3 commits into
Krukov:masterfrom
seracoder:feature/key-builder

Conversation

@seracoder

Copy link
Copy Markdown
Contributor

Summary

Adds a key_builder parameter to all cache and rate-limiting decorators, allowing users to supply a custom callable (func, args, kwargs) -> str for cache key generation instead of relying on the template-based system. Closes #424.

Changes

New KeyBuilder protocol (cashews/_typing.py):

  • Callable[[Callable, tuple, dict], str] — receives the decorated function, positional args, and keyword args, returns the cache key string.

Core key resolution (cashews/key.py):

  • get_cache_key() accepts an optional key_builder. When provided, it short-circuits template formatting and delegates to the callable directly.

All cache strategy decorators updated with key_builder parameter:

  • cache, early, soft, failover, hit, iterator
  • locked, rate_limit, slice_rate_limit, circuit_breaker
  • bloom, dual_bloom

Wrapper methods (cashews/wrapper/decorators.py):

  • All public decorator methods thread key_builder through to the underlying decorator.

Design decisions

  • key and key_builder are mutually exclusive — raises ValueError if both are provided.
  • Tag registration is skipped when key_builder is used (tags require template-based key resolution for registration), but tag resolution at call time still works.
  • Thunder protection is skipped when key_builder is used (it relies on template-based key generation).
  • Lock key namespacing: when lock=True is combined with key_builder, the lock key is automatically prefixed with lock: to prevent collision with the cache key.

Usage

from cashews import cache

def my_key_builder(func, args, kwargs):
    return f"user:{kwargs['user_id']}"

@cache(ttl=60, key_builder=my_key_builder)
async def get_user(user_id, session=None):
    ...

Testing

  • 16 test functions (64 parametrized cases across memory, transactional, redis, and redis_cs backends) covering all decorators, mutual exclusivity, conditions, and lock interaction.
  • Full existing test suite passes with zero regressions (1320+ tests).

seracoder added 3 commits May 3, 2026 12:44
Add support for a callable key_builder(func, args, kwargs) -> str as an
alternative to template-based key generation. The key_builder and key
parameters are mutually exclusive. Closes Krukov#424.
…ock=True

When key_builder bypasses the template system, both lock and cache
decorators received the same raw key, causing set_lock to overwrite
cached values. Fix by prefixing lock key_builder output with 'lock:'.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add key_builder support for @cache decorator

1 participant