A lightweight Python library for Redis-backed tenant configuration storage
Project description
litewave-cache-lib
A lightweight Python library that provides a connection-pooled, fault-tolerant Redis client with automatic retry logic and JSON-aware key lookup helpers for tenant configuration storage.
Features
- Connection-pooled Redis client with automatic retry on failure (5-minute cooldown)
- Fetch values by raw Redis key, or by
(tenant_id, secret_name)pair viaget_secret - Automatic JSON deserialization of stored values
- Attribute-level extraction from stored JSON objects via
get_attribute_value_by_key - Standardised tenant key format:
tenant:{tenant_id}:secret:{secret_name} - Fully configurable via environment variables
- Zero-boilerplate logging setup
Installation
pip install git+https://github.com/aiorch/litewave-cache-lib
Or install from source:
git clone https://github.com/aiorch/litewave-cache-lib.git
cd litewave-cache-lib
pip install .
Requirements
- Python >= 3.10
- redis >= 5.0.0
- python-dotenv >= 1.0.0
Configuration
All settings are read from environment variables at import time. REDIS_HOST, REDIS_PORT, and REDIS_PASSWORD are required — the library raises a ValueError at startup if any of them are missing.
| Environment Variable | Default | Description |
|---|---|---|
REDIS_HOST |
(required) | Redis server hostname |
REDIS_PORT |
(required) | Redis server port |
REDIS_PASSWORD |
(required) | Redis password |
REDIS_DB |
0 |
Default Redis database index |
REDIS_COORDINATION_DB |
1 |
Redis DB reserved for coordination workloads |
REDIS_TENANT_CONFIG_DB |
2 |
Redis DB used for tenant configuration |
REDIS_MAX_CONNECTIONS |
50 |
Connection pool size |
REDIS_SOCKET_CONNECT_TIMEOUT |
2 |
Socket connect timeout in seconds |
REDIS_SOCKET_TIMEOUT |
2 |
Socket read/write timeout in seconds |
LOG_LEVEL |
INFO |
Logging level (DEBUG, INFO, WARNING, …) |
A .env file is supported via python-dotenv. Load it before importing the library:
from dotenv import load_dotenv
load_dotenv(".env", override=True)
from tenant_mgr_cache import get_redis_client
Usage
Get the Redis client
Returns the shared, connection-pooled Redis client. Returns None if the connection is unavailable. A failed connection is retried automatically after a 5-minute cooldown; subsequent calls reuse the existing client.
from tenant_mgr_cache import get_redis_client
client = get_redis_client()
if client:
client.set("tenant:15:secret:satoken", "abc123")
print(client.get("tenant:15:secret:satoken")) # "abc123"
get_secret — fetch by tenant ID and secret name
Builds the canonical key tenant:{tenant_id}:secret:{secret_name} internally and returns the stored value. JSON values are deserialized automatically; plain strings are returned as-is.
from tenant_mgr_cache import get_secret
# JSON object stored → returned as dict
config = get_secret("15", "db_config")
if isinstance(config, dict):
print(config["host"]) # e.g. "db.prod.internal"
print(config["port"]) # e.g. 5432
# Plain string stored → returned as-is
token = get_secret("15", "satoken")
print(token) # e.g. "abc123"
# Key does not exist → None
missing = get_secret("15", "nonexistent")
print(missing) # None
get_secret(tenant_id: str, secret_name: str) -> Optional[Any]
Builds the canonical key tenant:{tenant_id}:secret:{secret_name} and returns the stored value. JSON is deserialized automatically. Returns None if the key does not exist, Redis is unavailable, or any error occurs.
get_value_by_key(key: str) -> Optional[Any]
Fetches the value stored at key and JSON-decodes it if possible. Returns None when the key does not exist, Redis is unavailable, or any error occurs.
get_attribute_value_by_key(tenant_id: str, secret_name: str, attribute_name: str) -> Optional[Any]
Builds the canonical key for tenant_id + secret_name, fetches the stored JSON object, and returns data.get(attribute_name). Falls back to getattr for non-dict objects. Returns None if the key is missing, the value is not dict-like, or the attribute is absent.
prepare_key(tenant_id: str, secret_name: str) -> str
Builds the canonical Redis key for a tenant secret:
from tenant_mgr_cache.cache_client import prepare_key
key = prepare_key("15", "satoken")
print(key) # "tenant:15:secret:satoken"
settings — CacheSettings
A dataclass instance holding all resolved configuration values. Import it to inspect or override settings programmatically:
from tenant_mgr_cache import settings
print(settings.REDIS_HOST)
print(settings.REDIS_PORT)
print(settings.REDIS_TENANT_CONFIG_DB)
logger — logging.Logger
A pre-configured logger (litewave_cache) that respects the LOG_LEVEL environment variable. Import it to emit log messages consistent with the library's format:
from tenant_mgr_cache import logger
logger.info("Custom message from application code")
Development
Setup
pip install -r requirements.txt
Running Tests
pytest
With coverage:
pytest --cov=tenant_mgr_cache --cov-report=term-missing
License
MIT License. See LICENSE for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
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
File details
Details for the file litewave_cache_lib-0.1.2.tar.gz.
File metadata
- Download URL: litewave_cache_lib-0.1.2.tar.gz
- Upload date:
- Size: 9.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8323c10e10e4733a9137efa0b4e6ce2a71bb7f763ab2d61eae2794ab782fc23
|
|
| MD5 |
9a748d08c6530ad813a66753f50a7b4c
|
|
| BLAKE2b-256 |
805f58bd1f9dedafe358c9d71502c49f3769777428573bbfaaf61acc042342ac
|
File details
Details for the file litewave_cache_lib-0.1.2-py3-none-any.whl.
File metadata
- Download URL: litewave_cache_lib-0.1.2-py3-none-any.whl
- Upload date:
- Size: 5.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a935e08840bd9e580768b1b05388d39f7a3415af3ce75f4eecb34cf1d37a2f3b
|
|
| MD5 |
6eaf9804207323296048013ec335b4fa
|
|
| BLAKE2b-256 |
9f5a140455eb7072f7b5f86a3b2fa221efc409021786e5785f2f0c83d33154ef
|