def tf_tensors(reader, shuffling_queue_capacity=0, min_after_dequeue=0):
    """Bridges between python-only interface of the Reader (next(Reader)) and tensorflow world.

    This function returns a named tuple of tensors from the dataset, e.g.,

    >>> row_tensors
    >>> Out[2]: TestSchema_view(field_1=<tf.Tensor 'PyFunc:0' shape=() dtype=string>,
    >>>         field_2=<tf.Tensor 'StringSplit:1' shape=(?,) dtype=string>,
    >>>         field_3=<tf.Tensor 'PyFunc:2' shape=() dtype=int64>, ...)

    If the reader was created with ``ngram=NGram(...)`` parameter, then a dictionary of named tuples is returned
    (indexed by time):

    >>> row_tensors
    >>> Out[6]:
    >>> {0: TestSchema_view(field_1=<tf.Tensor 'PyFunc_4:0' shape=() dtype=string>, field_2=...),
    >>>  1: TestSchema_view(field_1=<tf.Tensor 'PyFunc_4:11' shape=() dtype=string>, field_2=...),
    >>>  2: TestSchema_view(field_1=<tf.Tensor 'PyFunc_4:22' shape=() dtype=string>, field_2=...)}

    An optional shuffling queue is created if shuffling_queue_capacity is greater than 0.

    Note that if reading a unischema field that is unicode (``np.unicode_`` or ``np.str_``) tensorflow will
    represent it as a tf.string which will be an array of bytes. If using python3 you may need to decode
    it to convert it back to a python str type.

    :param reader: An instance of petastorm.Reader object used as the data source
    :param shuffling_queue_capacity: Queue capacity is passed to the underlying :class:`tf.RandomShuffleQueue`
        instance. If set to 0, no shuffling will be done.
    :param min_after_dequeue: If ``shuffling_queue_capacity > 0``, this value is passed to the underlying
        :class:`tf.RandomShuffleQueue`.
    :return: If no ngram reading is used, the function will return a named tuple with tensors that are populated
        from the underlying dataset. If ngram reading is enabled, a dictionary of named tuples of tensors is returned.
        The dictionary is indexed by time.
    """

    # NGram enabled and disabled code is quite different. It appears to be cleaner to simply go in orthogonal
    # execution paths.

    if reader.batched_output:
        if shuffling_queue_capacity > 0:
            raise ValueError('shuffling_queue_capacity can not be used with a reader that produces '
                             'batched_output, since each batch is a parquet read rowgroup. Extra '
                             'shuffling of the batches does not further decrease correlation.')

    if reader.ngram:
        result = _tf_tensors_ngram(reader, shuffling_queue_capacity, min_after_dequeue)
    else:
        result = _tf_tensors_nonngram(reader, shuffling_queue_capacity, min_after_dequeue)

    return result
Bridges between python-only interface of the Reader (next(Reader)) and tensorflow world.

    This function returns a named tuple of tensors from the dataset, e.g.,

    >>> row_tensors
    >>> Out[2]: TestSchema_view(field_1=<tf.Tensor 'PyFunc:0' shape=() dtype=string>,
    >>>         field_2=<tf.Tensor 'StringSplit:1' shape=(?,) dtype=string>,
    >>>         field_3=<tf.Tensor 'PyFunc:2' shape=() dtype=int64>, ...)

    If the reader was created with ``ngram=NGram(...)`` parameter, then a dictionary of named tuples is returned
    (indexed by time):

    >>> row_tensors
    >>> Out[6]:
    >>> {0: TestSchema_view(field_1=<tf.Tensor 'PyFunc_4:0' shape=() dtype=string>, field_2=...),
    >>>  1: TestSchema_view(field_1=<tf.Tensor 'PyFunc_4:11' shape=() dtype=string>, field_2=...),
    >>>  2: TestSchema_view(field_1=<tf.Tensor 'PyFunc_4:22' shape=() dtype=string>, field_2=...)}

    An optional shuffling queue is created if shuffling_queue_capacity is greater than 0.

    Note that if reading a unischema field that is unicode (``np.unicode_`` or ``np.str_``) tensorflow will
    represent it as a tf.string which will be an array of bytes. If using python3 you may need to decode
    it to convert it back to a python str type.

    :param reader: An instance of petastorm.Reader object used as the data source
    :param shuffling_queue_capacity: Queue capacity is passed to the underlying :class:`tf.RandomShuffleQueue`
        instance. If set to 0, no shuffling will be done.
    :param min_after_dequeue: If ``shuffling_queue_capacity > 0``, this value is passed to the underlying
        :class:`tf.RandomShuffleQueue`.
    :return: If no ngram reading is used, the function will return a named tuple with tensors that are populated
        from the underlying dataset. If ngram reading is enabled, a dictionary of named tuples of tensors is returned.
        The dictionary is indexed by time.
    
petastorm/tf_utils.py