Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/reference/client.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Client

## Read a query result

`Client.query_workflow()` returns the Server's receipt. Read its `result`
member for the decoded value returned by the query handler:

```python
receipt = await client.query_workflow("approval-1", "status")
status = receipt["result"]
print(status["approved"])
```

The receipt also identifies the workflow, run and query. A successful handler
may return `None`; that value appears in `receipt["result"]`. Query failures
raise `QueryFailed`. `WorkflowHandle.query()` and the synchronous client
return the same receipt shape.

## Read an update outcome

`Client.update_workflow()` returns a Server receipt. Its default wait stage is
Expand Down
6 changes: 6 additions & 0 deletions docs/sdk-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,12 @@ after that discovery succeeds. `Client.query_workflow()` checks the same
manifest before sending a query and raises `RuntimeCapabilityUnsupported` or
`RuntimeDiscoveryUnavailable` with remediation when the route cannot be used.

`Client.query_workflow()` and `WorkflowHandle.query()` return the Server's
receipt. The decoded handler value is in `receipt["result"]`, including a
successful `None` result. See the [query result example](reference/client.md#read-a-query-result).
The synchronous client returns the same receipt shape. Query failures raise
`QueryFailed`.

Python workers advertise declared update validators and evaluate them on a
dedicated synchronous validation task before the Server records an accepted
update. Validation replays the authoritative workflow state without committing
Expand Down
9 changes: 6 additions & 3 deletions src/durable_workflow/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4966,11 +4966,14 @@ async def append_message_stream(
async def query_workflow(
self, workflow_id: str, query_name: str, *, args: list[Any] | None = None
) -> Any:
"""Execute a named read-only query against a workflow and return the result.
"""Execute a named read-only query and return the Server's receipt.

Queries are synchronous and non-mutating. The server runs the named
query handler inside the workflow process and returns the decoded
result. Raises :class:`~durable_workflow.errors.QueryFailed` if the
query handler inside the workflow process. The returned ``dict``
includes workflow/run identities and ``query_name``; its ``result``
member holds the decoded handler value, which may be ``None``.
Read ``receipt["result"]`` to obtain that value.
Raises :class:`~durable_workflow.errors.QueryFailed` if the
query was rejected, the handler errored, or the original query timed
out. A canonical query timeout is surfaced without automatically
admitting another query.
Expand Down
Loading