Skip to main content

accordsync

The Accord client for Python: local-first writes, background sync, conflicts and refusals.

A Python program becomes an Accord device like a phone or a browser: it writes to its own SQLite database at once, online or not, and syncs with any Accord server (TypeScript, PHP or Python). It speaks the same protocol and merges by the same rules as @accordsync/client. Python 3.11+.

pip install accordsync

Open the client

Declare the same schema as your server, then open the client with SQLite storage and the HTTP transport.

from accordsync import (
    AccordClient,
    HttpTransport,
    SqliteStorage,
    conflict,
    counter,
    define_schema,
    lww,
    set_,
)

schema = define_schema(
    {"dossier": {"agent": lww(), "visits": counter(), "docs": set_(), "status": conflict()}}
)


def get_token() -> str:
    return my_auth.current_jwt()  # your app's auth; called before every request


accord = AccordClient.open(
    schema=schema,
    storage=SqliteStorage("accord.db"),
    transport=HttpTransport("https://sync.example.com", get_token=get_token),
)

Leave device_id unset: the client generates one from a secure random source and stores it. SqliteStorage takes a path or an open sqlite3.Connection; its tables are prefixed accord_, so they can share your program's database. MemoryStorage keeps nothing on disk (tests).

Write, then sync

Writes apply locally and are saved before they return. Sync on demand, or in the background.

accord.assign("dossier:91", "agent", "awa")
accord.inc("dossier:91", "visits", 1)
accord.add("dossier:91", "docs", "photo-1.jpg")

accord.sync()  # one round: push the pending writes, pull everyone else's
accord.start()  # or sync in a background thread: after writes, every 30 s, backoff on errors

print(accord.read("dossier:91"))  # {'agent': 'awa', 'visits': 1, 'docs': ['photo-1.jpg']}
print(accord.status().pending)  # writes not yet acknowledged by the server

accord.close()  # stops background sync and closes the storage

Events and refusals

off = accord.on("change", lambda records: print("changed:", records))
accord.on("refused", lambda r: print(f"refused {r.record}.{r.field}: {r.reason}"))
accord.on("error", lambda e: print("sync failed, retrying:", e))

The events are change (records whose local state changed), refused (a write the server refused, already rolled back on this device: tell the user), synced, resync and error. on() returns a function that unsubscribes. Listeners run on the thread that caused the event.

Conflicts

A conflict() field written concurrently on two devices keeps both values until someone decides.

for c in accord.conflicts():
    print(c.record, c.field, [v.value for v in c.values])
    accord.resolve(c.record, c.field, c.values[0].value)

While conflicted, read() shows the field as {"conflicted": [{"value": …, "opId": …}, …]}; once resolved, as {"value": …}.

Same behaviour as TypeScript

The merge core (accordsync-core) passes the shared golden vectors in every delivery order and reproduces the TypeScript core's random scenarios byte for byte. The repository's interop/ harness runs this client against the real TypeScript server, alone and together with TypeScript devices over a network that loses requests and responses, and checks every device ends with identical data.

Docs: accord.benhattab.pro/docs/python · Source: crossben/accordsync-python · Licence: Apache-2.0

Metadata

Release files for accordsync 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for accordsync 0.3.2
File Size Uploaded
accordsync-0.3.2.tar.gz 26.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for accordsync 0.3.2
File Interpreter ABI Platform
accordsync-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 46.3 kB

Release files / accordsync-0.3.2.tar.gz

Download URL accordsync-0.3.2.tar.gz
Size 26.5 kB
Tags Source
SHA-256 checksum
How to use checksums
058aed088832ed4b724c9f4efe00eca0edbcb4a4feb93952b67d4c1627ea4f8b
BLAKE2b-256 checksum
How to use checksums
ae98d386c32521e82d30897843a4449e6908aa351bee3fd2d2d95e98fdc0106c
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 Oct 8, 2026.

Transparency log

Release files / accordsync-0.3.2-py3-none-any.whl

Download URL accordsync-0.3.2-py3-none-any.whl
Size 19.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fb13d60deed7a4fb6861d9445a614964f54d06a2b4b9488648dec4ef32ed79f8
BLAKE2b-256 checksum
How to use checksums
705d63f458393952fdfd1596859acaebf88183c501807a0755ad9cb1085d7e8b
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 Oct 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.2 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page