philiprehberger-cache-kit
Lightweight in-memory cache with TTL, LRU eviction, and tag-based invalidation.
Installation
pip install philiprehberger-cache-kit
Usage
Basic Cache
from philiprehberger_cache_kit import Cache
cache: Cache[str] = Cache(max_size=1000)
cache.set("key", "value")
print(cache.get("key")) # "value"
TTL (Time-to-Live)
cache = Cache(default_ttl=60.0) # 60 seconds default
cache.set("session", "abc123") # uses default TTL
cache.set("temp", "data", ttl=5.0) # expires in 5 seconds
cache.set("permanent", "data", ttl=None) # no expiry when default is set
LRU Eviction
cache = Cache(max_size=100)
# When full, least recently used entries are evicted first
# Expired entries are evicted before non-expired ones
for i in range(200):
cache.set(f"key-{i}", f"value-{i}")
print(cache.size) # 100
Tag-Based Invalidation
cache.set("user:1", user_data, tags={"users", "team-a"})
cache.set("user:2", user_data, tags={"users", "team-b"})
cache.set("post:1", post_data, tags={"posts", "team-a"})
# Invalidate all entries tagged "team-a"
removed = cache.invalidate_by_tag("team-a")
print(removed) # 2
# Invalidate everything tagged "team-a" OR "team-b" in one pass
removed = cache.invalidate_by_tags(["team-a", "team-b"])
Lazy load with get_or_compute
from philiprehberger_cache_kit import Cache
cache: Cache[dict] = Cache(max_size=1000)
def fetch_user(user_id: int) -> dict:
# Expensive lookup (DB, HTTP, etc.) — only called on cache miss.
return {"id": user_id, "name": "Ada"}
# First call: computes, caches with TTL/tags, returns the value (miss).
user = cache.get_or_compute(
"user:1",
lambda: fetch_user(1),
ttl=60.0,
tags=["users"],
)
# Second call within TTL: returns cached value, compute_fn is NOT invoked (hit).
user = cache.get_or_compute("user:1", lambda: fetch_user(1))
Batch Operations
# Set multiple entries at once
cache.set_many({"a": 1, "b": 2, "c": 3}, ttl=30.0)
# Get multiple entries at once (skips missing/expired)
results = cache.get_many(["a", "b", "missing"])
print(results) # {"a": 1, "b": 2}
Cache Statistics
from philiprehberger_cache_kit import Cache, CacheStats
cache: Cache[str] = Cache(max_size=100)
cache.set("x", "hello")
cache.get("x") # hit
cache.get("missing") # miss
stats = cache.stats()
print(stats.hits) # 1
print(stats.misses) # 1
print(stats.hit_rate) # 0.5
print(stats.evictions) # 0
print(stats.expired) # 0
cache.reset_stats() # zero out all counters
Other Operations
cache.has("key") # check existence
"key" in cache # same as has()
cache.delete("key") # delete single entry
cache.keys() # list all non-expired keys
len(cache) # count of non-expired entries
cache.get_entry("key") # get CacheEntry with tags, expires_at
cache.clear() # remove everything
API
| Function / Class | Description |
|---|---|
Cache(max_size=1000, default_ttl=None) |
Create a new cache |
.set(key, value, ttl=None, tags=None) |
Store a value |
.get(key, default=None) |
Retrieve a value |
.get_or_compute(key, compute_fn, ttl=None, tags=None) |
Return cached value, or compute and cache it on miss |
.get_many(keys) |
Retrieve multiple values, skip missing/expired |
.set_many(items, ttl=None) |
Store multiple values |
.has(key) |
Check if key exists and is not expired |
.delete(key) |
Remove a key |
.invalidate_by_tag(tag) |
Remove all entries with a tag |
.invalidate_by_tags(tags) |
Remove all entries matching any tag in tags (single pass) |
.clear() |
Remove all entries |
.keys() |
List non-expired keys |
.get_entry(key) |
Get CacheEntry object (value, expires_at, tags) |
.stats() |
Get CacheStats (hits, misses, evictions, expired, hit_rate) |
.reset_stats() |
Zero out all stat counters |
.size |
Number of stored entries |
len(cache) |
Number of non-expired entries |
key in cache |
Check key existence |
CacheStats |
Dataclass with hits, misses, evictions, expired, hit_rate |
Development
pip install -e .
python -m pytest tests/ -v
Support
If you find this project useful:
License
Release files for philiprehberger-cache-kit 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| philiprehberger_cache_kit-0.5.0.tar.gz | 191.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| philiprehberger_cache_kit-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 198.3 kB
Release files / philiprehberger_cache_kit-0.5.0.tar.gz
| Download URL | philiprehberger_cache_kit-0.5.0.tar.gz |
|---|---|
| Size | 191.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ce9bcb7b48b7683e25ee4500389711d33fe80cff3ed70052c694ee2c90c16b30
|
|
BLAKE2b-256 checksum How to use checksums |
081ed082bed500efb6ceba00a36c0caa6b1c17af4e8617107ada6375e8f9eee8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / philiprehberger_cache_kit-0.5.0-py3-none-any.whl
| Download URL | philiprehberger_cache_kit-0.5.0-py3-none-any.whl |
|---|---|
| Size | 6.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ef2ff65a6776d493f9e5fe13f5df0c5d508ef910b21473940c804fa2942f2af5
|
|
BLAKE2b-256 checksum How to use checksums |
2767c7baf94f42d90b4dc7ef1a7f30c32083a6aa7f073dfdcb780b1939945362
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|