aioredis
========

asyncio (PEP 3156) Redis client library.

.. image:: https://travis-ci.org/aio-libs/aioredis.svg?branch=master
   :target: https://travis-ci.org/aio-libs/aioredis


.. image:: https://codecov.io/gh/aio-libs/aioredis/branch/master/graph/badge.svg
   :target: https://codecov.io/gh/aio-libs/aioredis

.. image:: https://ci.appveyor.com/api/projects/status/wngyx6s98o6hsxmt/branch/master?svg=true
   :target: https://ci.appveyor.com/project/popravich/aioredis

Features
--------

================================  ==============================
hiredis_ parser                     Yes
Pure-python parser                  Yes
Low-level & High-level APIs         Yes
Connections Pool                    Yes
Pipelining support                  Yes
Pub/Sub support                     Yes
SSL/TLS support                     Yes
Sentinel support                    Yes [1]_
Redis Cluster support               WIP
Trollius (python 2.7)               No
Tested CPython versions             `3.5, 3.6 <travis_>`_ [2]_
Tested PyPy3 versions               `5.9.0 <travis_>`_
Tested for Redis server             `2.6, 2.8, 3.0, 3.2, 4.0 <travis_>`_
Support for dev Redis server        through low-level API
================================  ==============================


.. [1] Sentinel support is available in master branch.
   This feature is not yet stable and may have some issues.

.. [2] For Python 3.3, 3.4 support use aioredis v0.3.

Documentation
-------------

http://aioredis.readthedocs.io/

Usage examples
--------------

Simple low-level interface:

.. code:: python

    import asyncio
    import aioredis

    loop = asyncio.get_event_loop()

    async def go():
        conn = await aioredis.create_connection(
            'redis://localhost', loop=loop)
        await conn.execute('set', 'my-key', 'value')
        val = await conn.execute('get', 'my-key')
        print(val)
        conn.close()
        await conn.wait_closed()
    loop.run_until_complete(go())
    # will print 'value'

Simple high-level interface:

.. code:: python

    import asyncio
    import aioredis

    loop = asyncio.get_event_loop()

    async def go():
        redis = await aioredis.create_redis(
            'redis://localhost', loop=loop)
        await redis.set('my-key', 'value')
        val = await redis.get('my-key')
        print(val)
        redis.close()
        await redis.wait_closed()
    loop.run_until_complete(go())
    # will print 'value'

Connections pool:

.. code:: python

    import asyncio
    import aioredis

    loop = asyncio.get_event_loop()

    async def go():
        pool = await aioredis.create_pool(
            'redis://localhost',
            minsize=5, maxsize=10,
            loop=loop)
        await pool.execute('set', 'my-key', 'value')
        print(await pool.execute('get', 'my-key'))
        # graceful shutdown
        pool.close()
        await pool.wait_closed()

    loop.run_until_complete(go())

Simple high-level interface with connections pool:

.. code:: python

    import asyncio
    import aioredis

    loop = asyncio.get_event_loop()

    async def go():
        redis = await aioredis.create_redis_pool(
            'redis://localhost',
            minsize=5, maxsize=10,
            loop=loop)
        await redis.set('my-key', 'value')
        val = await redis.get('my-key')
        print(val)
        redis.close()
        await redis.wait_closed()
    loop.run_until_complete(go())
    # will print 'value'

Requirements
------------

* Python_ 3.5.3+
* hiredis_

.. note::

    hiredis is preferred requirement.
    Pure-python protocol parser is implemented as well and can be used
    through ``parser`` parameter.

Benchmarks
----------

Benchmarks can be found here: https://github.com/popravich/python-redis-benchmark

Discussion list
---------------

*aio-libs* google group: https://groups.google.com/forum/#!forum/aio-libs

Or gitter room: https://gitter.im/aio-libs/Lobby

License
-------

The aioredis is offered under MIT license.

.. _Python: https://www.python.org
.. _hiredis: https://pypi.python.org/pypi/hiredis
.. _travis: https://travis-ci.org/aio-libs/aioredis

Changes
-------

1.1.0 (2018-02-16)
^^^^^^^^^^^^^^^^^^

**NEW**:

* Implement new commands: ``wait``, ``touch``, ``swapdb``, ``unlink``
  (see `#376 <https://github.com/aio-libs/aioredis/pull/376>`_);

* Add ``async_op`` argument to ``flushall`` and ``flushdb`` commands
  (see `#364 <https://github.com/aio-libs/aioredis/pull/364>`_,
  and `#370 <https://github.com/aio-libs/aioredis/pull/370>`_);

**FIX**:

