Skip to main content

Redis control with Python - Async support, decorators, and high availability

Project description

WRedis

Python 3.10+ License: MIT Coverage: 95%+ Ruff PyPI LTS

WRedis v1.0.0 LTS — Production-ready Python library for Redis with real async/await, cache decorators, high availability, and comprehensive type safety.

Description

WRedis simplifies interacting with Redis by providing:

  • Sync & Async APIs — Real asyncio, zero threads
  • Cache Decorators@cache, @async_cache with hit/miss metrics
  • High Availability — Sentinel & Cluster support
  • Error Handling — Proper exceptions, no silent failures
  • Type Safety — Full type hints, mypy clean
  • 12 Data Structures — Bitmap, Hash, Set, SortedSet, Stream, Queue, Pub/Sub, Geo, HyperLogLog, Pipeline, Transaction
  • 95%+ Test Coverage — 800+ unit tests, 38 integration tests (Redis real), 19 stress tests

Installation

To install the library, use pip:

pip install wredis

Make sure you have Redis installed on your system or that you can access a remote Redis server. You can install Redis locally by following the official instructions or use a docker-compose.yaml like the following:

version: "3.3"
services:
  redis:
    image: redislabs/redismod
    ports:
      - "6379:6379"
    environment:
      - SO=docker
    volumes:
      - ./cache_redis:/data
    command: --dir /data --loadmodule /usr/lib/redis/modules/redistimeseries.so

  redis-commander:
    image: rediscommander/redis-commander:latest
    environment:
      - REDIS_HOSTS=local:redis:6379
      - HTTP_USER=root
      - HTTP_PASSWORD=qwerty
    ports:
      - "8081:8081"
    depends_on:
      - redis

Modules

The WRedis library offers a series of modules that facilitate interaction with Redis. The available modules are described below:


Bitmaps

Class: RedisBitmapManager

This module allows you to interact with bitmaps in Redis.

Constructor

RedisBitmapManager(host="localhost", port=6379, db=0, verbose=True)

Methods

