Migrated from https://git2.unturf.com/python/erldistpy.git
Node wraps EPMD lookup + handshake + Channel into a single client
object. Constructor eagerly opens the dist connection; call() runs the
synchronous $gen_call protocol against a registered name on the peer:
caller -> {'$gen_call', {FromPid, Ref}, Request} (REG_SEND)
server -> {Ref, Reply} (SEND)
Synthesized FromPid and a Node-lifetime Ref counter route replies back
to us; mismatched Ref or unexpected control op raises CallProtocolError.
Reply timeout raises CallTimeout (also covers Erlang's silent-drop case
when the registered name doesn't exist).
Tests against an erl peer running a $gen_call-aware loop:
- {ping, X} -> {pong, X}
- {add, A, B} -> {ok, A + B}
- five sequential calls with monotonically increasing Refs
- server error response surfaces as Python tuple
- slow responder triggers CallTimeout
- unknown registered name surfaces as CallTimeout
- ref uniqueness across 100 synthesized refs
111 tests green across 10 consecutive runs, lint clean.
|
||
|---|---|---|
| docs | ||
| erldistpy | ||
| tests | ||
| .gitignore | ||
| LICENSE | ||
| Makefile | ||
| pyproject.toml | ||
| README.md | ||
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).