* **Important!** Fix Sentinel sentinel client with pool ``minsize``
  greater than 1
  (see `#380 <https://github.com/aio-libs/aioredis/pull/380>`_);

* Fix ``SentinelPool.discover_timeout`` usage
  (see `#379 <https://github.com/aio-libs/aioredis/pull/379>`_);

* Fix ``Receiver`` hang on disconnect
  (see `#354 <https://github.com/aio-libs/aioredis/pull/354>`_,
  and `#366 <https://github.com/aio-libs/aioredis/pull/366>`_);

* Fix an issue with ``subscribe``/``psubscribe`` with empty pool
  (see `#351 <https://github.com/aio-libs/aioredis/pull/351>`_,
  and `#355 <https://github.com/aio-libs/aioredis/pull/355>`_);

* Fix an issue when ``StreamReader``'s feed_data is called before set_parser
  (see `#347 <https://github.com/aio-libs/aioredis/pull/347>`_);

**MISC**:

* Update dependencies versions;

* Multiple test fixes;


1.0.0 (2017-11-17)
^^^^^^^^^^^^^^^^^^

**NEW**:

* **Important!** Drop Python 3.3, 3.4 support;
  (see `#321 <https://github.com/aio-libs/aioredis/pull/321>`_,
  `#323 <https://github.com/aio-libs/aioredis/pull/323>`_
  and `#326 <https://github.com/aio-libs/aioredis/pull/326>`_);

* **Important!** Connections pool has been refactored; now ``create_redis``
  function will yield ``Redis`` instance instead of ``RedisPool``
  (see `#129 <https://github.com/aio-libs/aioredis/pull/129>`_);

* **Important!** Change sorted set commands reply format:
  return list of tuples instead of plain list for commands
  accepting ``withscores`` argument
  (see `#334 <https://github.com/aio-libs/aioredis/pull/334>`_);

* **Important!** Change ``hscan`` command reply format:
  return list of tuples instead of mixed key-value list
  (see `#335 <https://github.com/aio-libs/aioredis/pull/335>`_);

* Implement Redis URI support as supported ``address`` argument value
  (see `#322 <https://github.com/aio-libs/aioredis/pull/322>`_);

* Dropped ``create_reconnecting_redis``, ``create_redis_pool`` should be
  used instead;

* Implement custom ``StreamReader``
  (see `#273 <https://github.com/aio-libs/aioredis/pull/273>`_);

* Implement Sentinel support
  (see `#181 <https://github.com/aio-libs/aioredis/pull/181>`_);

* Implement pure-python parser
  (see `#212 <https://github.com/aio-libs/aioredis/pull/212>`_);

* Add ``migrate_keys`` command
  (see `#187 <https://github.com/aio-libs/aioredis/pull/187>`_);

* Add ``zrevrangebylex`` command
  (see `#201 <https://github.com/aio-libs/aioredis/pull/201>`_);

* Add ``command``, ``command_count``, ``command_getkeys`` and
  ``command_info`` commands
  (see `#229 <https://github.com/aio-libs/aioredis/pull/229>`_);

* Add ``ping`` support in pubsub connection
  (see `#264 <https://github.com/aio-libs/aioredis/pull/264>`_);

* Add ``exist`` parameter to ``zadd`` command
  (see `#288 <https://github.com/aio-libs/aioredis/pull/288>`_);

* Add ``MaxClientsError`` and implement ``ReplyError`` specialization
  (see `#325 <https://github.com/aio-libs/aioredis/pull/325>`_);

* Add ``encoding`` parameter to sorted set commands
  (see `#289 <https://github.com/aio-libs/aioredis/pull/289>`_);

**FIX**:

* Fix ``CancelledError`` in ``conn._reader_task``
  (see `#301 <https://github.com/aio-libs/aioredis/pull/301>`_);

* Fix pending commands cancellation with ``CancelledError``,
  use explicit exception instead of calling ``cancel()`` method
  (see `#316 <https://github.com/aio-libs/aioredis/pull/316>`_);

* Correct error message on Sentinel discovery of master/slave with password
  (see `#327 <https://github.com/aio-libs/aioredis/pull/327>`_);

* Fix ``bytearray`` support as command argument
  (see `#329 <https://github.com/aio-libs/aioredis/pull/329>`_);

* Fix critical bug in patched asyncio.Lock
  (see `#256 <https://github.com/aio-libs/aioredis/pull/256>`_);

* Fix Multi/Exec transaction canceled error
  (see `#225 <https://github.com/aio-libs/aioredis/pull/225>`_);

* Add missing arguments to ``create_redis`` and ``create_redis_pool``;

