Enterprise-grade hybrid cache for Python
Project description
🌐 cachka
Enterprise-grade hybrid cache for Python
Combines in-memory (L1) and disk-based (L2) caching with observability, encryption, and circuit breaking.
Works seamlessly in async, sync, and threaded environments.
✨ Features
- Hybrid architecture: L1 (memory) + L2 (SQLite disk)
- Async & sync support: Use the same decorator everywhere
- TTL with smart LRU eviction (no memory leaks)
- Observability: Prometheus metrics, OpenTelemetry tracing
- Security: AES-GCM encryption for disk storage
- Resilience: Circuit breaker, graceful degradation
- Zero dependencies for core functionality
- Type-safe: Full type hints and Pydantic config
🚀 Quick Start
1. Install
# Core (required)
pip install cachka
# With Prometheus metrics
pip install "cachka[prometheus]"
# Full enterprise features
pip install "cachka[full]"
2. Initialize Cache
from cachka import cache_registry, CacheConfig
# Basic initialization
cache_registry.initialize()
# Or with custom configuration
config = CacheConfig(
db_path="my_cache.db",
l1_maxsize=2048, # L1 cache size
l1_ttl=600, # L1 TTL in seconds
enable_metrics=True,
enable_encryption=True,
encryption_key="your-base64-encoded-32-byte-key"
)
cache_registry.initialize(config)
📖 Usage Examples
Basic Async Function Caching
import asyncio
from cachka import cached, cache_registry, CacheConfig
# Initialize cache
config = CacheConfig(db_path="cache.db")
cache_registry.initialize(config)
@cached(ttl=300) # Cache for 5 minutes
async def fetch_user_data(user_id: int):
# Simulate API call
await asyncio.sleep(0.1)
return {"id": user_id, "name": f"User {user_id}"}
async def main():
# First call - fetches data
user1 = await fetch_user_data(1)
print(user1) # {"id": 1, "name": "User 1"}
# Second call - returns cached data (no API call)
user1_cached = await fetch_user_data(1)
print(user1_cached) # {"id": 1, "name": "User 1"} (from cache)
# Cleanup
await cache_registry.shutdown()
asyncio.run(main())
Sync Function Caching
from cachka import cached, cache_registry, CacheConfig
cache_registry.initialize()
@cached(ttl=60)
def expensive_computation(n: int) -> int:
"""Fibonacci calculation - cached after first call"""
if n < 2:
return n
return expensive_computation(n - 1) + expensive_computation(n - 2)
# First call - computes
result1 = expensive_computation(30) # Takes time
# Second call - returns cached result instantly
result2 = expensive_computation(30) # Instant!
Class Methods with ignore_self
from cachka import cached, cache_registry, CacheConfig
cache_registry.initialize()
class UserService:
@cached(ttl=300, ignore_self=True)
async def get_user(self, user_id: int):
# Cache key will be based on user_id only, not self instance
return await self._fetch_from_db(user_id)
async def _fetch_from_db(self, user_id: int):
# Database query simulation
return {"id": user_id, "name": f"User {user_id}"}
service = UserService()
user = await service.get_user(123) # Cached by user_id only
Advanced Configuration
from cachka import cache_registry, CacheConfig
import base64
import secrets
# Generate encryption key (32 bytes, base64-encoded)
encryption_key = base64.b64encode(secrets.token_bytes(32)).decode()
config = CacheConfig(
db_path="secure_cache.db",
name="my_cache",
l1_maxsize=4096, # Larger L1 cache
l1_ttl=1800, # 30 minutes L1 TTL
vacuum_interval=3600, # Cleanup every hour
cleanup_on_start=True, # Clean expired on startup
enable_metrics=True, # Prometheus metrics
enable_encryption=True, # AES-GCM encryption
encryption_key=encryption_key, # Your encryption key
circuit_breaker_threshold=50, # Open circuit after 50 failures
circuit_breaker_window=60 # Recovery window: 60 seconds
)
cache_registry.initialize(config)
Graceful Shutdown
import asyncio
from cachka import cache_registry
async def main():
# Your application code
pass
# Cleanup on application exit
async def cleanup():
await cache_registry.shutdown()
# In FastAPI, for example:
# @app.on_event("shutdown")
# async def shutdown_event():
# await cache_registry.shutdown()
Accessing Metrics (Prometheus)
from cachka import cache_registry
# After enabling metrics in config
cache = cache_registry.get()
metrics_text = cache.get_metrics_text()
print(metrics_text)
# Output: Prometheus metrics in text format
Health Check
from cachka import cache_registry
cache = cache_registry.get()
health = await cache.health_check()
print(health)
# {
# "status": "healthy",
# "l1_size": 42,
# "circuit_breaker": "CLOSED",
# "storage": "ok"
# }
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
cachka-0.2.0.tar.gz
(34.4 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
cachka-0.2.0-py3-none-any.whl
(18.6 kB
view details)
File details
Details for the file cachka-0.2.0.tar.gz.
File metadata
- Download URL: cachka-0.2.0.tar.gz
- Upload date:
- Size: 34.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.15 {"installer":{"name":"uv","version":"0.9.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44e42d2f6472e15aa7d7f44ee88aec2f177562ebe56ac49cf51a16455a58322e
|
|
| MD5 |
8cb34e0cc67d77c6ef82f89044b702dc
|
|
| BLAKE2b-256 |
02c17b2ff7cb2abe06e3d1cdc266e9f532209841cc91c784b6c2530acfcf0b5b
|
File details
Details for the file cachka-0.2.0-py3-none-any.whl.
File metadata
- Download URL: cachka-0.2.0-py3-none-any.whl
- Upload date:
- Size: 18.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.15 {"installer":{"name":"uv","version":"0.9.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47a9fa6faaebe78a878a14232b081e0597d1010db5b3a9a1829d972a3c811c33
|
|
| MD5 |
161e8c6b575db9a7ddee6e4036afd398
|
|
| BLAKE2b-256 |
b1236aec6b68036e47eb5c37751df37fcfa3e8e14dff399b005e2e9a9564768d
|