tallipoika
A stable son (Finnish: tallipoika) — a JSON Canonicalization Scheme (JCS) implementation conforming to RFC 8785.
Requires Python 3.11 or later.
Install
pip install tallipoika
Manual
The man page provides the CLI reference (man tallipoika after placing the file on your MANPATH):
mkdir -p ~/.local/share/man/man1
cp docs/man/tallipoika.1 ~/.local/share/man/man1/
Quickstart
Run tallipoika with no arguments for a usage summary,
or tallipoika --version to check the installed version.
The library function for canonical JSON is canonicalize:
from tallipoika.api import canonicalize
result = canonicalize({"b": 2, "a": 1})
# b'{"a":2,"b":1}'
To serialize without key sorting, use serialize:
from tallipoika.api import serialize
result = serialize({"b": 2, "a": 1})
# b'{"b":2,"a":1}'
The command line tool reads JSON from a file or stdin and writes to a file or stdout:
tallipoika --in-path input.json --out-path output.json
echo '{"b":2,"a":1}' | tallipoika
# {"a":2,"b":1}
RFC 8785 compliance
tallipoika implements the JSON Canonicalization Scheme (JCS) defined by RFC 8785:
- UTF-8 output: all output is UTF-8 encoded bytes.
- No whitespace: no indentation, no spaces around
:or,. - Key sort by UTF-16BE byte order: object keys are sorted by their UTF-16BE
encoding, which matches the ES6
String.prototype.localeCompareordering used by JCS-compliant implementations. - ES6 §7.1.12.1 number serialization: floats are serialized using the shortest representation that round-trips through the ES6 number parsing algorithm.
- NaN and Infinity rejected:
allow_nan=Falseby default per RFC 8785 §3.2.2.3. - Control character escaping: code points U+0000–U+001F are escaped as
\uXXXX. - Unicode passthrough: non-ASCII characters above U+001F pass through verbatim
(
ensure_ascii=Falseby default).
API
canonicalize(obj, utf8=True) -> bytes
Produce RFC 8785 JCS-canonical JSON for obj.
Raises ValueError for NaN or Infinity float values.
Raises TypeError for non-serializable objects.
serialize(obj, utf8=True) -> bytes
Produce JSON without key sorting; all other RFC 8785 rules (number format, control-character escaping, no whitespace) still apply.
JSONEncoder
The underlying encoder class with JCS defaults:
from tallipoika.api import JSONEncoder
encoder = JSONEncoder(sort_keys=True)
output = encoder.encode({"b": 2, "a": 1})
# '{"a":2,"b":1}'
Constructor keyword arguments and their JCS defaults:
| Argument | JCS default | Description |
|---|---|---|
skipkeys |
False |
Skip non-string keys instead of raising TypeError |
ensure_ascii |
False |
Escape non-ASCII; disabled for Unicode passthrough |
check_circular |
True |
Raise ValueError on circular references |
allow_nan |
False |
Reject NaN/Infinity per RFC 8785 §3.2.2.3 |
sort_keys |
True |
Sort object keys by UTF-16BE byte order |
indent |
None |
No indentation |
separators |
(',', ':') |
No whitespace around , or : |
default |
None |
Custom serializer for non-standard types |
CLI
tallipoika [--in-path PATH] [--out-path PATH] [--serialize-only] [--version]
| Option | Default | Description |
|---|---|---|
--in-path PATH |
stdin | Input JSON file; also accepted as positional argument |
--out-path PATH |
stdout | Output path; writes bytes when path given, text to stdout |
--serialize-only |
off | Serialize only — do not sort keys |
--version, -V |
— | Print version string and exit |
Design and requirements
| Document | Identifier | File |
|---|---|---|
| Software Requirements Specification | TAL-SRS-001 | docs/requirements/srs/ |
| Software Design Description | TAL-SDD-001 | docs/design/sdd/ |
Both documents follow the MIL-STD-498 DID structure.
Bug Tracker
Any feature requests or bug reports shall go to the todos of tallipoika.
Primary Source repository
The main source of tallipoika is on a mountain in Central Switzerland under
configuration control (fossil).
Contributions
If you like to share small changes under the repositories license please kindly do so by sending a patchset. You can send such a patchset per email using git send-email.
Support
Please kindly submit issues at https://todo.sr.ht/~sthagen/tallipoika or write plain text email to ~sthagen/tallipoika@lists.sr.ht to support. Thanks.
Security Policy
See SECURITY.md for the security policy.
Changes
See docs/releases/ for release summaries and docs/releases/changes/ for the detailed change log.
Coverage
The test suite maintains high branch coverage (≥97%).
The HTML report (if generated) is in site/coverage/.
SBOM
Runtime dependency information is published in docs/sbom/ in SPDX 3.0 (JSON-LD)
and CycloneDX 1.6 (JSON) formats.
See docs/sbom/README.md for the component inventory and validation guide.
Metadata
Release files for tallipoika 2026.7.19
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tallipoika-2026.7.19.tar.gz | 20.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tallipoika-2026.7.19-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.6 kB
Release files / tallipoika-2026.7.19.tar.gz
| Download URL | tallipoika-2026.7.19.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d99a300732b15114acb2cd0715072d797cd765841d3a23d8de6a2f1b9c6b0b81
|
|
BLAKE2b-256 checksum How to use checksums |
3c2899579e6523777b742e565657a2d6814c0c42fff8628dfa8ab131e3483ee8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|
Release files / tallipoika-2026.7.19-py3-none-any.whl
| Download URL | tallipoika-2026.7.19-py3-none-any.whl |
|---|---|
| Size | 13.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4f382027330486a4946d1ad982e8273d48f1159c016180bba0c81bf5958e7a8f
|
|
BLAKE2b-256 checksum How to use checksums |
114d70c8565e17f1cdbd47720bde37f147b888889f14dab5bf6cf59fe997891a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|