Skip to content

api: add Snapshot endpoint, with raw/binary transport support#122

Merged
mbrulatout merged 2 commits into
criteo:masterfrom
mbrulatout:snapshot-endpoint
Jul 3, 2026
Merged

api: add Snapshot endpoint, with raw/binary transport support#122
mbrulatout merged 2 commits into
criteo:masterfrom
mbrulatout:snapshot-endpoint

Conversation

@mbrulatout

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #121 — implements the Snapshot endpoint that PR deliberately deferred.

  • Transport layer: adds an opt-in raw: bool = False mode to HTTPClient.get() in both the sync (std.py, requests-based) and async (aio.py, aiohttp-based) clients. Previously every response body was unconditionally decoded as UTF-8 text, which corrupts binary payloads. Off by default, so every existing endpoint is unaffected — verified via a full test suite run. Also widens put()'s data param to str | bytes, and adds CB.binary() for endpoints that need the raw body with normal status-code error handling.
  • Snapshot (consul/api/snapshot.py) — save()/restore(), built on the above. Both require a management-level ACL token (not a granular ACL rule), per Consul's docs.

Verification

Beyond the new pytest integration tests (tests/api/test_snapshot.py, run against real dockerized Consul 1.20.6/1.21.5/1.22.0), I also directly exercised the full save → mutate → restore → verify round-trip against a live Consul container for both the sync and async clients, since the async path isn't covered by the existing test suite's fixtures:

snapshot type <class 'bytes'> len 4019 magic b'\x1f\x8b'
restore ok? True
value after restore b'before'

Test plan

  • mypy consul/ --no-sqlite-cache — clean
  • ruff check . / ruff format --diff . — clean
  • New integration tests in tests/api/test_snapshot.py — passing across all 3 Consul versions
  • Manual end-to-end verification of both sync and async clients (see above)
  • Full existing test suite re-run — no regressions

Mathias Brulatout added 2 commits July 3, 2026 10:17
Both sync (std.py, requests-based) and async (aio.py, aiohttp-based)
HTTP clients unconditionally decoded every response body as UTF-8
text, which corrupts binary payloads (e.g. the gzip archive returned
by GET /v1/snapshot). Adds a `raw: bool = False` parameter to
HTTPClient.get() across base/std/aio: when set, the response body is
kept as raw bytes (response.content / await resp.read()) instead of
being decoded. Also widens put()'s data param to str | bytes, and
adds CB.binary() for endpoints that need the raw body with normal
status-code error handling.

Off by default, so every existing endpoint is unaffected. Verified
end-to-end (not just unit-level) against a live Consul instance for
both the sync and async clients ahead of the Snapshot endpoint that
depends on this.
Adds consul.snapshot.save()/restore(), built on the raw/binary
response mode added in the previous commit. Both endpoints require
a management-level ACL token, not a granular ACL rule.

Verified against a live Consul instance for both the sync and async
clients: save a snapshot, mutate state, restore, and confirm the
pre-mutation state comes back.
@mbrulatout
mbrulatout merged commit 8c50898 into criteo:master Jul 3, 2026
5 checks passed
@mbrulatout
mbrulatout deleted the snapshot-endpoint branch July 3, 2026 13:19
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.

2 participants