Skip to content

chore(examples): share one operation-status reader across the demos - #1319

Merged
jfrench9 merged 1 commit into
mainfrom
chore/examples-operation-status-helper
Aug 31, 2026
Merged

chore(examples): share one operation-status reader across the demos#1319
jfrench9 merged 1 commit into
mainfrom
chore/examples-operation-status-helper

Conversation

@jfrench9

Copy link
Copy Markdown
Member

Summary

Six demos polled async operations through the same twelve-line dance, branching on the response body's shape to extract status and result:

status_data = status_resp.parsed
if isinstance(status_data, dict):
    status = status_data.get("status")
elif hasattr(status_data, "additional_properties"):
    props = status_data.additional_properties
    status = props.get("status")
else:
    status = getattr(status_data, "status", None)   # could never fire

The operations endpoints are declared as free-form objects, so the generated model carries only additional_properties and attribute access on it raises — that middle branch is the workaround, and the getattr fallback beneath it was unreachable. This is the consumer-side echo of the client defect fixed in RoboFinSystems/robosystems-python-client#202: everyone hit the wall and hand-rolled the same escape.

Changes

  • examples/_common/sdk.pyoperation_status(client, operation_id) reads the body through to_dict() and returns a plain dict, or {} when the response carried no body.
  • Six polling loops_scenario/runner.py, custom_graph_demo/create_graph.py, roboinvestor_demo/main.py, roboledger_demo/main.py, seattle_method_demo/main.py, seattle_method_world_online/main.py — each drops the dance for the helper and swaps the generated import for it. Net −99/+61 across seven files.

Behaviour is unchanged at every site. {} is falsy, so the existing continue still fires on an empty body; an error response or a body without a status key yields status is None, so the loop keeps polling rather than mistaking it for a terminal state — same as before.

Not touched

Three other additional_properties reads under examples/custom_graph_demo/memory_subgraph.py, custom_graph_demo/upload_documents.py, roboledger_demo/validate.py — read different response models (period-close overflow, an investor payload). The operations accessor does not apply, so they stay as they are.

This does not bump the client pin. The helper only needs to_dict(), which has always been generated, so it works against the currently-locked 1.13.1. Moving to 1.13.2 (for the query/operator/operations retry parity in #202) is worth doing on its own merits and belongs in its own change.

Testing

  • just test-code — ruff, format and basedpyright clean. Note examples is in ruff's exclude list in pyproject.toml, so the tree is deliberately unlinted; these edits match the surrounding style by hand rather than by running a formatter over an excluded path.
  • All seven touched modules import clean.
  • operation_status exercised against a live stub for four cases: a completed operation (result.graph_id read back), a failed one, a 500 error body, and a 200 whose body omits status — the last two yielding status is None so a poll continues.
  • The demos themselves need a live stack; not run end-to-end here.

Six demos polled async operations through the same twelve-line dance,
branching on the response body's shape to pull out status and result.
The operations endpoints are free-form objects, so the generated model
carries only additional_properties and attribute access on it raises —
which is what the middle branch worked around, and why the getattr
fallback under it could never fire.

`operation_status` in _common/sdk.py reads the body through to_dict()
and hands back a plain dict, or {} when there was no body — a transient
blip mid-poll, which callers already treated as "ask again". Behaviour
is unchanged at every site, including for an error response or a body
without a status: the caller reads None and keeps polling, exactly as
before.

Three other additional_properties reads under examples/ are left alone
— memory_subgraph, upload_documents and roboledger_demo/validate read
different models, where this accessor does not apply.
@jfrench9
jfrench9 merged commit 29c413b into main Aug 31, 2026
7 checks passed
@jfrench9
jfrench9 deleted the chore/examples-operation-status-helper branch August 31, 2026 23:25
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