Network communication library based on greenlets, with zeromq and redis support
Failed to load latest commit information.
tests Implement HTTPS client Oct 28, 2013
.gitignore Updated gitignore file Nov 7, 2011
.travis.yml Add redis dependency to travis config Feb 10, 2014
LICENSE Added `README` and `LICENSE` tests Jan 17, 2011
README.rst Version bumped to v0.1.4 Jan 9, 2014



This is mostly networking library. It implements main loop based on greenlets. Mostly suitable for servers of some kind.

API's implemented so far:

  • Zeromq
  • Redis
  • MySQL
  • Mongo
  • HTTP/HTTPS (client)
  • DNS (async)


  • Only for Python3 (works with 3.2, needs 3.3 for zorro.web)
  • Full set of synchronisation primitives (incl. Futures, Lock, Conditions...)
  • Pipelining for all network protocols
  • Pure python implementation (still outperforms C implementations for many tasks because of pipelining)
  • Basic web framework for zerogw
  • Pluggable polling mechanisms


from zorro import Hub

hub = Hub()
def main():
    # setup other coroutines here

Basic zmq replier example. Each reply will get it's own microthread:

from zorro import Hub, zmq

def replier(preference,*other_multipart_args):
    if preference == b'binary':
        return b'hello'
    elif preference == b'unicode':
        return 'hello' # same as above, encoded in 'utf-8'
    elif preference == b'tuple':
        return 'hello', 'world' # two parts will be sent
        # exeption will be logged, but reply is not sent
        # so you must timeout on the other side
        # other requests will be ok (we use ZMQ_XREP actually)
        raise ValueError(preference)

hub = Hub()
def main():
    sock = zmq.rep_socket(replier)

Some advanced redis usage example:

from zorro import Hub, redis, Future
from functools import partial

hub = Hub()
redis = redis.Redis()

def getkey(index):
    # Semi-parallel requests will be pipelined so it's quite fast
    a = redis.execute('INCR', 'test:{0}'.format(index-1), 1)
    redis.execute('DECR', 'test:{0}'.format(index+1), a)
    return int(redis.execute('GET', 'test:{0}'.format(index)))
def main():
    futures = [Future(partial(getkey, i)) for i in range(100)]
    print("TOTAL", sum(f.get() for f in futures))