Skip to main content

Reference implementation of the JSONLT (JSON Lines Table) specification for Python.

Project description

jsonlt

PyPI CI Codecov CodSpeed Badge Python 3.10+ License: MIT

The Python reference implementation of JSONLT (JSON Lines Table), a data format for storing keyed records in append-only files. JSONLT builds on JSON Lines and optimizes for version control. Modifications append new lines rather than rewriting existing content, producing clean and meaningful diffs.

[!NOTE] This package is under active development. The API may change before the 1.0 release.

Resources

Installation

pip install --pre jsonlt-python

# Or

uv add --pre jsonlt-python

Requires Python 3.10 or later.

Quick start

from jsonlt import Table

# Open or create a table
table = Table("users.jsonlt", key="id")

# Insert or update records
table.put({"id": "alice", "role": "admin", "email": "alice@example.com"})
table.put({"id": "bob", "role": "user", "email": "bob@example.com"})

# Read records
user = table.get("alice")  # Returns the record or None
exists = table.has("bob")  # Returns True

# Delete records (appends a tombstone)
table.delete("bob")

# Iterate over all records
for record in table.all():
    print(record)

The underlying file after these operations:

{"id": "alice", "role": "admin", "email": "alice@example.com"}
{"id": "bob", "role": "user", "email": "bob@example.com"}
{"id": "bob", "$deleted": true}

When to use JSONLT

JSONLT works well for configuration, metadata, and small-to-medium datasets where you want human-readable files that play nicely with Git. It's a good fit when you need keyed record storage but don't want the overhead of a database, and when you want to see exactly what changed in a pull request.

JSONLT is not a database. For large datasets, high write throughput, query operations, or concurrent multi-process access, consider SQLite or a full-featured database.

Compound keys

JSONLT supports multi-field compound keys for composite identifiers:

orders = Table("orders.jsonlt", key=("customer_id", "order_id"))

orders.put({"customer_id": "alice", "order_id": 1, "total": 99.99})
orders.put({"customer_id": "alice", "order_id": 2, "total": 149.99})

order = orders.get(("alice", 1))

Transactions

Transactions provide snapshot isolation and atomic writes with conflict detection:

from jsonlt import Table, ConflictError

table = Table("counters.jsonlt", key="name")

with table.transaction() as tx:
    counter = tx.get("visits")
    new_count = (counter["count"] + 1) if counter else 1
    tx.put({"name": "visits", "count": new_count})
# Commits automatically; rolls back on exception

# Handle concurrent modification conflicts
try:
    with table.transaction() as tx:
        tx.put({"name": "counter", "value": 42})
except ConflictError as e:
    print(f"Conflict on key: {e.key}")

Finding records

# Find all records matching a predicate
expensive = table.find(lambda r: r.get("price", 0) > 100)

# Find with limit
top_3 = table.find(lambda r: r.get("in_stock"), limit=3)

# Find the first match
first = table.find_one(lambda r: r.get("category") == "electronics")

Maintenance

# Compact the file (removes tombstones and superseded records)
table.compact()

# Clear all records
table.clear()

# Force reload from disk
table.reload()

API summary

Table

Method Description
Table(path, key) Open or create a table
get(key) Get a record by key, or None
has(key) Check if a key exists
put(record) Insert or update a record
delete(key) Delete a record
all() Iterate all records
keys() Iterate all keys
items() Iterate (key, record) pairs
count() Number of records
find(predicate, limit=None) Find matching records
find_one(predicate) Find first match
transaction() Start a transaction
compact() Remove historical entries
clear() Remove all records
reload() Reload from disk

The Table class also supports len(table), key in table, and for record in table.

Transaction

Method Description
get(key) Get from snapshot
has(key) Check in snapshot
put(record) Buffer a write
delete(key) Buffer a deletion
commit() Write to disk
abort() Discard changes

Exceptions

All exceptions inherit from JSONLTError:

Exception Description
ParseError Invalid file format
InvalidKeyError Invalid or missing key
FileError I/O error
LockError Cannot get lock
LimitError Size limit exceeded
TransactionError Invalid transaction state
ConflictError Write-write conflict

Conformance

This library implements the JSONLT 1.0 Specification. It provides both Lenient and Strict Parser conformance profiles, and generates Strict-conformant output by default.

As the reference implementation, jsonlt-python passes the JSONLT conformance test suite. Implementers of other JSONLT libraries can use these tests to verify compatibility.

Acknowledgements

The JSONLT format draws from related work including BEADS, which uses JSONL for git-backed structured storage.

AI disclosure

The development of this library involved AI language models, specifically Claude (Anthropic). AI tools contributed to drafting code, tests, and documentation. Human authors made all design decisions and final implementations, and they reviewed, edited, and validated AI-generated content. The authors take full responsibility for the correctness of this software.

This disclosure promotes transparency about modern software development practices.

License

MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jsonlt_python-0.1.0a4.tar.gz (32.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jsonlt_python-0.1.0a4-py3-none-any.whl (40.0 kB view details)

Uploaded Python 3

File details

Details for the file jsonlt_python-0.1.0a4.tar.gz.

File metadata

  • Download URL: jsonlt_python-0.1.0a4.tar.gz
  • Upload date:
  • Size: 32.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.21 {"installer":{"name":"uv","version":"0.9.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for jsonlt_python-0.1.0a4.tar.gz
Algorithm Hash digest
SHA256 a7c45c8e1ed2ed346e3ed7f8b5898ab8ddee51e0aa9d5b101a1b69a1278a47d6
MD5 900e0d98da6874d4d85dcc08c965630a
BLAKE2b-256 77d1dfd9eed760d6c8e64f255f23e52a30f4bf866efe462774971568a1f85d7a

See more details on using hashes here.

File details

Details for the file jsonlt_python-0.1.0a4-py3-none-any.whl.

File metadata

  • Download URL: jsonlt_python-0.1.0a4-py3-none-any.whl
  • Upload date:
  • Size: 40.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.21 {"installer":{"name":"uv","version":"0.9.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for jsonlt_python-0.1.0a4-py3-none-any.whl
Algorithm Hash digest
SHA256 c3d9760022e51289ece81449e0990c5008118c15d1c17f8a9f3290442dcd5842
MD5 0481bdf14c73315beb3c245b6e2a7887
BLAKE2b-256 635e4d44a9c7957454abc7a66c39185116eab55325866e01405fe16cf0bb1bc8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page