Skip to main content

meridian-crdt

Python asyncio client for Meridian — real-time CRDT sync over WebSocket.

Install

pip install meridian-crdt

# With AES-GCM encryption and Ed25519 signing support
pip install meridian-crdt[crypto]

Quick start

import asyncio
from meridian import MeridianClient

async def main():
    async with MeridianClient(
        url="ws://localhost:3000",
        namespace="my-room",
        token="...",
    ) as client:
        views = client.gcounter("gc:views")
        views.increment(1)
        print(views.value())  # 1

asyncio.run(main())

CRDT handles

GCounter

views = client.gcounter("gc:views")
views.increment(5)
print(views.value())  # int

views.on_change(lambda v: print("views:", v))  # returns unsubscribe callable

PNCounter

balance = client.pncounter("pn:balance")
balance.increment(100)
balance.decrement(20)
print(balance.value())  # int (can be negative)

LwwRegister

profile = client.lww_register("lw:profile")
profile.set({"name": "Alice", "role": "admin"})
print(profile.value())  # dict | None

# With AES-GCM encryption (requires meridian-crdt[crypto])
from meridian.crypto import generate_aes_gcm_key
key = generate_aes_gcm_key()

enc_profile = client.lww_register("lw:private-profile", encrypt_key=key, decrypt_key=key)
enc_profile.set({"secret": "value"})  # encrypted on the wire

Presence

room = client.presence("pr:room-1")
room.heartbeat({"cursor": {"x": 100, "y": 200}}, ttl_ms=30_000)
print(room.online())  # list[PresenceEntry]

room.on_change(lambda entries: print("online:", [e.data for e in entries]))

Undo

PNCounter operations can be undone via UndoManager:

from meridian import MeridianClient
from meridian.crdt import UndoManager

async with MeridianClient(...) as client:
    balance = client.pncounter("pn:balance")
    undo = UndoManager()

    undo.pn_increment(balance, 100)  # increment and record
    print(balance.value())  # 100

    if undo.can_undo:
        undo.undo()  # sends inverse decrement
        print(balance.value())  # 0

LwwRegister has built-in server-validated undo:

profile = client.lww_register("lw:profile")
profile.set({"name": "Alice"})
profile.set({"name": "Bob"})

await profile.undo()   # server validates atomically before applying
print(profile.value()) # {"name": "Alice"} if undo succeeded

Live queries

async for result in client.live_query("gc:views-*", aggregate="sum"):
    print(f"total views: {result['value']}")  # pushed on every matching delta

Supported aggregates: sum, max, min, count, union, intersection, latest, collect, merge.

Conflict notifications

The client logs conflicts to logging.getLogger("meridian._client") at INFO level:

INFO meridian._client — conflict on lw:profile: LwwOverwritten

Encryption

Pass encrypt_key / decrypt_key to any handle that supports it (LwwRegister, Presence). Keys are AesGcmKey objects from meridian.crypto:

from meridian.crypto import generate_aes_gcm_key, import_aes_gcm_key

key = generate_aes_gcm_key()                   # generate
key = import_aes_gcm_key(b"32-byte-raw-key")   # import from bytes

Requires pip install meridian-crdt[crypto].

API

MeridianClient(url, namespace, token, *, connect_timeout=10.0)

Async context manager. Also supports manual lifecycle:

client = MeridianClient(url=..., namespace=..., token=...)
await client.connect()
# ...
await client.close()

CRDT handles

Method Returns
client.gcounter(crdt_id) GCounter
client.pncounter(crdt_id) PNCounter
client.lww_register(crdt_id, *, encrypt_key?, decrypt_key?) LwwRegister
client.presence(crdt_id, *, encrypt_key?, decrypt_key?) Presence

Other

Method Description
client.live_query(from_, aggregate, *, crdt_type?, where?) Async generator — yields {value, matched} on every update
client.sync(crdt_id, since?) Request a delta sync from the server

Development

pip install -e ".[crypto]"
pip install pytest pytest-asyncio
pytest
ruff check src/

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

meridian_crdt-0.1.1.tar.gz (13.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

meridian_crdt-0.1.1-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

Details for the file meridian_crdt-0.1.1.tar.gz.

File metadata

  • Download URL: meridian_crdt-0.1.1.tar.gz
  • Upload date:
  • Size: 13.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for meridian_crdt-0.1.1.tar.gz
Algorithm Hash digest
SHA256 372eb7f2c7b32f0d9aa3c621622d7ebde27ea7fe999c062d0b5953eac1ba93eb
MD5 3cb836256158b98a98af6db36d300616
BLAKE2b-256 6611c7eb2b5e74975f32f13ec5f7200a4b0526c92a44c0a3ff527ed1f42c824c

See more details on using hashes here.

File details

Details for the file meridian_crdt-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: meridian_crdt-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 16.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for meridian_crdt-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 bcbb3cb975f932fead3498311797a806361a81c3a6eb85c6575b71d961d9608a
MD5 78f80b94cbce364d2ccde4bebf5bd250
BLAKE2b-256 21fa74e63ea0f8bc159012918c3dea7bbbdf4ea54ab1e2dba63c90d695f47185

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page