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.1

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.1
File Size Uploaded
accordsync-0.3.1.tar.gz 26.1 kB Details

Built distribution (wheel)

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

Total release size: 45.7 kB

Release files / accordsync-0.3.1.tar.gz

Download URL accordsync-0.3.1.tar.gz
Size 26.1 kB
Tags Source
SHA-256 checksum
How to use checksums
feb59e93986522696feb78396cf9a564a33d4ffab8b9695037f0ebbfb039e762
BLAKE2b-256 checksum
How to use checksums
533838246a493530f5f1cc701bcdda8fd6d699d34fe8ae50b9a6f394d28ed1df
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.1-py3-none-any.whl

Download URL accordsync-0.3.1-py3-none-any.whl
Size 19.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b51d65cf175733aa8cd6db1cbb3e50b522b054b100bb2282f1a4d4c663986986
BLAKE2b-256 checksum
How to use checksums
17ae8f1e47cc36603f2f48ddb6c0232d6a64342897dee0bcaa9175222e32a68e
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

0.3.2

2 release files

This release

0.3.1 This release

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