Examples¶
The Connection
class¶
A Connection
instance will take care of the
connection and will automatically reconnect, using a new transport when the
connection drops. This connection class also acts as a proxy to at
RedisProtocol
instance; any Redis
command of the protocol can be called directly at the connection.
import asyncio
import asyncio_redis
@asyncio.coroutine
def example():
# Create Redis connection
connection = yield from asyncio_redis.Connection.create(host='localhost', port=6379)
# Set a key
yield from connection.set('my_key', 'my_value')
# When finished, close the connection.
connection.close()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(example())
See the reference to learn more about the other Redis commands.
Connection pooling¶
Requests will automatically be distributed among all connections in a
Pool
. If a connection is blocking because of
–for instance– a blocking rpop, another connection will be used for new
commands.
Note
This is the recommended way to connect to the Redis server.
import asyncio
import asyncio_redis
@asyncio.coroutine
def example():
# Create Redis connection
connection = yield from asyncio_redis.Pool.create(host='localhost', port=6379, poolsize=10)
# Set a key
yield from connection.set('my_key', 'my_value')
# When finished, close the connection pool.
connection.close()
Transactions¶
A transaction can be started by calling multi
. This returns a Transaction
instance which is in fact just a proxy to the
RedisProtocol
, except that every Redis
method of the protocol now became a coroutine that returns a future. The
results of these futures can be retrieved after the transaction is commited
with exec
.
import asyncio
import asyncio_redis
@asyncio.coroutine
def example(loop):
# Create Redis connection
connection = yield from asyncio_redis.Pool.create(host='localhost', port=6379, poolsize=10)
# Create transaction
transaction = yield from connection.multi()
# Run commands in transaction (they return future objects)
f1 = yield from transaction.set('key', 'value')
f2 = yield from transaction.set('another_key', 'another_value')
# Commit transaction
yield from transaction.exec()
# Retrieve results
result1 = yield from f1
result2 = yield from f2
# When finished, close the connection pool.
connection.close()
It’s recommended to use a large enough poolsize. A connection will be occupied as long as there’s a transaction running in there.
Pubsub¶
By calling start_subscribe
(either on the protocol, through
the Connection
class or through the Pool
class), you can start a pubsub listener.
import asyncio
import asyncio_redis
@asyncio.coroutine
def example():
# Create connection
connection = yield from asyncio_redis.Connection.create(host='localhost', port=6379)
# Create subscriber.
subscriber = yield from connection.start_subscribe()
# Subscribe to channel.
yield from subscriber.subscribe([ 'our-channel' ])
# Inside a while loop, wait for incoming events.
while True:
reply = yield from subscriber.next_published()
print('Received: ', repr(reply.value), 'on channel', reply.channel)
# When finished, close the connection.
connection.close()
LUA Scripting¶
The register_script
function – which can be used to register a LUA script – returns a
Script
instance. You can call its run
method to execute this script.
import asyncio
import asyncio_redis
code = \
"""
local value = redis.call('GET', KEYS[1])
value = tonumber(value)
return value * ARGV[1]
"""
@asyncio.coroutine
def example():
connection = yield from asyncio_redis.Connection.create(host='localhost', port=6379)
# Set a key
yield from connection.set('my_key', '2')
# Register script
multiply = yield from connection.register_script(code)
# Run script
script_reply = yield from multiply.run(keys=['my_key'], args=['5'])
result = yield from script_reply.return_value()
print(result) # prints 2 * 5
# When finished, close the connection.
connection.close()
Raw bytes or UTF-8¶
The redis protocol only knows about bytes, but normally you want to use strings
in your Python code. asyncio_redis
is helpful and installs an encoder that
does this conversion automatically, using the UTF-8 codec. However, sometimes
you want to access raw bytes. This is possible by passing a
BytesEncoder
instance to the
connection, pool or protocol.
import asyncio
import asyncio_redis
from asyncio_redis.encoders import BytesEncoder
@asyncio.coroutine
def example():
# Create Redis connection
connection = yield from asyncio_redis.Connection.create(host='localhost', port=6379, encoder=BytesEncoder())
# Set a key
yield from connection.set(b'my_key', b'my_value')
# When finished, close the connection.
connection.close()
Scanning for keys¶
Redis has a few nice scanning utilities to discover keys in the database. They
are rather low-level, but asyncio_redis
exposes a simple
Cursor
class that allows you to iterate over
all the keys matching a certain pattern. Each call of the
fetchone()
coroutine will return the next
match. You don’t have have to worry about accessing the server every x pages.
The following example will print all the keys in the database:
import asyncio
import asyncio_redis
from asyncio_redis.encoders import BytesEncoder
@asyncio.coroutine
def example():
cursor = yield from protocol.scan(match='*')
while True:
item = yield from cursor.fetchone()
if item is None:
break
else:
print(item)
See the scanning utilities: scan()
,
sscan()
,
hscan()
and
zscan()
The RedisProtocol
class¶
The most low level way of accessing the redis server through this library is probably by creating a connection with the RedisProtocol yourself. You can do it as follows:
import asyncio
import asyncio_redis
@asyncio.coroutine
def example():
loop = asyncio.get_event_loop()
# Create Redis connection
transport, protocol = yield from loop.create_connection(
asyncio_redis.RedisProtocol, 'localhost', 6379)
# Set a key
yield from protocol.set('my_key', 'my_value')
# Get a key
result = yield from protocol.get('my_key')
print(result)
if __name__ == '__main__':
asyncio.get_event_loop().run_until_complete(example())
Note
It is not recommended to use the Protocol class directly, because the
low-level Redis implementation could change. Prefer the
Connection
or Pool
class as demonstrated above if possible.