Skip to content
GitHubDiscord

Cache (lexigram-cache)

Multi-backend caching system for Lexigram Framework — Redis, Memcached, and in-memory caching.


Multi-backend async caching for the Lexigram Framework. Supports Redis, in-memory, and Memcached backends with stampede protection, circuit breaker, Result-aware caching, and domain model round-trip serialization.

Configure backends via CacheModule.configure() and inject CacheBackendProtocol into any service. The @cacheable decorator provides cache-aside logic with automatic key generation and Result support.

Terminal window
uv add lexigram-cache
# Optional extras
uv add "lexigram-cache[redis,memcached,semantic]"
from lexigram import Application
from lexigram.di.module import Module, module
from lexigram.cache import CacheModule, CacheConfig
from lexigram.cache.config import CacheBackendConfig
from lexigram.cache.types import BackendType
from lexigram.contracts.infra.cache import CacheBackendProtocol
@module(imports=[
CacheModule.configure(
CacheConfig(
backends=[
CacheBackendConfig(
name="default",
type=BackendType.REDIS,
default=True,
redis_url="redis://localhost:6379/0",
)
]
)
)
])
class AppModule(Module):
pass
async def main():
async with Application.boot(modules=[AppModule]) as app:
cache = await app.container.resolve(CacheBackendProtocol)
await cache.set("greeting", "hello", ttl=60)
value = await cache.get("greeting")
print(value) # "hello"
if __name__ == "__main__":
import asyncio
asyncio.run(main())

Zero-config usage: Call CacheModule.configure() with no arguments to use defaults (in-memory backend).

application.yaml
cache:
enabled: true
backends:
- name: redis
type: redis
default: true
redis_url: "redis://localhost:6379/0"
default_ttl: 300
service:
enable_protection: true
Section titled “Option 2 — Profiles + Environment Variables (recommended)”
Terminal window
export LEX_CACHE__ENABLED=true
export LEX_CACHE__BACKENDS__0__TYPE=redis
export LEX_CACHE__BACKENDS__0__REDIS_URL=redis://localhost:6379/0
from lexigram.cache import CacheModule, CacheConfig
from lexigram.cache.config import CacheBackendConfig
from lexigram.cache.types import BackendType
CacheModule.configure(
CacheConfig(
backends=[
CacheBackendConfig(
name="redis",
type=BackendType.REDIS,
default=True,
redis_url="redis://localhost:6379/0",
)
]
)
)
FieldDefaultEnv varDescription
enabledTrueLEX_CACHE__ENABLEDEnable the cache module
backends[].nameLEX_CACHE__BACKENDS__0__NAMEUnique backend name
backends[].typeLEX_CACHE__BACKENDS__0__TYPEBackend type: redis, memory, memcached
backends[].redis_urlLEX_CACHE__BACKENDS__0__REDIS_URLRedis connection URL
backends[].default_ttlnullLEX_CACHE__BACKENDS__0__DEFAULT_TTLDefault TTL in seconds
service.enable_protectionTrueLEX_CACHE__SERVICE__ENABLE_PROTECTIONStampede protection
service.circuit_breaker_enabledFalseLEX_CACHE__SERVICE__CIRCUIT_BREAKER_ENABLEDCircuit breaker on backend failures
MethodDescription
CacheModule.configure(...)Configure with explicit CacheConfig
CacheModule.stub()In-memory backend for unit testing
  • Multi-backend — Redis, in-memory, and Memcached with a unified protocol
  • Stampede protection — Distributed lock on cold reads prevents thundering herd
  • Circuit breaker — Opens on repeated backend failures, falls through to origin
  • @cacheable decorator — Cache-aside with automatic key generation and Result support
  • Domain model serialization — Type-tagged JSON envelope preserves type identity round-trip
  • Production security — Blocks insecure Redis passwords when LEX_ENV=production
async with Application.boot(modules=[CacheModule.stub()]) as app:
cache = await app.container.resolve(CacheBackendProtocol)
await cache.set("key", "value", ttl=60)
assert await cache.get("key") == "value"
FileWhat it contains
src/lexigram/cache/module.pyCacheModule with configure() and stub()
src/lexigram/cache/config.pyCacheConfig, CacheBackendConfig, CacheServiceConfig
src/lexigram/cache/di/provider.pyCacheProvider boot and registration
src/lexigram/cache/decorators.py@cacheable decorator
src/lexigram/cache/backends/Redis, in-memory, and Memcached implementations