Skip to main content

Async Redis cache with optional AES-128 encryption powered by mores-encryption

Project description

๐Ÿš€ ValCache

PyPI Python License: MIT Tests

Async Redis Cache with Optional AES-128 Encryption

ValCache is a lightweight, async-first Redis caching library for Python with two modes:

  • ๐Ÿ”“ Normal Mode (ValCache) โ€” Fast plaintext caching with JSON support
  • ๐Ÿ” Encrypted Mode (EncryptedValCache) โ€” Transparent AES-128 encryption via mores-encryption

Perfect for securing PII, medical data, API keys, session tokens, or any sensitive information in your Redis cache.


๐Ÿ“ฆ Installation

pip install valcache

โš™๏ธ Setup (Encrypted Mode)

Generate a secure encryption key:

python -c "from cryptography.fernet import Fernet; print('ENCRYPTION_KEY=' + Fernet.generate_key().decode())"

Save it in your .env file:

ENCRYPTION_KEY=your_generated_key_here

Or pass it directly to the constructor (see usage below).


๐Ÿš€ Usage

1. Normal Cache

from valcache import ValCache

cache = ValCache(host="localhost", port=6379, default_ttl=600)
await cache.connect()

# String operations
await cache.set("user:1", "John Doe")
name = await cache.get("user:1")  # "John Doe"

# JSON operations
await cache.set_json("profile:1", {"name": "John", "age": 30})
profile = await cache.get_json("profile:1")  # {"name": "John", "age": 30}

# Check existence
exists = await cache.exists("user:1")  # True

# Delete
await cache.delete("user:1")

# Health check
healthy = await cache.health_check()  # True

await cache.close()

2. Encrypted Cache

from valcache import EncryptedValCache

cache = EncryptedValCache(
    host="localhost",
    port=6379,
    encryption_key="your-fernet-key-here",  # or set ENCRYPTION_KEY env var
)
await cache.connect()

# Values are automatically encrypted in Redis
await cache.set("secret", "My Secret Data")
result = await cache.get("secret")  # "My Secret Data" (decrypted)

# JSON encryption โ€” entire dict encrypted as one blob
await cache.set_json("patient:1", {"ssn": "123-45-6789", "diagnosis": "healthy"})
data = await cache.get_json("patient:1")  # decrypted dict

await cache.close()

3. Hashed Keys (Full Anonymization)

When even the Redis key should not reveal sensitive information:

from valcache import EncryptedValCache

cache = EncryptedValCache(encryption_key="your-fernet-key")
await cache.connect()

# Key is hashed, value is encrypted
await cache.set_hashed("patient@hospital.com", "diagnosis data", salt="my_salt")
# Redis key: "a3F9x...Kz8=" (hashed)  |  Redis value: "gAAAAABk..." (encrypted)

# Retrieve using the same key + salt
data = await cache.get_hashed("patient@hospital.com", salt="my_salt")
# "diagnosis data" (decrypted)

# JSON with hashed keys
await cache.set_json_hashed("user@example.com", {"role": "admin"}, salt="my_salt")
profile = await cache.get_json_hashed("user@example.com", salt="my_salt")

# Delete & exists with hashed keys
await cache.delete_hashed("patient@hospital.com", salt="my_salt")
exists = await cache.exists_hashed("patient@hospital.com", salt="my_salt")  # False

await cache.close()

๐Ÿ“š API Reference

ValCache (Normal Mode)

Method Description
connect() Initialize the Redis connection pool
close() Gracefully close the connection pool
set(key, value, ttl=None) Store a value with optional TTL
get(key) Retrieve a value by key
delete(key) Delete a key
exists(key) Check if a key exists
set_json(key, data, ttl=None) Store a dict as JSON
get_json(key) Retrieve and parse a JSON value
health_check() Ping the Redis server
get_ttl(key) Get remaining TTL for a key
keys(pattern="*") List keys matching a pattern
flush_db() Delete all keys in the database

EncryptedValCache (Encrypted Mode)

