Getting Started =============== Installation ------------ To install, use pip: .. code-block:: bash pip install redpipe or from source: .. code-block:: bash python setup.py install Get the Source Code ------------------- **RedPipe** is actively developed on GitHub. You can either clone the public repository: .. code-block:: bash git clone git://github.com/72squared/redpipe.git Or, download the tarball: .. code-block:: bash curl -OL https://github.com/72squared/redpipe/tarball/master Once you have a copy of the source, install it into your site-packages easily: .. code-block:: bash python setup.py install Connect redis-py to RedPipe --------------------------- To use redpipe, You need to bind your redis client instance to *RedPipe*. Use the standard `redis-py `_ client. .. code-block:: python client = redis.Redis() redpipe.connect_redis(client) You only need to do this setup once during application bootstrapping. This example just sets one connection up as a default, since that is the most common case. But you can connect multiple redis connections to *RedPipe*. You can use `StrictRedis` if you want too. It doesn't matter. Whatever you use normally in your application. The goal is to reuse your application's existing redis connection. RedPipe can be used to build your entire persistence layer in your application. Or you can use *RedPipe* along side your existing code. More on this later. Using RedPipe ------------- Using *RedPipe* is easy. We can pipeline multiple calls to redis and assign the results to variables. .. code-block:: python with redpipe.pipeline() as pipe: foo = pipe.incr('foo') bar = pipe.incr('bar) pipe.execute() print([foo, bar]) *RedPipe* allocates a pipeline object. Then we increment a few keys on the pipeline object. The code looks mostly like the code you might write with redis-py pipelines. The methods you call on the pipeline object are the same. But, notice that each `incr` call immediately gets a reference object back in return from each call. That part looks similar to how `redis-py` works without a pipeline. The variables (in this case `foo` and `bar`) are empty until the pipeline executes. If you try to do any operations on them beforehand, it will raise an exception. Once we complete the `execute()` call we can consume the pipeline results. These variables, `foo` and `bar`, behave just like the underlying result once the pipeline executes. You can iterate over it, add it, multiply it, etc. Reusable Functions ------------------ You can write a function that can work as a standalone chunk of logic and can also be linked to other pipelines. Here's a quick example of what I mean: .. code-block:: python def get_foo(pipe=None): with redpipe.pipeline(pipe=pipe) as pipe: pipe.setnx('foo', 'bar') foo = pipe.get('foo') pipe.execute() return foo It is easy to see how this works as an standalone function. It looks almost like what you might write if you were just using redis-py. .. code-block:: python print(get_foo()) This will pipeline the following commands to redis: * SETNX foo bar * GET foo But the magic happens when you link this function with other pipeline objects. .. code-block:: python with redpipe.pipeline() as pipe: foo = get_foo(pipe) bar = pipe.get('bar') pipe.execute() This example will pipeline these three commands together: * SETNX foo bar * GET foo * GET bar In this example, the `foo` and `bar` variables are both `redpipe.Future` objects. They are empty until the `pipe.execute()` happens outside of the function. The `pipe.execute()` called inside the `get_foo` function in this case is a `NestedPipeline`. It passes its stack of commands to the parent pipeline. That's because we passed a pipeline object into the `get_foo` function. The function passed that into `redpipe.pipeline` and it returned a NestedPipeline to wrap the one passed in.