Observed since 20 Oct, 18:00 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
The Accord client for Python: local-first writes, background sync, conflicts and refusals.
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
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).
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
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.
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": …}.
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
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.3.2 | 8 Oct 2026 | 2 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 20 Oct, 18:00 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:c66f8d566e443f438c4a2077720d881db163bdd41ace75f023616bc720ccb360