Skip to content

python: Add episode versions and labels - #168

Draft
brookfxg wants to merge 2 commits into
mainfrom
brook/dc-1873-update-python-library-to-support-episode-versioning-and
Draft

brookfxg wants to merge 2 commits into
mainfrom
brook/dc-1873-update-python-library-to-support-episode-versioning-and

Conversation

@brookfxg

Copy link
Copy Markdown
Contributor

Changelog

None. Episode annotations remain behind the server rollout gate.

Product updates

Python callers can now read a specific episode version, inspect version history, set or remove TEXT and URI labels, and change ranges or recording membership. Dataset membership accepts explicit episode versions. An exported committed dataset keeps each episode's pinned version even after that episode changes.

Existing string-ID dataset additions and episode metadata remain supported. Creating an episode version and selecting it in a dataset are separate calls; if pinning fails, the created version remains available for a retry.

Links

Fixes: DC-1873

Backend API: foxglove/app#19987

Implementation details

The client maps version and label responses to snake_case dictionaries and converts URI content_type only at the API boundary. Single and bulk updates preserve structured HTTP errors, while dataset edits continue to stage changes until a separate commit.

The exporter captures the committed dataset's member snapshots before transfer, signs each stream with that member's version, and records version and labels in the existing manifest format. It preserves the current selection-digest formula and never fetches URI label targets.

Testing

  • Against the local API, create an episode, edit labels and range through five versions, and confirm stale writes fail without changing database rows.
  • Make a two-episode bulk update fail on one stale precondition; confirm neither episode changes, then retry successfully.
  • Commit E@1, edit to E@5, and export the old dataset version; confirm the manifest, signed stream, and downloaded MCAP still use E@1.
  • Add and remove recordings between versions; confirm each historical read returns its original membership.
  • With annotations disabled for a local org, retry a string-ID dataset addition, commit and export it, and confirm annotation writes stay gated.

[ GENERATED BY AI ]

@linear-code

linear-code Bot commented Oct 14, 2026

Copy link
Copy Markdown

DC-1873

Comment thread foxglove/client/api.py Outdated
Comment thread foxglove/client/api.py
Comment thread foxglove/client/api.py Outdated
Comment thread foxglove/client/api.py
"already_present": result["alreadyPresent"],
}
if "updated" in result:
mapped["updated"] = result["updated"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return shape now changes with the server response. updated is present only when the server sends it. The same applies to changed_count, discarded_updates, and changed_episode_count. A caller who writes result["updated"] gets a KeyError when the server omits the field, for example for an org that does not have annotations enabled.

When does the server omit these fields? If an omitted field means zero, set a default so that callers get one shape:

"updated": result.get("updated", 0),

If the omission has a different meaning, document it in the docstring.

Comment thread foxglove/client/api.py Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prior unresolved thread(s) still open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant