Marshall/unmarshall JSON to/from DynamoDB JSON format — fast Python library backed by Rust
Project description
dynojson
Marshall / unmarshall JSON to and from DynamoDB JSON format — a fast Python library backed by Rust.
Convert between regular JSON and DynamoDB JSON format on the terminal or in your Python code. Powered by a Rust core via PyO3 for maximum performance.
- 🔥 Works on all platforms (Linux, macOS, Windows)
- 📄 Convert a file from a given file path
- ✏️ Convert a JSON string directly
- ⛓ Read from stdin — pipe in JSON from another command
- 🍰 Extract and convert only a subset of the JSON
- 🤝 Output can be piped or redirected to other commands
- 🧰 Integrate into your workflow with AWS DynamoDB CLI
Installation
pip install dynojson
Python API
All functions accept JSON strings or Python dicts/lists directly. The return type matches the input type.
from dynojson import marshall, unmarshall, get_property
# ── With dicts (recommended) ──────────────────────────────────────
result = marshall({"name": "Alice", "age": 30})
# {"name": {"S": "Alice"}, "age": {"N": "30"}} ← returns a dict
result = unmarshall({"name": {"S": "Alice"}, "age": {"N": "30"}})
# {"name": "Alice", "age": 30} ← returns a dict
# ── With strings (also supported) ─────────────────────────────────
result = marshall('{"name": "Alice", "age": 30}')
# '{"name":{"S":"Alice"},"age":{"N":"30"}}' ← returns a string
result = unmarshall('{"name":{"S":"Alice"},"age":{"N":"30"}}')
# '{"name":"Alice","age":30}' ← returns a string
# ── Extract a property ────────────────────────────────────────────
subset = get_property({"Items": [{"type": {"S": "fruit"}}]}, "Items")
result = unmarshall(subset)
# [{"type": "fruit"}]
CLI Usage
dynojson <command> [options] <json>
Commands:
dynojson unmarshall, u Convert DynamoDB JSON to regular JSON
dynojson marshall, m Convert regular JSON to DynamoDB JSON
Options:
-g <path> Extract a property before converting (dot-separated, supports *)
--version Show version
--help Show help
Unmarshall (DynamoDB JSON → regular JSON)
# From a JSON string
$ dynojson u '{"name":{"S":"Alice"},"age":{"N":"30"}}'
{"name":"Alice","age":30}
# From a file
$ dynojson u data.json
# From stdin
$ cat data.json | dynojson u -
# From AWS CLI
$ aws dynamodb get-item --table-name users --key '{"id":{"S":"1"}}' | dynojson u -g "Item" -
Marshall (regular JSON → DynamoDB JSON)
# From a JSON string
$ dynojson m '{"name":"Alice","age":30}'
{"name":{"S":"Alice"},"age":{"N":"30"}}
# From a file
$ dynojson m data.json
# From stdin
$ echo '{"name":"Alice"}' | dynojson m -
Extract a subset of JSON with -g
Use dot-notation to select a property. Supports numeric array indices and * to expand all array items.
# Get a specific property
$ dynojson m -g "fruits.0.benefits" food.json
# Expand all items
$ dynojson m -g "fruits.*.name" food.json
# With AWS CLI scan output
$ aws dynamodb scan --table-name food | dynojson u -g "Items" -
DynamoDB type mapping
| JSON type | DynamoDB descriptor |
|---|---|
| String | {"S": "…"} |
| Number | {"N": "…"} |
| Boolean | {"BOOL": …} |
| Null | {"NULL": true} |
| Array | {"L": […]} |
| Object | {"M": {…}} |
String sets (SS), number sets (NS), and binary types (B, BS) are also supported during unmarshalling.
Benchmarks
The dict path is faster than the string path because it skips two JSON serialization round-trips (json.dumps + json.loads on the Python side).
| Payload | Marshall speedup | Unmarshall speedup |
|---|---|---|
| Small (1 item) | 1.28x | 1.15x |
| Medium (100 items) | 1.20x | 1.22x |
| Large (10,000 items) | 1.14x | 1.22x |
Run the benchmark yourself:
maturin develop --release
python benchmarks/bench_marshall.py
Development
Prerequisites
Setup
# Clone the repo
git clone https://github.com/cykruss/dynojson.git
cd dynojson
# Create a virtual environment
uv venv
source .venv/bin/activate
# Install build and test dependencies
uv pip install maturin pytest
# Build and install in development mode
maturin develop
# Run Rust tests
cargo test --lib
# Run Python tests
pytest tests/ -v
Project structure
dynojson/
├── Cargo.toml # Rust package manifest
├── pyproject.toml # Python package manifest (maturin build)
├── README.md
├── LICENSE
├── CONTRIBUTING.md
├── src/
│ ├── lib.rs # PyO3 module + re-exports
│ ├── error.rs # Custom error types (thiserror)
│ ├── marshall.rs # Regular JSON → DynamoDB JSON
│ ├── unmarshall.rs # DynamoDB JSON → regular JSON
│ └── property.rs # Dot-path property extraction
├── python/
│ └── dynojson/
│ ├── __init__.py # Public Python API
│ ├── _dynojson.pyi # Type stubs
│ └── cli.py # CLI entry point
├── benchmarks/
│ └── bench_marshall.py # String vs dict path benchmark
└── tests/
├── test_marshall.py
├── test_unmarshall.py
├── test_property.py
└── test_cli.py
Acknowledgements
This project was inspired by ddbjson by Alexandre Duarte, an excellent Node.js CLI tool for converting DynamoDB JSON. dynojson is a ground-up Rust rewrite with Python bindings, building on the same ideas.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dynojson-0.1.2.tar.gz.
File metadata
- Download URL: dynojson-0.1.2.tar.gz
- Upload date:
- Size: 27.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08483bf26eb37a0d0a088156110f5e65703f5f1dce38f3c4121b892c0538367a
|
|
| MD5 |
feb4cebdfbf4286a44a11c47f5087e05
|
|
| BLAKE2b-256 |
cb83c2bfac420fcc7a593953ebda73ab5800bea5caddcb0705431c386ddd5074
|
Provenance
The following attestation bundles were made for dynojson-0.1.2.tar.gz:
Publisher:
CI.yml on cykruss/dynojson
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dynojson-0.1.2.tar.gz -
Subject digest:
08483bf26eb37a0d0a088156110f5e65703f5f1dce38f3c4121b892c0538367a - Sigstore transparency entry: 1006315214
- Sigstore integration time:
-
Permalink:
cykruss/dynojson@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/cykruss
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dynojson-0.1.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: dynojson-0.1.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 311.8 kB
- Tags: PyPy, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
99d76831c0c61c5c53f6642dcc85ccf18d3f1d22b2755b0afed0d3dcec3abba8
|
|
| MD5 |
736bef82acedf5a93fe1a4e78ef63e9f
|
|
| BLAKE2b-256 |
7fd33f270916908a9cba97f3d3945b28bb5f2a424d7bda6fac7b79c965ccbb61
|
Provenance
The following attestation bundles were made for dynojson-0.1.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
CI.yml on cykruss/dynojson
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dynojson-0.1.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
99d76831c0c61c5c53f6642dcc85ccf18d3f1d22b2755b0afed0d3dcec3abba8 - Sigstore transparency entry: 1006315220
- Sigstore integration time:
-
Permalink:
cykruss/dynojson@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/cykruss
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dynojson-0.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: dynojson-0.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 297.1 kB
- Tags: PyPy, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b28a3b1ca89b3d01853cceb13b484730b33ace9972db681f75d6c46eb5faba3d
|
|
| MD5 |
c90cbfb74fdb8bc4d2bfec7082fc5c34
|
|
| BLAKE2b-256 |
8f6fffbba0708bb989aec69f8b329f2342b3a451abc47ea9ac103b68608488e9
|
Provenance
The following attestation bundles were made for dynojson-0.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
CI.yml on cykruss/dynojson
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dynojson-0.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
b28a3b1ca89b3d01853cceb13b484730b33ace9972db681f75d6c46eb5faba3d - Sigstore transparency entry: 1006315218
- Sigstore integration time:
-
Permalink:
cykruss/dynojson@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/cykruss
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dynojson-0.1.2-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: dynojson-0.1.2-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 215.4 kB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
628f3f13370d9473278134368224033c5d50efc44d3202cdb885f03a1253b2b7
|
|
| MD5 |
75791146d726fee356d1b2a9eed2aed9
|
|
| BLAKE2b-256 |
0c0cfeb15107a12a2498c7396c287e3ca78413a6907c91125a82dba351e4a26b
|
Provenance
The following attestation bundles were made for dynojson-0.1.2-cp310-abi3-win_amd64.whl:
Publisher:
CI.yml on cykruss/dynojson
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dynojson-0.1.2-cp310-abi3-win_amd64.whl -
Subject digest:
628f3f13370d9473278134368224033c5d50efc44d3202cdb885f03a1253b2b7 - Sigstore transparency entry: 1006315219
- Sigstore integration time:
-
Permalink:
cykruss/dynojson@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/cykruss
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dynojson-0.1.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: dynojson-0.1.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 311.8 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4cae51574df15c83bb3960c96ad93a0afdc609b2224d77f57a45d9d98e3cd09a
|
|
| MD5 |
aa9d6d7a8a7f0b65fd8256c227be17a5
|
|
| BLAKE2b-256 |
53d164ebf49d40b5c39724ee7be355922303e21cab44c20e39a8a0d80ef6face
|
Provenance
The following attestation bundles were made for dynojson-0.1.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
CI.yml on cykruss/dynojson
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dynojson-0.1.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
4cae51574df15c83bb3960c96ad93a0afdc609b2224d77f57a45d9d98e3cd09a - Sigstore transparency entry: 1006315215
- Sigstore integration time:
-
Permalink:
cykruss/dynojson@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/cykruss
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dynojson-0.1.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: dynojson-0.1.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 296.9 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47dfbe0db38e05e88080142b535724d8905b91514274c2091782559d48bfd2d2
|
|
| MD5 |
655700e9856f59d2be2ddd10bcaa226f
|
|
| BLAKE2b-256 |
6ea76a89da713575ba00a74ad5ffeaf1cc8e58f9f3a48e695ebad2b2c38553df
|
Provenance
The following attestation bundles were made for dynojson-0.1.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
CI.yml on cykruss/dynojson
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dynojson-0.1.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
47dfbe0db38e05e88080142b535724d8905b91514274c2091782559d48bfd2d2 - Sigstore transparency entry: 1006315216
- Sigstore integration time:
-
Permalink:
cykruss/dynojson@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/cykruss
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dynojson-0.1.2-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: dynojson-0.1.2-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 270.0 kB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f384e2bf174c061e9a97e0f26b0598af8b11a4bef7dfb4259cea12de8d0a4170
|
|
| MD5 |
d8341421b278309b0a107892fe423c12
|
|
| BLAKE2b-256 |
0688ce4dde9a2396b913801118f726d12416937d339c6708e1f44b4860ba5c11
|
Provenance
The following attestation bundles were made for dynojson-0.1.2-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
CI.yml on cykruss/dynojson
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dynojson-0.1.2-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
f384e2bf174c061e9a97e0f26b0598af8b11a4bef7dfb4259cea12de8d0a4170 - Sigstore transparency entry: 1006315221
- Sigstore integration time:
-
Permalink:
cykruss/dynojson@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/cykruss
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
CI.yml@ecdeb75cf3c098d86bb08f0cb4f6df1f23a41498 -
Trigger Event:
push
-
Statement type: