Skip to main content

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 use Auth.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 cors list, answered by the server.
  • What a user may read and write is decided only by your access function 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)

Source distribution for accordsync-server 0.3.0
File Size Uploaded
accordsync_server-0.3.0.tar.gz 32.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for accordsync-server 0.3.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

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