Pipelines can be used to chain a series of functions to process a piece of data. For instance you can build a pipeline to process web requests easily including some middleware for instance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52  | class Pipeline(object):
  def __init__(self, _func_list=None):
    if _func_list is None:
      _func_list = []
    self._func_list = _func_list
  def __call__(self, *args, **kwargs):
    f = None
    while f == None:
      try:
        f = self.pop(0)
      except IndexError:
        raise StopIteration()
      if callable(f):
        return f(self, *args, **kwargs)
      else:
        f = None
  def __iter__(self):
    for f in self._func_list:
      yield f
  def __eq__(self, other):
    return self._func_list == other._func_list
  def __add__(self, other):
    return Pipeline(self._func_list + list(other))
  def push(self, f):
    return self._func_list.insert(0, f)
  def pop(self, *args, **kwargs):
    return self._func_list.pop(*args, **kwargs)
  def append(self, *args, **kwargs):
    return self._func_list.append(*args, **kwargs)
if __name__ == '__main__':
  def add_1(pipeline, x):
    return pipeline(x + 1)
  def mul_2(pipeline, x):
    return pipeline(x * 2)
  def identity(pipeline, x):
    return x
  p = Pipeline([add_1, mul_2, add_1, mul_2, identity])
  print p(1)
  # 10
 | 
The way this works is: You create the pipeline with: pipeline = Pipeline([f1, f2, f3]). The first pipeline() call will call f1, the second call calls f2, etc...
I use this recipe for WSGI applications. Basically, I create a pipeline including some functions handling authentication, database access, logging, URL dispatching etc. When a request comes in, I copy the pipeline and just call return pipeline(environ, start_response).
More generally, this could be used for just about any event-driven application/framework.
Download
Copy to clipboard