lapinbeam
Real-time distributed systems framework for Python with a Rust core. An actor model inspired by Erlang/Elixir (BEAM), built with Rust (Tokio) exposed through PyO3.
Repository: https://github.com/rroblf01/lapinbeam · Docs: https://rroblf01.github.io/lapinbeam/ · Changelog
Status
1.0.1 — the public API (Node, Supervisor, actor/on, ActorRef/
RemoteRef, codec) is stable; a breaking change now requires a major
version bump. This hasn't been run at production scale yet — see
Limitations below for what it deliberately doesn't do.
Features
@actordecorated Python classes withasync def receive(msg), or typed dispatch via@on(Type)/@on(default=True)(see below).Supervisorwith restart strategies (one_for_one).Nodewith transparent remote actor references.- Multiplexed TCP transport (one socket per peer) with bincode serialization.
- Heartbeat and connection watchdog in the Rust core.
- Automatic reconnection of desired peers with backoff.
- Type-preserving payloads:
@dataclassand Pydantic v2 models round-trip between nodes vialapinbeam.codec. ask()request/response on top of fire-and-forgetsend(), andon_event()for connection/delivery/supervisor observability.- Optional shared-secret handshake authentication (
cluster_secret).
Install
pip install lapinbeam
The wheel is built for abi3 >= 3.11, so a single artifact covers Python 3.11 through 3.14.
Quickstart (two nodes)
# terminal 1
NODE_NAME=node_a@127.0.0.1:9001 PEER=node_b@127.0.0.1:9002 uv run python examples/app_node_a.py
# terminal 2
NODE_NAME=node_b@127.0.0.1:9002 PEER=node_a@127.0.0.1:9001 uv run python examples/app_node_b.py
Or with Docker (validated end-to-end: 100/100 ACKs inside the compose network):
docker compose up --build
Typed message dispatch
By default an actor implements a single async def receive(self, msg). As an
alternative, use @on(Type) to dispatch by the message's real type — which
lapinbeam.codec already preserves for @dataclass/Pydantic payloads across
nodes — and @on(default=True) for a catch-all handler:
from dataclasses import dataclass
from lapinbeam import actor, on
@dataclass
class Task:
payload_id: int
name: str
@actor(name="worker")
class Worker:
@on(Task)
async def handle_task(self, msg: Task):
...
@on(default=True)
async def handle_other(self, msg):
print("unrecognized message:", msg)
An actor with any @on handler stops using receive entirely; a message
whose type has no dedicated handler and no @on(default=True) fallback
raises TypeError (crashing the actor, so Supervisor restarts it like any
other unhandled exception). Actors that only define receive are unaffected.
Development
uv sync # create .venv, build the extension, install deps
uv run maturin develop # fast rebuild of the Rust extension
uv run pytest # Python test suite
cargo test # Rust test suite
uv run python bench/bench_remote.py # throughput benchmarks
uv run python bench/bench_latency.py # RTT latency percentiles
uv run python bench/bench_codec.py # codec + JSON conversion path, layer by layer
Nothing is installed on the OS: everything lives in .venv.
Documentation
Full docs (English + Spanish) live under docs/ and build with MkDocs +
Material:
uv sync --group docs # installs mkdocs, mkdocs-material, mkdocs-static-i18n
uv run mkdocs serve # http://127.0.0.1:8000, live-reloads on edits
uv run mkdocs build --strict # static site in site/ (gitignored)
Each page has an English file (e.g. docs/getting-started.md) and its
Spanish translation (docs/getting-started.es.md); mkdocs-static-i18n
serves the Spanish build under /es/ with a language switcher.
Benchmark snapshot
Measured on this machine (Python 3.14, loopback):
| Metric | Result |
|---|---|
| asyncio.Queue put/get | ~1.6M msg/s |
| lapinbeam local send | ~440K msg/s |
| lapinbeam remote (loopback TCP) throughput | ~16K msg/s |
| Local dispatch RTT | p50 0.007 ms |
| Remote loopback TCP RTT (send + ack) | p50 0.44 ms / p99 0.93 ms |
Limitations
- Payloads must be JSON-compatible (dict/list/str/int/float/bool/None). Ints are
limited to
i64/u64; larger ints raiseTypeError. __lb_type__is a reserved payload key (used by the type-preserving codecs).- Type preservation happens only on remote sends; local sends pass the object
by reference (zero-copy). A Pydantic field typed loosely (e.g.
Any) won't get a nested@dataclassvalue reconstructed on decode — it comes back as a plain dict instead; a properly-typed field (e.g.inner: Inner) round-trips fine via Pydantic's own validation. - Actor names must be unique per node —
Supervisor.spawn()raisesValueErrorif the name is already registered to a different actor. Simultaneous dial (both nodes connecting to each other at once) is resolved deterministically — exactly one connection survives, not two. - No message persistence and no at-least-once delivery: a message in flight during a network partition is lost, not retried. See lapinbeam vs. Celery + RabbitMQ for what that means in practice.
- Actor mailboxes are unbounded by default: an actor that can't keep up with
its inbound rate has its mailbox grow without limit instead of applying
backpressure. Pass
Node(..., mailbox_capacity=N)to cap it — a full mailbox then drops new messages instead, firingon_event(kind="mailbox_full")(and, for a dropped remote send, an"error"event back on the sender). - Payloads larger than 16 MiB are rejected on the sender.
Publishing to PyPI
uv build # produce wheel (abi3) + sdist in dist/
uv publish # upload to PyPI (uses UV_PUBLISH_TOKEN)
CI (./.github/workflows/ci.yml) runs the test matrix on Python 3.11-3.14, a
Docker Compose end-to-end check, and builds the distributable artifacts.
Project layout
src/ Rust core (_core extension module)
lapinbeam/ Pure-Python layer (@actor, Node, Supervisor, refs)
tests/ Rust integration tests
tests-python/ Python tests (pytest)
examples/ Two-node bidirectional demo, plus E2E fixtures used by CI
bench/ Throughput, latency and codec benchmarks
License
MIT
Release files for lapinbeam 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lapinbeam-1.0.1.tar.gz | 178.5 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| lapinbeam-1.0.1-cp311-abi3-win_amd64.whl | CPython 3.11 | abi3 | Windows x86-64 | Details |
| lapinbeam-1.0.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| lapinbeam-1.0.1-cp311-abi3-macosx_11_0_arm64.whl | CPython 3.11 | abi3 | macOS 11.0+ ARM64 | Details |
| lapinbeam-1.0.1-cp311-abi3-macosx_10_12_x86_64.whl | CPython 3.11 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 4.4 MB
Release files / lapinbeam-1.0.1.tar.gz
| Download URL | lapinbeam-1.0.1.tar.gz |
|---|---|
| Size | 178.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d37f72aa35603f9389581c94acacfc89368aebda6e6d71ba9560fb95dda7752d
|
|
BLAKE2b-256 checksum How to use checksums |
0d257e6300529948925108d74de195f90c2f362b82b04e6d7c5d246a6c31df53
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.
Transparency logRelease files / lapinbeam-1.0.1-cp311-abi3-win_amd64.whl
| Download URL | lapinbeam-1.0.1-cp311-abi3-win_amd64.whl |
|---|---|
| Size | 954.8 kB |
| Tags | CPython 3.11 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
10fbe9d08a821b9a2a1c1bb577e6e05caab3a7d282b61d450c3c5df89486cd57
|
|
BLAKE2b-256 checksum How to use checksums |
293971fc12b18e0dc6835fc3e328b263a4b9dac85f61cdfa0e7f38abec7a264a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.
Transparency logRelease files / lapinbeam-1.0.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | lapinbeam-1.0.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
4db5f78d8ca4b0f7e0ac44a1d8aa67f05dd44110c780cae9a6466ec8f0cc813a
|
|
BLAKE2b-256 checksum How to use checksums |
e6879621ffde9523149bf6b37d0e5226b91cd8f58831b588fb41749e62256ff0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.
Transparency logRelease files / lapinbeam-1.0.1-cp311-abi3-macosx_11_0_arm64.whl
| Download URL | lapinbeam-1.0.1-cp311-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.1 MB |
| Tags | CPython 3.11 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
3b5e3ad323f57cda6839598ac146b7482d56b41198abdf1c71256adc9ab7440e
|
|
BLAKE2b-256 checksum How to use checksums |
e3f92bd1c94b6a38c18086ed255b615179ad96d917b296bd2b51f72fcba3a29e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.
Transparency logRelease files / lapinbeam-1.0.1-cp311-abi3-macosx_10_12_x86_64.whl
| Download URL | lapinbeam-1.0.1-cp311-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 1.1 MB |
| Tags | CPython 3.11 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
e7343626540cebe942639fc1e692f2fe32df7fbd5ca4450bb9178e404c707929
|
|
BLAKE2b-256 checksum How to use checksums |
92f86b1975a50a284e910295d17058645eb9d51beef0efeadead39cb665b7005
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.
Transparency log