Run a pipeline over a input generator

    >>> # if we have a simple component
    >>> from reliure.pipeline import Composable
    >>> @Composable
    ... def print_each(letters):
    ...     for letter in letters:
    ...         print(letter)
    ...         yield letter
    >>> # that we want to run over a given input:
    >>> input = "abcde"
    >>> # we just have to do :
    >>> res = run(print_each, input)
    a
    b
    c
    d
    e
    
    it is also possible to run any reliure pipeline this way:
    >>> import string
    >>> pipeline = Composable(lambda letters: (l.upper() for l in letters)) | print_each
    >>> res = run(pipeline, input)
    A
    B
    C
    D
    E

def run(pipeline, input_gen, options={}):
    """ Run a pipeline over a input generator

    >>> # if we have a simple component
    >>> from reliure.pipeline import Composable
    >>> @Composable
    ... def print_each(letters):
    ...     for letter in letters:
    ...         print(letter)
    ...         yield letter
    >>> # that we want to run over a given input:
    >>> input = "abcde"
    >>> # we just have to do :
    >>> res = run(print_each, input)
    a
    b
    c
    d
    e
    
    it is also possible to run any reliure pipeline this way:
    >>> import string
    >>> pipeline = Composable(lambda letters: (l.upper() for l in letters)) | print_each
    >>> res = run(pipeline, input)
    A
    B
    C
    D
    E
    """
    logger = logging.getLogger("reliure.run")
    t0 = time()
    res = [output for output in pipeline(input_gen, **options)]
    logger.info("Pipeline executed in %1.3f sec" % (time() - t0))
    return res