Skip to content

[Brook S3] Added Stream definitions, handles, Records and errors to temporalio.common. - #373

Open
moetemp wants to merge 7 commits into
moe/brook/review/feature-streamsfrom
moe/brook/review/s3-data-model
Open

moetemp wants to merge 7 commits into
moe/brook/review/feature-streamsfrom
moe/brook/review/s3-data-model

Conversation

@moetemp

@moetemp moetemp commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

What was changed

This PR adds the data model of the Streams API to temporalio.common. That's Stream definitions, the StreamHandle[T] data, Records, errors and the generated wire models that they carry.

  • A definition subclasses StreamDefinition[T] and has @common.defn. It gives a Stream its name and its one payload type.
  • StreamHandle[T] is data only. It has the fields of the temporal.api.stream.v1.StreamHandle wire model (id, owner and backend) and no calls. S5 adds temporalio.client.Stream, which makes the calls outside Workflow code, and S7 adds temporalio.workflow.WorkflowStream, which makes them in Workflow code.
  • A handle converts to the proto JSON of StreamHandle through nexgen's generated converter, also as a field of a dataclass or a pydantic model, through the nested conversion of [Brook G2] Converted transfer types nested in JSON values. #368. So a Workflow can pass a handle to an Activity, a child or the next run. The type argument, such as StreamHandle[Turn], is for type checks only.
  • temporalio.common also exports the generated wire models that handles, Records, Superseded items and errors carry: Execution, ExecutionType, Producer, ProducerEpoch, StreamErrorReason, StreamProducerKind, StreamSuperseded and WorkflowTaskEpoch. So code outside the SDK can build a Workflow's handle.
  • The errors are the generated classes of S2, with the public names. Each class maps a case of StreamErrorReason. They have no code, and reason is the generated StreamErrorReason IntEnum. StreamConfigError stays hand-written, since it isn't a Store reason.

It depends on #372 (the generated Stream bindings) and #368.

Why?

Every later Streams PR builds on these types, and they need no backend or server. Stream handles and big-payload handles discusses the handle's wire form, and why the handle is data with no calls.

One open question. temporalio.common gets its first __all__, which changes from temporalio.common import *. Is that OK?

Part of the Brook review series.

Checklist

  1. How was this tested:
    • tests/contrib/streams/test_handles.py, and test_vectors.py, which checks the ids and withdrawal rules against the temporalio-streams crate.

@moetemp moetemp added the skip-changelog Changelog entry rides another PR label Oct 25, 2026
@moetemp
moetemp force-pushed the moe/brook/review/feature-streams branch from 9e54468 to 4c0260b Compare October 26, 2026 00:14
@moetemp
moetemp force-pushed the moe/brook/review/s3-data-model branch 2 times, most recently from 347fb8d to 9e969ce Compare October 26, 2026 02:08
@moetemp
moetemp force-pushed the moe/brook/review/feature-streams branch 2 times, most recently from c4ce9d7 to c22d918 Compare October 26, 2026 08:44
@moetemp
moetemp force-pushed the moe/brook/review/s3-data-model branch 2 times, most recently from 9b54b39 to fda6c46 Compare October 27, 2026 09:07
@moetemp
moetemp force-pushed the moe/brook/review/feature-streams branch from 479a894 to 63423ea Compare October 27, 2026 09:17
@moetemp
moetemp force-pushed the moe/brook/review/s3-data-model branch 2 times, most recently from 5a0f9bf to 7a7e940 Compare October 28, 2026 01:33
@moetemp
moetemp force-pushed the moe/brook/review/feature-streams branch from 63423ea to 6a7f134 Compare October 28, 2026 01:33
They are the data model of the Streams API in `temporalio.common`. A
handle is data, so a Workflow can pass it to an Activity, a child or the
next run.
@moetemp
moetemp force-pushed the moe/brook/review/s3-data-model branch from 7a7e940 to cbec633 Compare October 28, 2026 07:54
@moetemp
moetemp force-pushed the moe/brook/review/feature-streams branch from 6a7f134 to 021a3b7 Compare October 28, 2026 07:54
…us`.

The backend takes the close status from the failure, so a close only turns an asyncio cancel into
Temporal's cancel failure. The Stream errors are the generated classes, with the same names.
`StreamHandle` is the one handle type of every context, so `from_handle` is gone.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog Changelog entry rides another PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant