Skip to content

Add an on_progress callback for long wire transfers (SCREENSHOT, FSGET) - #84

Merged
sidick merged 1 commit into
mainfrom
screenshot-progress-callback
Aug 10, 2026
Merged

Add an on_progress callback for long wire transfers (SCREENSHOT, FSGET)#84
sidick merged 1 commit into
mainfrom
screenshot-progress-callback

Conversation

@sidick

@sidick sidick commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • WireClient.command()/_read_exact() (host/amipilot/wire.py) now accept an optional on_progress(bytes_so_far, total_bytes) callback, invoked as a response payload streams in over the wire — the natural hook point since every large binary payload (SCREENSHOT, FSGET, any future binary-payload verb) already flows through _read_exact().
  • Threaded through Amipilot._run() into screenshot() and fs_get() as an optional keyword-only on_progress argument, defaulting to None (today's exact behavior, zero overhead when unused).
  • amipilot.stderr_progress(label="") is a ready-made callback for the common case: a self-overwriting label: done/total bytes (pct%) line to stderr, so scripts don't all have to hand-roll the same thing. Exported from the package root.
  • Documented in userdocs/Wire-Protocol.md (right after the SCREENSHOT transfer-time table, the exact pain point this addresses) and host/README.md's Current State section.

Why

Felt directly during real Picasso96/uaegfx SCREENSHOT verification on Amiberry: a capture against a real P96 CLUT/truecolor screen took tens of seconds with zero feedback, no way to tell "still working" from "hung" from the caller's side.

Test plan

  • New unit tests in host/tests/test_wire.py (ProgressCallback, StderrProgress classes): callback called once per chunk with non-decreasing progress against the true total, correctly handles the case where the header read over-reads into the payload buffer, zero-length payloads, omitted/None callback is a no-op, stderr_progress()'s output format and zero-total edge case.
  • New tests in host/tests/test_client.py confirming on_progress reaches (total, total) by the end for both screenshot() and fs_get().
  • Full host suite: python3 -m unittest discover -s host/tests — 242 passed (the one pre-existing failure, test_pytest_plugin.py, is pytest not being installed in this shell, unrelated to this change).

🤖 Generated with Claude Code

WireClient gave zero feedback while a large payload streamed in --
felt directly during real Picasso96/uaegfx SCREENSHOT testing on
Amiberry, where a capture can take tens of seconds to several minutes
with no way to tell "still working" from "hung".

WireClient.command()/_read_exact() now accept an optional
on_progress(bytes_so_far, total_bytes) callback, threaded through
Amipilot.screenshot() and fs_get(). amipilot.stderr_progress() is a
ready-made callback for the common case (a self-overwriting "X/Y
bytes (Z%)" line). Defaults to None everywhere -- zero behavior
change for existing callers.

Closes #53
@sidick
sidick merged commit 3e99bdb into main Aug 10, 2026
7 checks passed
@sidick
sidick deleted the screenshot-progress-callback branch August 10, 2026 19:58
sidick added a commit that referenced this pull request Aug 10, 2026
Release prep for the imminent v1.1 tag.

## Version bumps
- version.mk -> 1.1, host/pyproject.toml -> 1.1.0
- amipilot.readme: Version field -> 1.1 plus a new "From 1.1" features
  paragraph (PICK, full Requester close, pointer-based MENUPICK,
  WHERE/WHEREGADGET, STRING_KIND/INTEGER_KIND, 12 more ReAction roles)
- README.md, host/README.md, CLAUDE.md, server/README.md: status text
  flipped from "not yet in a tagged release"/"not yet released" to
  shipped-in-v1.1, matching the v1.0 release-prep precedent (PR #71)

## Docs pass
- userdocs/Changelog.md: renamed "## Unreleased" to "## v1.1", and
  added the three entries that PRs #83/#84/#85 (PyPI, on_progress,
  PICK) never wrote there in the first place -- the five requester/
  ReAction/WHERE/MENUPICK/STRING-INTEGER entries were already present
- userdocs/ARexx-Reference.md: PICK was entirely missing from the
  verb table -- added
- userdocs/Use-Cases.md, Getting-Started.md: point at PICK from the
  "exploratory GUI inspection" use case and the getting-started
  walkthrough, where it now genuinely delivers on the long-standing
  "element-picker equivalent" claim
- userdocs/Troubleshooting-and-FAQ.md: new PICK entry covering the
  three real gotchas (single-snapshot semantics, system gadgets in
  an "empty" chrome hit, the untested-display-modes caveat on the
  pointer-Y correction)
- userdocs/Wire-Protocol.md: the one live "pip install amipilot[serial]"
  instruction now hedges on PyPI publishing not being live yet,
  matching skills/amipilot/SKILL.md's own existing hedge

## Verified
- scripts/verify-version.sh v1.1 passes (version.mk/amipilot.readme/
  host/pyproject.toml all agree)
- amipilot.readme: no line exceeds Aminet's 72-char limit
- mkdocs build --strict clean (also confirms the new
  #pick-mode-pick anchor resolves)
- make guide (AmigaGuide conversion) succeeds
- Host unit suite: 246 passed

## Deliberately NOT in this PR -- open pre-tag decisions
1. PyPI's one-time setup (pending publisher + `pypi` environment) is
   still outstanding -- confirmed neither exists yet. Pushing the tag
   now would leave the publish-pypi job failing on a missing
   environment. Needs doing (or the job needs skipping for this tag)
   before/at tag time.
2. The GitHub repo description update (standing release checklist
   item) -- a live setting change, not a file in this PR.
3. The tag itself and the GitHub release/Aminet pipeline it triggers.
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