Cache Framework
OpenViper provides a simple, robust caching abstraction that can be used directly or within your routing and background task layers. The core cache interacts asynchronously with the underlying store, ensuring non-blocking operations.
Getting Started
The simplest way to use the cache is to import the get_cache factory. It will automatically load the backend configured in your settings.
from openviper.cache import get_cache
async def my_view(request):
cache = get_cache()
# Check if we have cached data
if await cache.has_key("my_expensive_data"):
return await cache.get("my_expensive_data")
# Compute and cache
data = await compute_expensive_data()
await cache.set("my_expensive_data", data, ttl=300) # cache for 5 minutes
return data
Configuration
By default, OpenViper uses an in-memory cache. You can configure a different backend in your settings.py:
# Use the local memory cache (default)
CACHE_BACKEND = "memory"
# Use Redis
CACHE_BACKEND = "redis"
REDIS_URL = "redis://localhost:6379"
Built-in Backends
InMemoryCache
The default cache. Stores data in a Python dictionary. Suitable for local development or single-process deployments without critical cache persistence needs.
RedisCache
A production-ready asynchronous Redis backend.
Requirements: You must install the redis library (e.g., pip install openviper[redis] or pip install redis).
# settings.py
CACHE_BACKEND = "redis"
REDIS_URL = "redis://user:password@redis-host:6379/0"
The RedisCache will automatically serialize and deserialize dictionaries and lists to and from JSON.
Creating Custom Backends
If you need to store your cache in a different system (like Memcached, a Database table, or AWS ElastiCache), you can easily build a custom backend.
Create a class that inherits from
openviper.cache.base.BaseCache.Implement the required async methods:
get,set,delete,has_key, andclear.
# myapp/cache.py
from typing import Any
from openviper.cache.base import BaseCache
class FileSystemCache(BaseCache):
def __init__(self, directory: str = "/tmp/cache"):
self.dir = directory
# ... initialize directory
async def get(self, key: str, default: Any = None) -> Any:
# ... read from file
pass
async def set(self, key: str, value: Any, ttl: int | None = None) -> None:
# ... write to file
pass
async def delete(self, key: str) -> None:
pass
async def has_key(self, key: str) -> bool:
pass
async def clear(self) -> None:
pass
Point your settings to the custom backend using a dotted module path:
# settings.py
CACHE_BACKEND = "myapp.cache.FileSystemCache"
When get_cache() is called, OpenViper will dynamically import and instantiate your class.