* Fix deprecation warning
  (see `#191 <https://github.com/aio-libs/aioredis/pull/191>`_);

* Make correct ``__aiter__()``
  (see `#192 <https://github.com/aio-libs/aioredis/pull/192>`_);

* Backward compatibility fix for ``with (yield from pool) as conn:``
  (see `#205 <https://github.com/aio-libs/aioredis/pull/205>`_);

* Fixed pubsub receiver stop()
  (see `#211 <https://github.com/aio-libs/aioredis/pull/211>`_);

**MISC**:

* Multiple test fixes;

* Add PyPy3 to build matrix;

* Update dependencies versions;

* Add missing Python 3.6 classifier;


0.3.5 (2017-11-08)
^^^^^^^^^^^^^^^^^^

**FIX**:

* Fix for indistinguishable futures cancellation with
  ``asyncio.CancelledError``
  (see `#316 <https://github.com/aio-libs/aioredis/pull/316>`_),
  cherry-picked from master;


0.3.4 (2017-10-25)
^^^^^^^^^^^^^^^^^^

**FIX**:

* Fix time command result decoding when using connection-wide encoding setting
  (see `#266 <https://github.com/aio-libs/aioredis/pull/266>`_);


0.3.3 (2017-06-30)
^^^^^^^^^^^^^^^^^^

**FIX**:

* Critical bug fixed in patched asyncio.Lock
  (see `#256 <https://github.com/aio-libs/aioredis/pull/256>`_);


0.3.2 (2017-06-21)
^^^^^^^^^^^^^^^^^^

**NEW**:

* Added ``zrevrangebylex`` command
  (see `#201 <https://github.com/aio-libs/aioredis/pull/201>`_),
  cherry-picked from master;

* Add connection timeout
  (see `#221 <https://github.com/aio-libs/aioredis/pull/221>`_),
  cherry-picked from master;

**FIX**:

* Fixed pool close warning
  (see `#239 <https://github.com/aio-libs/aioredis/pull/239>`_
  and `#236 <https://github.com/aio-libs/aioredis/issues/236>`_),
  cherry-picked from master;

* Fixed asyncio Lock deadlock issue
  (see `#231 <https://github.com/aio-libs/aioredis/issues/231>`_
  and `#241 <https://github.com/aio-libs/aioredis/pull/241>`_);


0.3.1 (2017-05-09)
^^^^^^^^^^^^^^^^^^

**FIX**:

* Fix pubsub Receiver missing iter() method
  (see `#203 <https://github.com/aio-libs/aioredis/issues/203>`_);


0.3.0 (2017-01-11)
^^^^^^^^^^^^^^^^^^

**NEW**:

* Pub/Sub connection commands accept ``Channel`` instances
  (see `#168 <https://github.com/aio-libs/aioredis/pull/168>`_);

* Implement new Pub/Sub MPSC (multi-producers, single-consumer) Queue --
  ``aioredis.pubsub.Receiver``
  (see `#176 <https://github.com/aio-libs/aioredis/pull/176>`_);

* Add ``aioredis.abc`` module providing abstract base classes
  defining interface for basic lib components;
  (see `#176 <https://github.com/aio-libs/aioredis/pull/176>`_);

* Implement Geo commands support
  (see `#177 <https://github.com/aio-libs/aioredis/pull/177>`_
  and `#179 <https://github.com/aio-libs/aioredis/pull/179>`_);

**FIX**:

* Minor tests fixes;

**MISC**:

* Update examples and docs to use ``async``/``await`` syntax
  also keeping ``yield from`` examples for history
  (see `#173 <https://github.com/aio-libs/aioredis/pull/173>`_);

* Reflow Travis CI configuration; add Python 3.6 section
  (see `#170 <https://github.com/aio-libs/aioredis/pull/170>`_);

* Add AppVeyor integration to run tests on Windows
  (see `#180 <https://github.com/aio-libs/aioredis/pull/180>`_);

* Update multiple development requirements;


0.2.9 (2016-10-24)
^^^^^^^^^^^^^^^^^^

**NEW**:

* Allow multiple keys in ``EXISTS`` command
  (see `#156 <https://github.com/aio-libs/aioredis/issues/156>`_
  and `#157 <https://github.com/aio-libs/aioredis/issues/157>`_);

**FIX**:

* Close RedisPool when connection to Redis failed
  (see `#136 <https://github.com/aio-libs/aioredis/issues/136>`_);

* Add simple ``INFO`` command argument validation
  (see `#140 <https://github.com/aio-libs/aioredis/issues/140>`_);

