Skip to content

feat: auto-detect backend from environment variables in DefaultBackendProvider #87

@27Bslash6

Description

@27Bslash6

Problem

DefaultBackendProvider always resolves to Redis regardless of which environment variables are set. Setting CACHEKIT_API_KEY has no effect unless you explicitly use @cache.io(), set_default_backend(CachekitIOBackend()), or pass backend=CachekitIOBackend().

This contradicts the "zero config" principle — a user who sets CACHEKIT_API_KEY clearly wants CachekitIO, but @cache.production silently ignores it and tries to connect to Redis.

Current Behavior

import os
os.environ["CACHEKIT_API_KEY"] = "ck_live_..."

@cache.production(ttl=300)
def get_product(product_id: str) -> dict: ...
# ❌ Tries to connect to Redis, not CachekitIO

Proposed Behavior

DefaultBackendProvider.get_backend() should resolve based on env var presence, with this priority:

  1. CACHEKIT_API_KEY set → CachekitIOBackend (managed service gets priority)
  2. CACHEKIT_REDIS_URL or REDIS_URL set → RedisBackend
  3. CACHEKIT_MEMCACHED_SERVERS set → MemcachedBackend
  4. Nothing set → L1 only (no backend, current zero-config behavior)
import os
os.environ["CACHEKIT_API_KEY"] = "ck_live_..."

@cache.production(ttl=300)
def get_product(product_id: str) -> dict: ...
# ✅ Auto-detects CachekitIO from CACHEKIT_API_KEY

Edge Cases

  • Both CACHEKIT_API_KEY and CACHEKIT_REDIS_URL set: CachekitIO wins (priority 1). Log a warning noting both are configured.
  • @cache.io() with no CACHEKIT_API_KEY: Should still raise ConfigurationError immediately (fail-fast, current behavior).
  • Explicit backend= parameter: Always takes precedence over auto-detection (current behavior, unchanged).
  • set_default_backend() called: Always takes precedence over auto-detection (current behavior, unchanged).

Impact

  • @cache.io() becomes a convenience alias that validates the key upfront, rather than the only way to use CachekitIO
  • All presets (@cache.production, @cache.secure, @cache.minimal, etc.) become genuinely backend-agnostic
  • Docs can honestly say "switch backends by changing an environment variable"

Files

  • src/cachekit/backends/provider.pyDefaultBackendProvider.get_backend()
  • src/cachekit/cache_handler.pyget_backend_provider()
  • Tests for priority resolution and edge cases

Context

Found while writing docs for docs.cachekit.io — the "Switching Backends" section originally claimed you could switch by swapping env vars, but that's not how DefaultBackendProvider works today.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions