Trace generator functions

no
Summary: Track sync and async generator functions with W&B Weave tracing

Original Documentation

Documentation Index#

Fetch the complete documentation index at: https://docs.wandb.ai/llms.txt Use this file to discover all available pages before exploring further.

Track sync and async generator functions with W&B Weave tracing

W&B Weave supports tracing both sync and async generator functions, including deeply nested patterns.

Because generators yield values lazily, Weave logs outputs only when the generator is fully consumed (for example, when you convert it to a list). To ensure Weave captures outputs in the trace, fully consume the generator (for example, with list()).

    from typing import Generator
    import weave

    weave.init("my-project")

    # This function uses a simple sync generator.
    # Weave will trace the call and its input (`x`),
    # but output values are only captured once the generator is consumed (for example, with `list()`).
    @weave.op
    def basic_gen(x: int) -> Generator[int, None, None]:
        yield from range(x)

    # A normal sync function used within the generator pipeline.
    # Its calls are also traced independently by Weave.
    @weave.op
    def inner(x: int) -> int:
        return x + 1

    # A sync generator that calls another traced function (`inner`).
    # Each yielded value comes from a separate traced call to `inner`.
    @weave.op
    def nested_generator(x: int) -> Generator[int, None, None]:
        for i in range(x):
            yield inner(i)

    # A more complex generator that composes the above generator.
    # Tracing here produces a hierarchical call tree:
    # - `deeply_nested_generator` (parent)
    #   - `nested_generator` (child)
    #     - `inner` (grandchild)
    @weave.op
    def deeply_nested_generator(x: int) -> Generator[int, None, None]:
        for i in range(x):
            for j in nested_generator(i):
                yield j

    # The generator must be *consumed* for Weave to capture outputs.
    # This is true for both sync and async generators.
    res = deeply_nested_generator(4)
    list(res)  # Triggers tracing of all nested calls and yields
    ```
  <span class="tab-end"></span>

  <span class="tab-start" data-tab-title="TypeScript"></span>
```plaintext
    This feature is not available in the TypeScript SDK yet.
    ```
  <span class="tab-end"></span>
<span class="tab-group-end"></span>

The following screenshot shows the **Traces** page with a selected trace of the preceding code.  The center panel shows the trace tree for the selected trace. The trace tree shows the `deeply_nested_generator`, `nested_generator`, and `inner` Ops in the trace tree hierarchy.
<img src="https://mintcdn.com/wb-21fd5541/4ANo4MV8FzCjYewG/weave/guides/tracking/imgs/generators.png?fit=max&auto=format&n=4ANo4MV8FzCjYewG&q=85&s=da7f687c1e1db490ec563a88a7a5931f" alt="Weave Traces page showing a selected trace tree illustrating deeply nested Ops" width="2078" height="1134" data-path="weave/guides/tracking/imgs/generators.png" />

## Consuming generators

Weave captures generator outputs only after you fully consume the generator. Consume the generator by iterating over it (for example, with `list()`, a `for` loop, or `next()` until exhaustion). The same applies to async generators when you use `async for` or equivalent consumption.

For more on decorating functions and methods with `@weave.op`, see [Create calls](/weave/guides/tracking/create-call).
Link last verified June 7, 2026. View original ↗
Source: Weights & Biases Docs
Link last verified: 2026-04-05