* Remove invalid uses of ``next()``

**MISC**:

* Update devel.rst docs; update Pub/Sub Channel docs (cross-refs);

* Update MANIFEST.in to include docs, examples and tests in source bundle;


0.2.8 (2016-07-22)
^^^^^^^^^^^^^^^^^^

**NEW**:

* Add ``hmset_dict`` command
  (see `#130 <https://github.com/aio-libs/aioredis/issues/130>`_);

* Add ``RedisConnection.address`` property;

* RedisPool ``minsize``/``maxsize`` must not be ``None``;

* Implement ``close()``/``wait_closed()``/``closed`` interface for pool
  (see `#128 <https://github.com/aio-libs/aioredis/issues/128>`_);

**FIX**:

* Add test for ``hstrlen``;

* Test fixes

**MISC**:

* Enable Redis 3.2.0 on Travis;

* Add spell checking when building docs
  (see `#132 <https://github.com/aio-libs/aioredis/issues/132>`_);

* Documentation updated;


0.2.7 (2016-05-27)
^^^^^^^^^^^^^^^^^^

* ``create_pool()`` minsize default value changed to 1;

* Fixed cancellation of wait_closed
  (see `#118 <https://github.com/aio-libs/aioredis/issues/118>`_);

* Fixed ``time()`` convertion to float
  (see `#126 <https://github.com/aio-libs/aioredis/issues/126>`_);

* Fixed ``hmset()`` method to return bool instead of ``b'OK'``
  (see `#126`_);

* Fixed multi/exec + watch issue (changed watch variable was causing
  ``tr.execute()`` to fail)
  (see `#121 <https://github.com/aio-libs/aioredis/issues/121>`_);

* Replace ``asyncio.Future`` uses with utility method
  (get ready to Python 3.5.2 ``loop.create_future()``);

* Tests switched from unittest to pytest (see `#126`_);

* Documentation updates;


0.2.6 (2016-03-30)
^^^^^^^^^^^^^^^^^^

* Fixed Multi/Exec transactions cancellation issue
  (see `#110 <https://github.com/aio-libs/aioredis/issues/110>`_
  and `#114 <https://github.com/aio-libs/aioredis/issues/114>`_);

* Fixed Pub/Sub subscribe concurrency issue
  (see `#113 <https://github.com/aio-libs/aioredis/issues/113>`_
  and `#115 <https://github.com/aio-libs/aioredis/issues/115>`_);

* Add SSL/TLS support
  (see  `#116 <https://github.com/aio-libs/aioredis/issues/116>`_);

* ``aioredis.ConnectionClosedError`` raised in ``execute_pubsub`` as well
  (see `#108 <https://github.com/aio-libs/aioredis/issues/108>`_);

* ``Redis.slaveof()`` method signature changed: now to disable
  replication one should call ``redis.slaveof(None)`` instead of ``redis.slaveof()``;

* More tests added;


0.2.5 (2016-03-02)
^^^^^^^^^^^^^^^^^^

* Close all Pub/Sub channels on connection close
  (see `#88 <https://github.com/aio-libs/aioredis/issues/88>`_);

* Add ``iter()`` method to ``aioredis.Channel`` allowing to use it
  with ``async for``
  (see `#89 <https://github.com/aio-libs/aioredis/issues/89>`_);

* Inline code samples in docs made runnable and downloadable
  (see `#92 <https://github.com/aio-libs/aioredis/issues/92>`_);

* Python 3.5 examples converted to use ``async``/``await`` syntax
  (see `#93 <https://github.com/aio-libs/aioredis/issues/93>`_);

* Fix Multi/Exec to honor encoding parameter
  (see `#94 <https://github.com/aio-libs/aioredis/issues/94>`_
  and `#97 <https://github.com/aio-libs/aioredis/issues/97>`_);

* Add debug message in ``create_connection``
  (see `#90 <https://github.com/aio-libs/aioredis/issues/90>`_);

* Replace ``asyncio.async`` calls with wrapper that respects asyncio version
  (see `#101 <https://github.com/aio-libs/aioredis/issues/101>`_);

* Use NODELAY option for TCP sockets
  (see `#105 <https://github.com/aio-libs/aioredis/issues/105>`_);

* New ``aioredis.ConnectionClosedError`` exception added. Raised if
  connection to Redis server is lost
  (see `#108 <https://github.com/aio-libs/aioredis/issues/108>`_
  and `#109 <https://github.com/aio-libs/aioredis/issues/109>`_);

* Fix RedisPool to close and drop connection in subscribe mode on release;

* Fix ``aioredis.util.decode`` to recursively decode list responses;

