Skip to content

python: stdlib zap_py client + bidirectional Go interop tests#1

Open
abhicris wants to merge 1 commit intoluxfi:mainfrom
kcolbchain:zap-py-client
Open

python: stdlib zap_py client + bidirectional Go interop tests#1
abhicris wants to merge 1 commit intoluxfi:mainfrom
kcolbchain:zap-py-client

Conversation

@abhicris
Copy link
Copy Markdown

Summary

Adds a pure-stdlib Python client (python/zap_py) that's wire-compatible with the Go reference. Lets non-Go peers — AI agents, ops scripts, FHE clients, kcolbchain switchboard/monsoon agents — read and build ZAP messages without leaving Python.

  • No deps, py≥3.8. parse() returns a Message backed by memoryview; .bytes_view() exposes zero-copy slices.
  • Builder/ObjectBuilder/ListBuilder mirror builder.go method-for-method, including the deferred-write trick for text/bytes so relative offsets match the Go encoder byte-for-byte.
  • Wire features covered: header (magic/version/flags/size), all scalar widths (bool, u8/16/32/64, i8/16/32/64, f32/f64), text, bytes, nested objects, lists of u8/u32/u64/objects/raw bytes, null object/list, flag bits.
  • Not ported (yet): EVM helpers (Address/Hash/Signature), MCP bridge, mDNS node, schema DSL. The reader+builder is enough to interop with any Go ZAP service that publishes a fixed schema; higher-level helpers can follow as Python use cases land.

Cross-language parity

Two new fixtures prove bidirectional wire compatibility:

Direction Fixture builder Verifier
Go → Python python/testdata/gen_fixture.go tests/test_roundtrip.py::test_go_fixture_interop
Python → Go python/testdata/gen_python_fixture.py python_interop_test.go::TestPythonFixture

Both fixtures use identical schemas. Outputs are byte-identical except for the embedded text payload ("from go" vs "from py"):

$ diff <(xxd /tmp/zap_fixture.bin) <(xxd /tmp/zap_python_fixture.bin)
8c8
< 00000070: ... 6672 6f6d 2067 6f01  ...from go.
> 00000070: ... 6672 6f6d 2070 7901  ...from py.

Why now

kcolbchain's agent stack (switchboard, monsoon, meridian, scout) is Python — without a wire-format client, every ZAP-speaking service requires a Go shim. This unlocks first-class Python peers on the canonical ZAP port (9999) and lines up cleanly with the README's GPU/FHE kernel-comm and AI-agent-orchestration use cases.

Note on go.sum

go.sum gains the missing luxfi/mdns line that go test ./... already needs to compile. Surfaced while wiring up python_interop_test.go — independent of the Python work, but cheaper to fix here than in a one-line follow-up PR.

Test plan

  • cd python && python -m venv .venv && .venv/bin/pip install pytest && .venv/bin/pytest tests/ — 12 passed
  • go run ./python/testdata/gen_fixture.go > /tmp/zap_fixture.bin && ZAP_GO_FIXTURE=... pytest tests/test_roundtrip.py::test_go_fixture_interop — passed
  • python python/testdata/gen_python_fixture.py > /tmp/zap_python_fixture.bin && ZAP_PYTHON_FIXTURE=... go test -run TestPythonFixture — passed
  • go test ./... — full Go suite still green (incl. fuzz seeds)

Adds python/zap_py — a pure-stdlib (no deps, py>=3.8) reader and
builder that's wire-compatible with the Go reference. Lets non-Go
peers (AI agents, ops scripts, FHE clients) speak ZAP without
leaving Python.

Read: parse() returns a Message backed by a memoryview; .bytes_view()
exposes zero-copy slices.
Build: Builder/ObjectBuilder/ListBuilder mirror builder.go method
for method, including the deferred-write trick for text/bytes so
relative offsets match the Go encoder byte for byte.

Coverage: header validation, all scalar widths (bool, u8/16/32/64,
i8/16/32/64, f32/f64), text, bytes, nested objects, lists of
u8/u32/u64/objects/raw bytes, null pointers, flag bits.

Bidirectional fixtures prove parity:
- python/testdata/gen_fixture.go      → emits a Go-built message
- python/testdata/gen_python_fixture.py → emits a Python-built one
- python/tests/test_roundtrip.py::test_go_fixture_interop reads
  the Go fixture from Python (skipped unless ZAP_GO_FIXTURE is set)
- python_interop_test.go::TestPythonFixture reads the Python fixture
  from Go (skipped unless ZAP_PYTHON_FIXTURE is set)

Both fixtures use identical schemas; output is byte-identical
except for the embedded text payload.

go.sum gains the missing luxfi/mdns line that `go test ./...` already
requires (fixes a tidy-state issue surfaced while wiring up the new
Go interop test).

Not ported (yet): EVM helpers, MCP bridge, mDNS node, schema DSL.
Reader+builder is enough to interop with any Go ZAP service that
publishes a fixed schema; higher-level helpers can follow as Python
use cases land.
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