Skip to main content

grass-redis

Redis Sentinel client with optional mutual TLS for high-availability Redis clusters.

Features

  • Automatic failover via Sentinel
  • Connection pooling and caching
  • Read replicas for load distribution
  • TLS security with optional client certificates
  • Service discovery - automatically find primary and replicas
  • Multiple databases - manage multiple Redis instances from one client

Installation

pip install grass-redis

Quick Start

Load configuration from /etc/redis/credentials.env:

from grass_redis import create_client_from_credentials

# One-line client creation
with create_client_from_credentials() as client:
    # Connect to database
    db = client.get_primary("redis-instance-01")
    db.set("key", "value")
    
    # Read from replica for load distribution
    replica = client.get_replica("redis-instance-01")
    value = replica.get("key")

The factory method automatically:

  • Loads Sentinel endpoints from /etc/redis/credentials.env
  • Loads all database passwords
  • Configures TLS with /etc/redis/ca.crt
  • Returns a ready-to-use client

Manual Configuration

from pathlib import Path
from grass_redis import RedisSentinelClient, SentinelConfig

config = SentinelConfig(
    sentinel_hosts=[
        ("sentinel1.example.com", 26379),
        ("sentinel2.example.com", 26379),
        ("sentinel3.example.com", 26379),
    ],
    databases={"redis-instance-01": "password"},
    certs_dir=Path("/etc/redis"),
)

with RedisSentinelClient(config) as client:
    db = client.get_primary("redis-instance-01")
    db.set("key", "value")

Configuration

Credentials File Format

Deploy to /etc/redis/credentials.env:

# Sentinel endpoints
REDIS_SENTINEL_HOSTS=sentinel1.example.com:26379,sentinel2.example.com:26379

# Database credentials
REDIS_INSTANCE_01_MASTER=redis-instance-01
REDIS_INSTANCE_01_PORT=6379
REDIS_INSTANCE_01_PASSWORD=your-password

Required Files

  • /etc/redis/ca.crt - CA certificate (required, 644)
  • /etc/redis/credentials.env - Configuration and passwords (600)

Common Operations

Basic Operations with TTL

db = client.get_primary("redis-instance-01")
db.set("key", "value", ex=60)  # Expires in 60 seconds
value = db.get("key")

Hash Operations

db.hset("user:123", mapping={
    "name": "John",
    "email": "john@example.com",
    "status": "active"
})
data = db.hgetall("user:123")
name = db.hget("user:123", "name")

List Operations

# Push items to list
db.lpush("queue:tasks", "task1", "task2")

# Pop from list
task = db.rpop("queue:tasks")

# Get list length
length = db.llen("queue:tasks")

Set Operations

# Add items to set
db.sadd("processed:urls", "url1", "url2", "url3")

# Check membership
exists = db.sismember("processed:urls", "url1")

# Get all members
urls = db.smembers("processed:urls")

Using Read Replicas

Distribute read load across replicas:

with create_client_from_credentials() as client:
    # Write to primary
    primary = client.get_primary("redis-instance-01")
    primary.set("data", "value")
    
    # Read from replica (automatic load balancing)
    replica = client.get_replica("redis-instance-01")
    value = replica.get("data")

Service Discovery

Find where databases are currently running:

with create_client_from_credentials() as client:
    # Find current primary
    host, port = client.discover_primary("redis-instance-01")
    print(f"Primary: {host}:{port}")
    
    # Find all replicas
    replicas = client.discover_replicas("redis-instance-01")
    for host, port in replicas:
        print(f"Replica: {host}:{port}")

Error Handling

from redis.exceptions import ConnectionError, TimeoutError

try:
    with create_client_from_credentials() as client:
        db = client.get_primary("redis-instance-01")
        db.set("key", "value")
except FileNotFoundError as e:
    print(f"Missing credentials file: {e}")
except ConnectionError as e:
    print(f"Cannot connect to Redis: {e}")
except TimeoutError as e:
    print(f"Operation timed out: {e}")
except KeyError as e:
    print(f"Database not configured: {e}")

API

Factory Method

  • create_client_from_credentials() - Load from /etc/redis/credentials.env

SentinelConfig

  • sentinel_hosts - List[(host, port)]
  • databases - Dict[db_name, password]
  • certs_dir - Path (default: /etc/redis)

RedisSentinelClient

  • get_primary(db) - Connection for writes
  • get_replica(db) - Connection for reads (load balanced)
  • discover_primary(db) - Get current primary address
  • discover_replicas(db) - Get all replica addresses
  • test_connection(db) - PING test

Key Features

  • No Hardcoded Endpoints - Everything loaded from configuration files
  • Sentinel Discovery - Sentinels automatically find current primary location
  • TLS Required - All connections use TLS with CA certificate
  • Connection Pooling - Automatically managed, connections reused efficiently
  • Automatic Failover - Sentinel promotes replicas if primary fails

Example Scripts

Included example scripts:

  • example_production_usage.py - Comprehensive production examples
  • example_new_setup.py - Simple manual configuration example

Publishing to PyPI

See PUBLISHING.md for complete instructions on publishing this package to PyPI.

License

MIT License - see LICENSE file for details.

Metadata

Release files for grass-redis 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for grass-redis 0.2.0
File Size Uploaded
grass_redis-0.2.0.tar.gz 12.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for grass-redis 0.2.0
File Interpreter ABI Platform
grass_redis-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 18.6 kB

Release files / grass_redis-0.2.0.tar.gz

Download URL grass_redis-0.2.0.tar.gz
Size 12.0 kB
Tags Source
SHA-256 checksum
How to use checksums
d6d76dbe45695510bd3c96831f2086326c5d0c1b86f6ea8e3d42bdf65f3dd9e0
BLAKE2b-256 checksum
How to use checksums
1f1abe4923feaa805c760a1b07df263a1ffb4c8e066856b055420cbb144d67e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / grass_redis-0.2.0-py3-none-any.whl

Download URL grass_redis-0.2.0-py3-none-any.whl
Size 6.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a000ae6d70b68b19851fb5255e6f17434275ccdcafcdfc6acce6a9d0b3259905
BLAKE2b-256 checksum
How to use checksums
81a4636ceeeeaa9a75c3ed02c5071782f173d910b90d7e6b4e4260afcd45ecc8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page