- both sync and async API
- sync api using the standard library
socket
module (TPC, TPC+TLS, Unix domain sockets) async
/await
usingtrio
's stream primitives (TCP, TCP+TLS, Unix domain sockets)- minimal api so you don't have to relearn how to write redis commands
- supports all redis commands including modules except
SUBSCRIBE
,PSUBSCRIBE
andMONITOR
1 - parses responses back into python types if you like (powered by pydantic)
- works with every redis version and supports both
RESP2
andRESP3
protocols
pip install reddish # install just with support for socket
pip install reddish[trio] # install with support for trio
import socket
from reddish.socket import Redis, Command
redis = Redis(socket.create_connection(('localhost', 6379)))
assert b'PONG' == redis.execute(Command('PING'))
import trio
from reddish.trio import Redis, Command
redis = Redis(await trio.open_tcp_stream('localhost', 6379))
assert b'PONG' == await redis.execute(Command('PING'))
# simple command without any arguments
Command('PING')
# commands with positional arguments
Command('ECHO {}', 'hello world')
# commands with keyword arguments
Command('SET {key} {value}', key='foo', value=42)
# return response unchanged from redis
assert b'42' == await redis.execute(Command('ECHO {}', 42))
# parse response as type
assert 42 == await redis.execute(Command('ECHO {}', 42).into(int))
# use any type that works with pydantic
from pydantic import Json
import json
data = json.dumps({'alice': 30, 'bob': 42})
response == await redis.execute(Command('ECHO {}', data).into(Json))
assert response == json.loads(data)
from reddish.trio import Args
# inlining arguments
Command('DEL {keys}', keys=Args(['foo', 'bar'])) # DEL foo bar
# inlining pairwise arguments
data = {'name': 'bob', 'age': 42}
Command('XADD foo * {fields}', fields=Args.from_dict(data)) # XADD foo * name bob age 42
foo, bar = await redis.execute_many(Command('GET', 'foo'), Command('GET', 'bar'))
from reddish.trio import MultiExec
tx = MultiExec(
Command('ECHO {}', 'foo'),
Command('ECHO {}', 'bar')
)
foo, bar = await redis.execute(tx)
# pipelining together with transactions
[foo, bar], baz = await redis.execute_many(tx, Command('ECHO {}', 'baz'))
Footnotes
-
Commands like
SUBSCRIBE
orMONITOR
take over the redis connection for listeting to new events barring regular commands from being issued over the connection. ↩