Method Description
set_bit(key, offset, value, ttl=-1) Sets a bit at a specific position. Optionally sets TTL.
get_bit(key, offset) Retrieves the value of a bit at a specific position (0 or 1).
count_bits(key) Counts the number of bits set to 1 in a bitmap.
get_ttl(key) Retrieves the TTL for a bitmap key. Returns -1 (no TTL), -2 (key doesn't exist), or seconds remaining.
extend_ttl(key, ttl) Extends or sets a new TTL for a bitmap key.

Example

from wredis.bitmap import RedisBitmapManager

bitmap_manager = RedisBitmapManager(host="localhost")

# Write
bitmap_manager.set_bit(key="my_bitmap", offset=5, value=1)

# Read
print(bitmap_manager.get_bit("my_bitmap", 0))
print(bitmap_manager.count_bits("my_bitmap"))

# TTL
bitmap_manager.set_bit(key="my_bitmap", offset=10, value=1, ttl=300)
print(bitmap_manager.get_ttl("my_bitmap"))
bitmap_manager.extend_ttl("my_bitmap", 600)

Hash

Class: RedisHashManager

This module allows you to interact with hashes in Redis. Supports automatic JSON serialization for dict values.

Constructor

RedisHashManager(host="localhost", port=6379, db=0, verbose=True)

Methods

Method Description
create_hash(hash_name, key, value, ttl=-1) Writes a key-value pair into a Redis hash. Dict values are auto-serialized to JSON.
read_hash(hash_name, key) Reads a value from a hash. Auto-deserializes JSON if applicable. Returns None if not found.
update_hash(hash_name, key, new_data) Updates a key-value pair. If the field exists and is a dict, merges the data. Otherwise, replaces it.
delete_hash_field(hash_name, key) Deletes a specific field from a hash.
read_all_hash(hash_name) Reads all fields and values from a hash. Returns a dict or None.
get_ttl(hash_name) Retrieves the TTL for a hash. Returns -1 (no TTL), -2 (key doesn't exist), or seconds remaining.
extend_ttl(hash_name, ttl) Extends or sets a new TTL for a hash.

Example

from wredis.hash import RedisHashManager

redis_manager = RedisHashManager(host="localhost")

# Create
redis_manager.create_hash("my_hash", "user:1", {"name": "Alice", "age": 30}, ttl=60)
redis_manager.create_hash("my_hash", "user:2", {"name": "Bob", "age": 25})

# Read
user1 = redis_manager.read_hash("my_hash", "user:1")
print(f"User 1: {user1}")

all_users = redis_manager.read_all_hash("my_hash")
print(f"All users: {all_users}")

# Update
redis_manager.update_hash("my_hash", "user:3", {"name": "William", "age": 35, "gender": "male"})

# Delete
redis_manager.delete_hash_field("my_hash", "user:2")

# TTL
print(redis_manager.get_ttl("my_hash"))
redis_manager.extend_ttl("my_hash", 120)

Pub/Sub

Class: RedisPubSubManager

This module allows you to interact with the Redis publish/subscribe system using a decorator-based API.

Constructor

RedisPubSubManager(host="localhost", port=6379, db=0, verbose=True)

Methods

Method Description
publish_message(channel, message) Publishes a message to a channel. Supports strings and dicts (auto-serialized to JSON).
on_message(channel) Decorator to register a callback function for a specific channel. Starts a listener thread automatically.
stop_listeners() Stops all listener threads.

Example

Producer:

from wredis.pubsub import RedisPubSubManager

pubsub_manager = RedisPubSubManager(host="localhost")

pubsub_manager.publish_message("channel_1", "Hello, Redis!")
pubsub_manager.publish_message("channel_2", {"saludo": "Hola desde channel_2!"})

Consumer:

from wredis.pubsub import RedisPubSubManager
import signal

pubsub_manager = RedisPubSubManager(host="localhost", verbose=False)

@pubsub_manager.on_message("channel_1")
def handle_message(message):
    print(f"[channel_1] Received: {message}")

@pubsub_manager.on_message("channel_2")
def handle_channel_2(message):
    print(f"[channel_2] Received: {message}")

def signal_handler(sig, frame):
    print("\nStopping...")
    pubsub_manager.stop_listeners()
    exit(0)

signal.signal(signal.SIGINT, signal_handler)
signal.pause()

Queue

Class: RedisQueueManager

This module allows you to interact with queues in Redis using lists (RPUSH/BRPOP).

Constructor

RedisQueueManager(poll_interval=1, host="localhost", port=6379, db=0, max_retries=3, verbose=True)

Methods

Method Description
publish(queue_name, data, ttl=-1) Publishes a message (dict) to a queue. Auto-serialized to JSON. Optionally sets TTL on the queue key.
on_message(queue_name) Decorator to register a callback function for a specific queue.
start() Starts parallel consumption threads for all registered queues.
stop() Stops consumption for all queues and joins threads.
wait() Keeps the program running and handles SIGINT for clean shutdown.
get_queue_length(queue_name) Returns the number of elements in a queue.

Example

Producer:

from wredis.queue import RedisQueueManager

queue_manager = RedisQueueManager(host="localhost")

queue_manager.publish("tasks", {"id": 1, "task": "process_image", "status": "pending"})
queue_manager.publish("tasks", {"id": 2, "task": "generate_report", "priority": "high"}, ttl=30)

Consumer:

from wredis.queue import RedisQueueManager

queue_manager = RedisQueueManager(poll_interval=2, host="localhost", verbose=False)

@queue_manager.on_message("tasks")
def worker(record):
    print(f"Processing: {record}")

queue_manager.start()
queue_manager.wait()

Note: Setting a TTL on a queue modifies the TTL of the entire queue key, not individual messages. TTL is measured in seconds.


Sets

Class: RedisSetManager

This module allows you to interact with sets in Redis.

Constructor

RedisSetManager(host="localhost", port=6379, db=0, verbose=True)

Methods

Method Description
add_to_set(key, *values, ttl=-1) Adds one or more elements to a set. Optionally sets TTL.
get_set_members(key) Retrieves all members of a set as a decoded set.
is_member(key, value) Checks if an element is a member of the set. Returns True or False.
remove_from_set(key, *values) Removes one or more elements from a set.
get_ttl(key) Retrieves the TTL for a set. Returns -1 (no TTL), -2 (key doesn't exist), or seconds remaining.
extend_ttl(key, ttl) Extends or sets a new TTL for a set.

Example

from wredis.sets import RedisSetManager

set_manager = RedisSetManager(host="localhost")

# Add
set_manager.add_to_set("my_set", "value1", "value2")
set_manager.add_to_set("my_set", "value5", ttl=300)

# Read
print(set_manager.get_set_members("my_set"))
print(set_manager.is_member("my_set", "value1"))

# Remove
set_manager.remove_from_set("my_set", "value2")

# TTL
print(set_manager.get_ttl("my_set"))
set_manager.extend_ttl("my_set", 600)

Sorted Sets

Class: RedisSortedSetManager

This module allows you to interact with sorted sets in Redis.

Constructor

RedisSortedSetManager(host="localhost", port=6379, db=0, verbose=True)

Methods

Method Description
add_to_sorted_set(key, score, member, ttl=-1) Adds a member with a score. Optionally sets TTL.
get_sorted_set(key, start=0, stop=-1, with_scores=False) Retrieves elements in ascending order. Returns list of members or (member, score) tuples.
get_sorted_set_reverse(key, start=0, stop=-1, with_scores=False) Retrieves elements in descending order.
remove_from_sorted_set(key, member) Removes a member from the sorted set.
get_rank(key, member) Retrieves the rank (0-based index) of a member.
get_score(key, member) Retrieves the score of a member.
delete_sorted_set(key) Deletes the entire sorted set.
set_ttl(key, ttl) Sets a TTL for an existing sorted set.
get_ttl(key) Retrieves the TTL for a sorted set.
increment_score(key, increment, member) Increments the score of a member by a given amount.
get_sorted_set_by_score(key, min_score, max_score, with_scores=False) Retrieves members within a specific score range.

Example

from wredis.sortedset import RedisSortedSetManager

sorted_set_manager = RedisSortedSetManager(host="localhost")

# Add
sorted_set_manager.add_to_sorted_set("my_sorted_set", 1, "item1")
sorted_set_manager.add_to_sorted_set("my_sorted_set", 3, "item3")
sorted_set_manager.add_to_sorted_set("my_sorted_set", 2, "item2")

# Read
items = sorted_set_manager.get_sorted_set("my_sorted_set", with_scores=True)
items_reverse = sorted_set_manager.get_sorted_set_reverse("my_sorted_set")

# Rank and score
rank = sorted_set_manager.get_rank("my_sorted_set", "item1")
score = sorted_set_manager.get_score("my_sorted_set", "item2")

# Increment score
sorted_set_manager.increment_score("my_sorted_set", 5, "item1")

# Range by score
by_score = sorted_set_manager.get_sorted_set_by_score("my_sorted_set", 1, 3, with_scores=True)

# Remove
sorted_set_manager.remove_from_sorted_set("my_sorted_set", "item1")

# Delete entire sorted set
# sorted_set_manager.delete_sorted_set("my_sorted_set")

# TTL
sorted_set_manager.set_ttl("my_sorted_set", 300)
print(sorted_set_manager.get_ttl("my_sorted_set"))

Streams

Class: RedisStreamManager

This module allows you to interact with Redis Streams using consumer groups.

Constructor

RedisStreamManager(host="localhost", port=6379, db=0, verbose=True)

Methods

Method Description
add_to_stream(key, data, ttl=None) Adds a message to a stream. Returns the message ID. Optionally sets TTL.
on_message(stream_name, group_name, consumer_name) Decorator to register a consumer for a stream. Creates the consumer group if it doesn't exist. Starts a listener thread.
read_from_stream(key, count=1, block=None) Reads messages from a stream without a registered consumer.
wait() Keeps the program running and handles SIGINT for clean shutdown.

Example

Producer:

from wredis.streams import RedisStreamManager

stream_manager = RedisStreamManager(host="localhost")

stream_manager.add_to_stream("my_stream", {"field1": "value1"})
stream_manager.add_to_stream("my_stream", {"field2": "value3", "field4": "value4"})
stream_manager.add_to_stream("my_stream_2", {"field1": "value1"})

Consumer:

from wredis.streams import RedisStreamManager

stream_manager = RedisStreamManager(host="localhost", verbose=False)

@stream_manager.on_message(
    stream_name="my_stream", group_name="my_group", consumer_name="consumer_1"
)
def process_message(data):
    print(f"[Consumer 1] Processing: {data}")

@stream_manager.on_message(
    stream_name="my_stream_2", group_name="my_group", consumer_name="consumer_2"
)
def process_message_consumer_2(data):
    print(f"[Consumer 2] Processing: {data}")

stream_manager.wait()

License

MIT

This project is licensed under the MIT license. See the LICENSE file for more details.

Examples

This directory contains a collection of examples that demonstrate the usage of various modules and functionalities. Each subfolder corresponds to a specific module and includes example scripts to help you understand how to use that module.

Directory Structure

examples/
    bitmap/
        read.py
        write.py
    hash/
        read.py
        write.py
    pub_sub/
        consumer.py
        producer.py
    queue/
        consumer.py
        producer.py
    sets/
        read.py
        write.py
    sorted_set.py/
        read.py
        write.py
    streams/
        consume.py
        producer.py

How to Use

  1. Navigate to the module folder of interest, e.g., examples/bitmap/.
  2. Run the scripts directly using:
    python read.py
    python write.py
    

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

wredis-0.9.5.tar.gz (184.3 kB view details)

Uploaded Source

Built Distribution

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

wredis-0.9.5-py3-none-any.whl (61.1 kB view details)

Uploaded Python 3

File details

Details for the file wredis-0.9.5.tar.gz.

File metadata

  • Download URL: wredis-0.9.5.tar.gz
  • Upload date:
  • Size: 184.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for wredis-0.9.5.tar.gz
Algorithm Hash digest
SHA256 7dc9c68bcd3201617e7282323b62fea6839025f318650dd4ca06cdff0203516c
MD5 ed476706397293e18c0b09071ab4b737
BLAKE2b-256 496231568974098ab9cf86517048e1acc722b693ac0579e6cf6c1141b6f476f2

See more details on using hashes here.

File details

Details for the file wredis-0.9.5-py3-none-any.whl.

File metadata

  • Download URL: wredis-0.9.5-py3-none-any.whl
  • Upload date:
  • Size: 61.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for wredis-0.9.5-py3-none-any.whl
Algorithm Hash digest
SHA256 bf83093171a916ee297ca89827cf1484bafa6c5885ff5716035b4ea0048fe168
MD5 cfc71d226b74d8df6bae97b5621f781d
BLAKE2b-256 f21ba30aaf3dcd011aa4b75f2262a0e085877bba631f4fec98d237d3a2f4dddd

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