Inherits all methods from ValCache. The following are automatically encrypted:

Method Key Value
set(key, value) Plaintext ๐Ÿ” Encrypted
get(key) Plaintext ๐Ÿ”“ Decrypted
set_json(key, data) Plaintext ๐Ÿ” Encrypted
get_json(key) Plaintext ๐Ÿ”“ Decrypted

Hashed-key methods (key is also anonymized):

Method Key Value
set_hashed(key, value, salt) ๐Ÿ”’ Hashed ๐Ÿ” Encrypted
get_hashed(key, salt) ๐Ÿ”’ Hashed ๐Ÿ”“ Decrypted
delete_hashed(key, salt) ๐Ÿ”’ Hashed โ€”
exists_hashed(key, salt) ๐Ÿ”’ Hashed โ€”
set_json_hashed(key, data, salt) ๐Ÿ”’ Hashed ๐Ÿ” Encrypted
get_json_hashed(key, salt) ๐Ÿ”’ Hashed ๐Ÿ”“ Decrypted

๐Ÿ”’ Security Details

Component Implementation
Encryption AES-128 CBC via cryptography.fernet.Fernet (PKCS7 padding, HMAC-SHA256 integrity)
Key Hashing PBKDF2HMAC-SHA256 with 200,000 iterations, 32-byte output
Encoding URL-safe Base64 for all encrypted outputs
Key Management Via ENCRYPTION_KEY env var or constructor parameter

๐Ÿงช Running Tests

pip install -e ".[encrypted,dev]"
pytest tests/ -v

๐Ÿ”ง Configuration

ValCache resolves configuration in this priority order:

  1. Constructor params โ€” ValCache(host="myhost") wins
  2. .env file / environment variables โ€” auto-loaded via python-dotenv
  3. Defaults โ€” localhost, 6379, 0

.env File (Recommended)

Create a .env file in your project root:

# Redis connection
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB=0
REDIS_PASSWORD=your_redis_password
REDIS_MAX_CONNECTIONS=20

# Encryption (EncryptedValCache only)
ENCRYPTION_KEY=your_fernet_key_here

ValCache auto-loads this file โ€” no extra setup needed.

Environment Variables

Variable Description Default
REDIS_HOST Redis server hostname localhost
REDIS_PORT Redis server port 6379
REDIS_DB Redis database number 0
REDIS_PASSWORD Redis auth password None
REDIS_MAX_CONNECTIONS Connection pool size 20
ENCRYPTION_KEY Fernet encryption key Auto-generated

Constructor Parameters

All env vars can be overridden via constructor:

Parameter Type Overrides Env Var
host str REDIS_HOST
port int REDIS_PORT
db int REDIS_DB
password str REDIS_PASSWORD
max_connections int REDIS_MAX_CONNECTIONS
default_ttl int โ€” (no env var, default 3600)
encryption_key str ENCRYPTION_KEY (EncryptedValCache only)

๐Ÿ“„ License

MIT License โ€” see LICENSE for details.


๐Ÿ”— Related

  • mores-encryption โ€” The encryption library powering ValCache's encrypted mode

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

valcache-0.1.0.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

valcache-0.1.0-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

Details for the file valcache-0.1.0.tar.gz.

File metadata

  • Download URL: valcache-0.1.0.tar.gz
  • Upload date:
  • Size: 13.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for valcache-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bcd8703c104da2ece0995969c41961dbf05f3cce28129db4d43843e5ed207c7a
MD5 5bae0364f2e214acee4a7ab0d15af76d
BLAKE2b-256 15911930901a621aecef64abc28ddf070844ac2ed2c41647ed07bf021440d7bf

See more details on using hashes here.

File details

Details for the file valcache-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: valcache-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for valcache-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 20d406727b098535d3cf3059f344030199929d18d366785f759cc7b812fcf070
MD5 e65ef66ea4452ee6a22079fc0c42a4ca
BLAKE2b-256 76f878d4cfb8898282935dbe15d1192af28fd3b7a58581d07787df78bef6579b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page