accordsync-server
The Accord sync server for Python, on PostgreSQL.
Framework-agnostic: push and pull, scopes, JWT auth, limits, rate limits, CORS and compaction behind
one handle() call per request, plus a WSGI application. It speaks the same protocol, merges by the
same rules and uses the same PostgreSQL schema as
@accordsync/server, so the TypeScript, React
Native, Flutter and Python clients sync with it unchanged.
With FastAPI or Django, use accordsync-fastapi or
accordsync-django: they route to this package. This
page is for WSGI, or for another framework.
Install
pip install accordsync-server
Python 3.11+ and PostgreSQL (the conformance suite and the example apps use PostgreSQL 16). It connects with psycopg 3 and its connection pool.
Define the server
define_server() takes the same parts as defineServer in TypeScript: the schema, a scope function
per record type, the access a user gets from their JWT claims, and how tokens are checked. It checks
at once that every record type has a scope function.
# myapp/sync.py
from accordsync_core import conflict, counter, define_schema, lww, set_
from accordsync_server import Access, Auth, ScopedRecord, define_server
schema = define_schema(
{"dossier": {"agent": lww(), "visits": counter(), "docs": set_(), "status": conflict()}}
)
def dossier_scope(record: ScopedRecord) -> list[str]:
"""The scope keys of a record, from its current fields."""
agent = record.fields.get("agent")
return [f"agent:{agent}"] if isinstance(agent, str) else []
server = define_server(
schema=schema,
scopes={"dossier": dossier_scope},
# The scope keys a user may read and write, from their verified JWT claims.
access=lambda claims: Access(read=[f"agent:{claims['sub']}"], write=[f"agent:{claims['sub']}"]),
auth=Auth.jwks(
"https://auth.example.com/.well-known/jwks.json",
issuer="https://auth.example.com/",
audience="accord",
),
)
Optional arguments: cors (browser origins allowed to call the API), rate_limit (a RateLimits;
default 600 requests a minute per device and 1 800 per user; False turns it off), compaction (a
Compaction: device TTL, interval, minimum ops) and limits (a Limits: body size, concurrent
pushes, ops per push, pull page size, scope delta size, clock skew). Auth.hs256(secret) is for
development and tests.
Serve it
AccordServer(definition, pool) serves GET /health, POST /v1/push and GET /v1/pull.
server.handle(method, path, query, headers, body) returns a Response(status, headers, body) for
any framework; server.wsgi is a ready WSGI application:
# myapp/wsgi.py
import os
from accordsync_server import AccordServer, create_pool
from myapp.sync import server as definition
app = AccordServer(definition, create_pool(os.environ["ACCORD_DATABASE_URL"])).wsgi
create_pool(url, size=20) opens a psycopg pool of up to size connections. Serve app with a
threaded WSGI server (waitress, or gunicorn with --threads): each request holds a thread while it
waits on PostgreSQL. ACCORD_DATABASE_URL is a URL like postgresql://user:password@host:5432/db.
Migrations and compaction
ACCORD_DATABASE_URL=postgresql://… python -m accordsync_server migrate
ACCORD_DATABASE_URL=postgresql://… python -m accordsync_server compact --definition myapp.sync:server
Run compact from cron at the definition's compaction.interval_ms (default hourly). It takes
PostgreSQL's exclusive advisory lock, so overlapping runs, or several servers, do not conflict. In
code: migrate(url) and compact(pool, definition).
One database, any Accord server
The migrations are the TypeScript server's, recorded in the same ledger table (kysely_migration):
a database migrated by @accordsync/server is up to date here, and the other way round. One database
can be served by TypeScript and Python servers at the same time, with clients sent to either. The
repository's server-interop/ harness does exactly that: Python and TypeScript devices send every
request to a randomly chosen server, through a network that loses requests and responses, and must
end with identical data. This server, and the repository's FastAPI and Django example apps, also
pass Accord's black-box HTTP conformance suite, the same one the TypeScript server passes.
Security notes
- Requests authenticate with
Authorization: Bearer <jwt>. In production useAuth.jwks()with an issuer and an audience. - Rate limits are kept in memory, per process: with several worker processes, each has its own buckets.
- Request bodies above
limits.max_body_bytes(default 5 MiB) get 413; the WSGI app stops reading past the limit. - CORS for the sync API is the definition's
corslist, answered by the server. - What a user may read and write is decided only by your
accessfunction and scope functions. See docs/security.md.
Docs: accord.benhattab.pro/docs/python · Source: crossben/accordsync-python · Licence: Apache-2.0
Metadata
Release files for accordsync-server 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| accordsync_server-0.3.0.tar.gz | 32.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| accordsync_server-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.9 kB
Release files / accordsync_server-0.3.0.tar.gz
| Download URL | accordsync_server-0.3.0.tar.gz |
|---|---|
| Size | 32.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
43463e346b968311bfe99686fd47d07eff3ef23ff2255ded8bdf5f47039edee7
|
|
BLAKE2b-256 checksum How to use checksums |
e61529b0590e2f0056b4edec2fc553932a2ef942471ba4bdca223f9963ead1b4
|
| 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 logRelease files / accordsync_server-0.3.0-py3-none-any.whl
| Download URL | accordsync_server-0.3.0-py3-none-any.whl |
|---|---|
| Size | 30.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f1800bf09e41ec87f53c73f573c0eba336478be3b88e01d3f8bc904b4b32e26a
|
|
BLAKE2b-256 checksum How to use checksums |
fa831d0d50fb07589f3c106d332e3a4ab2a71dd5c882ebfc5a7c42809a37e276
|
| 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