* More examples added and docs updated;

* Add google groups link to README;

* Bump year in LICENSE and docs;


0.2.4 (2015-10-13)
^^^^^^^^^^^^^^^^^^

* Python 3.5 ``async`` support:

  - New scan commands API (``iscan``, ``izscan``, ``ihscan``);

  - Pool made awaitable (allowing ``with await pool: ...`` and ``async
    with pool.get() as conn:`` constructs);

* Fixed dropping closed connections from free pool
  (see `#83 <https://github.com/aio-libs/aioredis/issues/83>`_);

* Docs updated;


0.2.3 (2015-08-14)
^^^^^^^^^^^^^^^^^^

* Redis cluster support work in progress;

* Fixed pool issue causing pool growth over max size & ``acquire`` call hangs
  (see `#71 <https://github.com/aio-libs/aioredis/issues/71>`_);

* ``info`` server command result parsing implemented;

* Fixed behavior of util functions
  (see `#70 <https://github.com/aio-libs/aioredis/issues/70>`_);

* ``hstrlen`` command added;

* Few fixes in examples;

* Few fixes in documentation;


0.2.2 (2015-07-07)
^^^^^^^^^^^^^^^^^^

* Decoding data with ``encoding`` parameter now takes into account
  list (array) replies
  (see `#68 <https://github.com/aio-libs/aioredis/pull/68>`_);

* ``encoding`` parameter added to following commands:

  - generic commands: keys, randomkey;

  - hash commands: hgetall, hkeys, hmget, hvals;

  - list commands: blpop, brpop, brpoplpush, lindex, lpop, lrange, rpop, rpoplpush;

  - set commands: smembers, spop, srandmember;

  - string commands: getrange, getset, mget;

* Backward incompatibility:

  ``ltrim`` command now returns bool value instead of 'OK';

* Tests updated;


0.2.1 (2015-07-06)
^^^^^^^^^^^^^^^^^^

* Logging added (aioredis.log module);

* Fixed issue with ``wait_message`` in pub/sub
  (see `#66 <https://github.com/aio-libs/aioredis/issues/66>`_);


0.2.0 (2015-06-04)
^^^^^^^^^^^^^^^^^^

* Pub/Sub support added;

* Fix in ``zrevrangebyscore`` command
  (see `#62 <https://github.com/aio-libs/aioredis/pull/62>`_);

* Fixes/tests/docs;


0.1.5 (2014-12-09)
^^^^^^^^^^^^^^^^^^

* AutoConnector added;

* wait_closed method added for clean connections shutdown;

* ``zscore`` command fixed;

* Test fixes;


0.1.4 (2014-09-22)
^^^^^^^^^^^^^^^^^^

* Dropped following Redis methods -- ``Redis.multi()``,
  ``Redis.exec()``, ``Redis.discard()``;

* ``Redis.multi_exec`` hack'ish property removed;

* ``Redis.multi_exec()`` method added;

* High-level commands implemented:

  * generic commands (tests);

  * transactions commands (api stabilization).

* Backward incompatibilities:

  * Following sorted set commands' API changed:

    ``zcount``, ``zrangebyscore``, ``zremrangebyscore``, ``zrevrangebyscore``;

  * set string command' API changed;



0.1.3 (2014-08-08)
^^^^^^^^^^^^^^^^^^

* RedisConnection.execute refactored to support commands pipelining
  (see `#33 <http://github.com/aio-libs/aioredis/issues/33>`_);

* Several fixes;

* WIP on transactions and commands interface;

* High-level commands implemented and tested:

  * hash commands;
  * hyperloglog commands;
  * set commands;
  * scripting commands;
  * string commands;
  * list commands;


0.1.2 (2014-07-31)
^^^^^^^^^^^^^^^^^^

* ``create_connection``, ``create_pool``, ``create_redis`` functions updated:
  db and password arguments made keyword-only
  (see `#26 <http://github.com/aio-libs/aioredis/issues/26>`_);

* Fixed transaction handling
  (see `#32 <http://github.com/aio-libs/aioredis/issues/32>`_);

* Response decoding
  (see `#16 <http://github.com/aio-libs/aioredis/issues/16>`_);


0.1.1 (2014-07-07)
^^^^^^^^^^^^^^^^^^

* Transactions support (in connection, high-level commands have some issues);
* Docs & tests updated.


0.1.0 (2014-06-24)
^^^^^^^^^^^^^^^^^^

* Initial release;
* RedisConnection implemented;
* RedisPool implemented;
* Docs for RedisConnection & RedisPool;
* WIP on high-level API.

