Skip to content

[UPSTREAM-10] feat(python): add client classes for resources with methods - #57

Closed
moetemp wants to merge 5 commits into
moe/up/long-pollfrom
moe/up/python-client-resources
Closed

moetemp wants to merge 5 commits into
moe/up/long-pollfrom
moe/up/python-client-resources

Conversation

@moetemp

@moetemp moetemp commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

What changed?

This PR adds a class to client.py for each resource with methods. Each method fills in the request and calls the caller, and a caller method that returns the resource gives back a bound instance.

  • A record that holds such a resource gets a client twin in client.py.
  • The second commit adds the @nexus.doc docstrings, as temporalio/nexgen#281 does for the Workflow class.

Open question. A field that a Workflow fills from its context, such as namespace, isn't a client param, so code outside a Workflow sets it. Is that OK?

Depends on #55 (UPSTREAM-9).
Part of the Brook review series.

Why?

Workflow code already uses a resource as a class with methods. Code outside a Workflow had only the flat caller.

How did you test it?

The stream-service and start-workflow client.py goldens, and sample tests that check that a returned resource is bound to the caller.
cargo validate passes at both commits and cargo clippy adds no warnings. Fork CI passes.

@moetemp moetemp changed the title [Upstream] Added Python client classes for resources with methods. [Upstream] feat: add Python client classes for resources with methods Oct 22, 2026
@moetemp moetemp changed the title [Upstream] feat: add Python client classes for resources with methods feat(python): add client classes for resources with methods Oct 22, 2026
@moetemp moetemp changed the title feat(python): add client classes for resources with methods [Upstream] feat(python): add client classes for resources with methods Oct 22, 2026
@moetemp moetemp changed the title [Upstream] feat(python): add client classes for resources with methods [UPSTREAM-9] feat(python): add client classes for resources with methods Oct 22, 2026
@moetemp moetemp changed the title [UPSTREAM-9] feat(python): add client classes for resources with methods [UPSTREAM-10] feat(python): add client classes for resources with methods Oct 23, 2026
moetemp added a commit to temporalio/nexgen that referenced this pull request Oct 23, 2026
)

## What changed?

This PR adds a `stream-service` sample for Python and TypeScript, with today's output. #272 adds .NET with its fix. It has a `stream` resource built from a ref, `create-stream`, append, read, describe and close, with 64-bit offsets, payloads and durations.

Its records are proto-backed, as a stream service's are. Upstream has no stream protos, so the sample has its own small proto in `descriptors/streamsample/v1/`, with checked-in bindings. The samples README has the commands that regenerate them. `build_examples` now loads every `*.bin` under `descriptors/`.

## Why?

Later fixes show their effect as a golden diff on this sample.

## How did you test it?

The goldens. A TypeScript test sends a full `ReadRecordsRequest` through the converter, so the TypeScript type file can't drift from the proto.

## What comes next

These fixes are ready, in this order. Each one adds its shape to this sample, then the fix.

- #272: adds .NET, where the `stream` field of the `Stream` class fails with CS0542, then the fix.
- [moetemp#52](moetemp#52): Check required resource fields of a response. Adds `create-stream` returning the `stream` resource.
- [moetemp#56](moetemp#56): Allow a result record to hold a resource. Adds a `create-stream-result` holder record.
- [moetemp#53](moetemp#53): Emit `@nexus.doc` on resources and methods as Python docstrings.
- [moetemp#70](moetemp#70): Convert 64-bit resource method values to `Long` for a proto request in TypeScript. Adds 64-bit method parameters. Needs #265.
- [moetemp#54](moetemp#54): Generate a Python caller per service over a transport. Turns on the client for the sample.
- [moetemp#55](moetemp#55): Add `@nexus.long-poll` to the Python caller. Marks `read-records` as a long poll.
- [moetemp#57](moetemp#57): Add Python client classes for resources with methods.
- [moetemp#71](moetemp#71): Drop the bare keyword marker from a Python signature with no parameters. Adds a `stream-writer` interface with no endpoint.
- [moetemp#60](moetemp#60): Indent the docstrings of Python caller methods. Adds a doc on a writer operation.
- [moetemp#69](moetemp#69): Import record types that an endpoint-less Python client uses in unpacked parameters. Adds `open-writer`.
- [moetemp#72](moetemp#72): Plan proto unsigned integers as unsigned. Adds a `uint64` writer id.
- [moetemp#73](moetemp#73): Build a returned proto-wire resource in an endpoint-less TypeScript client. Makes `open-writer` return the `writer` resource.

#262 adds a `status` enum to the holder record once it merges.
@moetemp
moetemp force-pushed the moe/up/python-client-resources branch from 2430447 to 04274db Compare October 25, 2026 22:19
@moetemp
moetemp marked this pull request as ready for review October 25, 2026 22:20
A proto-backed request holds a 64-bit integer as a `Long`, but a resource
method takes a number. The method body converts its 64-bit params and fields.
With `--client`, `client.py` has one caller per service for code outside a
Workflow. A `Transport` sends each call, so the caller works over HTTP, an SDK
bridge or a test double.
A read that waits for new data returns early with an empty page. The caller
repeats such an operation until the answer has data, and gives an iterator
over the pages.
A caller method that returns a resource gives a client class bound to the
caller, so code outside a Workflow calls the resource methods on it. A
result record that holds a resource gets a client twin with the bound class.
The Workflow resource class takes the docs of a resource and its methods as
docstrings. The client class of the same resource takes them too.
@moetemp
moetemp force-pushed the moe/up/python-client-resources branch from 04274db to 571d3a9 Compare October 26, 2026 20:56
@moetemp

moetemp commented Oct 26, 2026

Copy link
Copy Markdown
Owner Author

Closing, since the reworked #54 covers this. Its client target renders the workflow target's resource classes, with their @nexus.doc docstrings, so a separate client class per resource isn't needed anymore.

@moetemp moetemp closed this Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant