# erldistpy Native Python client for our Erlang distribution protocol. Talk Erlang/Elixir nodes from CPython without HTTP shim layers. Built to swap into Python web apps as a drop-in for HTTP wallet-bridge clients (see [unfeed](https://git.unturf.com/foxhop/unfeed)'s `WalletTransport` and `make_post_sell`'s crypto watcher) so they can call Elixir `gen_server` processes over native Erlang dist instead of JSON-RPC or HTTPS. Same call semantics, lower latency, fewer moving parts. ## Install ```bash pip install erldistpy ``` ## Quick start ```python from erldistpy import Node, Atom with Node( our_name="myapp@host", peer_name="wallet", # short EPMD name peer_host="wallet.example.com", cookie="SHARED_COOKIE", # read from a file path, never inline ) as node: reply = node.call( "Elixir.Wallet.Service", (Atom("monero"), Atom("get_height"), []), timeout=5.0, ) # reply is whatever the gen_server returned — atoms / binaries / # tuples / maps / lists / pids / refs decode to Python natives. ``` For TLS dist (Erlang `inet_tls_dist`): ```python from erldistpy import Node, make_dist_tls_context ctx = make_dist_tls_context( cert="/etc/myapp/client.pem", key="/etc/myapp/client.key", ca="/etc/myapp/ca.pem", ) node = Node(our_name=..., peer_name=..., cookie=..., tls_context=ctx) ``` ## Scope - ETF (External Term Format) codec — encode/decode Erlang terms - EPMD client — node name → port lookup - v6 distribution handshake — MD5 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. erldistpy is a small synchronous client that fits behind the same Protocol surface as `httpx`. Different shape, different audience. ## Development ```bash make bootstrap # create venv, install editable + dev deps make test # run pytest (122 tests) make lint # ruff check make build # build sdist + wheel into dist/ make dist-check # twine check dist/* ``` See `docs/ROADMAP.md` for the phase-by-phase build log. ## License Unlicense (public domain).