Find a file
russell@unturf.com b9fd28ca3b
phase 0 + 1: repo bones and ETF codec
Repo scaffolding (LICENSE, Makefile, pyproject.toml, README) matching
unfeed conventions. Flat package layout, ruff config, Unlicense.

ETF codec covers the subset needed for gen_call against an Elixir node:
small/int/big_int, atom_utf8 (legacy atom_ext on decode), binary, nil,
list, small/large tuple, new_pid, newer_reference. Booleans round-trip
as atoms true/false; Python None as atom nil; str encodes to utf-8
binary to match Elixir convention.

Golden vectors were generated from real Erlang term_to_binary/1 output
(generator script at docs/etf_vectors.erl). Decode tests verify wire
compatibility; round-trip tests verify encoder consistency.

make all green: 58 passed, lint clean.

Next phases tracked in docs/ROADMAP.md (EPMD, handshake, channel,
gen_call, TLS, unfeed integration).
2026-06-16 10:39:01 -04:00
docs phase 0 + 1: repo bones and ETF codec 2026-06-16 10:39:01 -04:00
erldistpy phase 0 + 1: repo bones and ETF codec 2026-06-16 10:39:01 -04:00
tests phase 0 + 1: repo bones and ETF codec 2026-06-16 10:39:01 -04:00
.gitignore phase 0 + 1: repo bones and ETF codec 2026-06-16 10:39:01 -04:00
LICENSE phase 0 + 1: repo bones and ETF codec 2026-06-16 10:39:01 -04:00
Makefile phase 0 + 1: repo bones and ETF codec 2026-06-16 10:39:01 -04:00
pyproject.toml phase 0 + 1: repo bones and ETF codec 2026-06-16 10:39:01 -04:00
README.md phase 0 + 1: repo bones and ETF codec 2026-06-16 10:39:01 -04:00

erldistpy

Native Python client for our Erlang distribution protocol. Talk Erlang/Elixir nodes from CPython without HTTP shim layers.

Built to swap into unfeed's WalletTransport so a Python web app can call Unsandbox.WalletRPC over native dist instead of HTTPS. Same gen_call semantics, lower latency, fewer moving parts.

Status

Phase 0 — repo bones. See docs/ROADMAP.md for the phase plan.

Quick start

make bootstrap   # create venv, install editable + dev deps
make test        # run pytest
make lint        # ruff check

Scope

  • ETF (External Term Format) codec — encode/decode Erlang terms
  • EPMD client — node name → port lookup
  • Distribution handshake — cookie auth, version negotiation
  • gen_call to registered processes on a remote node
  • TLS dist support (Erlang inet_tls_dist)

Out of scope: full Erlang node impersonation, link/monitor lifecycles, distributed Mnesia. We are a client, not a peer node.

Why not Pyrlang?

Pyrlang implements a full asyncio Erlang node. Heavy, asyncio-first, complex. We need a small synchronous client that fits behind the same WalletTransport Protocol as httpx. Different shape.

License

Unlicense (public domain).