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

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

Built distribution (wheel)

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

Total release size: 45.7 kB

Release files / accordsync-0.3.0.tar.gz

Download URL accordsync-0.3.0.tar.gz
Size 26.1 kB
Tags Source
SHA-256 checksum
How to use checksums
b841a789386346745f7a61a392ecb6d7b93e449cf4f1e5652f90465cdc019879
BLAKE2b-256 checksum
How to use checksums
0e1e21b9c9d0bfafb0e2bd1e3bf2637bee19a1db156b060dd3d5f96cdd379a4a
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 7, 2026.

Transparency log

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

Download URL accordsync-0.3.0-py3-none-any.whl
Size 19.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bbe7c368401bbee028115991bdd910550c5235ae0b530280acb71fb5ce75bce5
BLAKE2b-256 checksum
How to use checksums
6c62617123d0991a27b582c2d8ea3056f0b2ba9f0cedf48479fea2f9cab85b31
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 7, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.2

2 release files

0.3.1

2 release files

This release

0.3.0 This release

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