def wrap_iterable(
    itb: Iterable[E],
    callback_class: Type[IterableCallbacks] = IterableCallbacks,
    **kwargs: Dict[str, Any],
) -> Iterable[E]:
    """Wrap an iterable to invoke various callbacks.

    See
    [IterableCallbacks][trulens.experimental.otel_tracing.core._utils.wrap.IterableCallbacks]
    for callbacks invoked.

    Args:
        itb: The iterator to wrap.

        **kwargs: All other arguments are passed to the callback class
            constructor and to `on_iterable_wrapped`,
            `on_iterable_iter_exception`.
    """

    init_args = {"itb": itb, **kwargs}

    def wrapper(itb: Iterable[E]) -> Iterable[E]:
        cb = callback_class(**init_args)

        try:
            it: Iterator[E] = iter(itb)
            it = cb.on_iterable_iter(it=it)

        except Exception as e:
            init_args["error"] = e
            e_wrapped = cb.on_iterable_iter_exception(**init_args)
            cb.on_iterable_end()

            if e == e_wrapped:
                raise e

            raise e_wrapped from e

        while True:
            cb.on_iterable_next()

            try:
                val = next(it)
                val = cb.on_iterable_next_result(val=val)
                yield val

            except StopIteration:
                cb.on_iterable_stop()
                cb.on_iterable_end()
                return

            except Exception as e:
                e_wrapped = cb.on_iterable_next_exception(error=e)
                cb.on_iterable_end()

                if e == e_wrapped:
                    raise e

                raise e_wrapped from e

    w: Iterable[E] = wrapper(itb)

    init_args["wrapper"] = w
    callback_class.on_iterable_wrapped(**init_args)

    return w
Wrap an iterable to invoke various callbacks.

    See
    [IterableCallbacks][trulens.experimental.otel_tracing.core._utils.wrap.IterableCallbacks]
    for callbacks invoked.

    Args:
        itb: The iterator to wrap.

        **kwargs: All other arguments are passed to the callback class
            constructor and to `on_iterable_wrapped`,
            `on_iterable_iter_exception`.
    
src/core/trulens/experimental/otel_tracing/core/_utils/wrap.py