From db9c9f4d2877631d7d9f9d82d41abfa3c540b954 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 18:36:44 +0000 Subject: [PATCH] Return episode recording locations The Foxglove API now includes `location` (bucket, object key, and Azure storage account when set) on episode recordings requested with `include=recordings`, for recordings indexed in place in a customer-managed bucket. `_episode_recording_dict` copies known fields only, so pass `location` through, as `None` when the API omits it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019TegazNERbHFBWDR5CFJ6m --- foxglove/client/api.py | 1 + tests/test_datasets.py | 1 + tests/test_episodes.py | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/foxglove/client/api.py b/foxglove/client/api.py index 7373bc4..15b0063 100644 --- a/foxglove/client/api.py +++ b/foxglove/client/api.py @@ -2148,6 +2148,7 @@ def _episode_recording_dict(recording): return { "id": recording["id"], "path": recording["path"], + "location": recording.get("location"), "start": arrow.get(recording["start"]).datetime, "end": arrow.get(recording["end"]).datetime, "device_id": recording.get("deviceId"), diff --git a/tests/test_datasets.py b/tests/test_datasets.py index 26c2539..024137a 100644 --- a/tests/test_datasets.py +++ b/tests/test_datasets.py @@ -184,6 +184,7 @@ def test_dataset_version_methods(): assert version["version_number"] == 1 assert version["has_missing_recordings"] is False assert episodes.items[0]["episode"]["id"] == "ep_1" + assert episodes.items[0]["episode"]["recordings"][0]["location"] is None assert comparison["changes"][0]["change"] == "added" assert "has_missing_recordings" not in comparison["changes"][0] assert comparison["next_cursor"] == "next" diff --git a/tests/test_episodes.py b/tests/test_episodes.py index bb0abff..8a7198e 100644 --- a/tests/test_episodes.py +++ b/tests/test_episodes.py @@ -25,6 +25,7 @@ def _episode_json(episode_id="ep_1", *, include_recordings=False): { "id": "rec_1", "path": "run.mcap", + "location": {"bucket": "robot-logs", "path": "fleet/run.mcap"}, "start": NOW.isoformat(), "end": NOW.replace(minute=1).isoformat(), "deviceId": "dev_1", @@ -94,6 +95,10 @@ def test_get_episodes_maps_response_and_filters(): assert episodes.items[0]["start_time"] == NOW assert episodes.items[0]["metadata"]["nestedValue"] == {"keepMe": True} assert episodes.items[0]["recordings"][0]["device_id"] == "dev_1" + assert episodes.items[0]["recordings"][0]["location"] == { + "bucket": "robot-logs", + "path": "fleet/run.mcap", + } assert episodes.items[0]["recordings"][0]["resolvable"] is True assert episodes.items[0]["has_missing_recordings"] is False assert responses.calls[0].request.params == {