Skip to main content

Marshall/unmarshall JSON to/from DynamoDB JSON format — fast Python library backed by Rust

Project description

dynojson

CI PyPI crates.io Python License: MIT

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"}]

File & Directory API

Process files and directories directly — Rust handles all I/O, skipping Python-Rust FFI overhead for large payloads.

from dynojson import marshall_file, unmarshall_file, marshall_dir, unmarshall_dir

# ── Single file ─────────────────────────────────────────────────

# File → dict (no output_path)
result = marshall_file("data.json")

# File → file (with output_path)
marshall_file("data.json", "output.json")

# With property extraction
result = unmarshall_file("scan.json", get="Items")

# ── Directory batch processing ──────────────────────────────────

# Mirror mode — one output file per input file
count = marshall_dir("input/", "output/")

# Merge mode — all results into a single JSON array
count = unmarshall_dir("input/", "merged.json", merge=True)

# With property extraction (e.g. DynamoDB scan exports)
count = unmarshall_dir("scans/", "output/", get="Items")

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_file_io.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

MIT

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

dynojson-0.2.0.tar.gz (33.5 kB view details)

Uploaded Source

Built Distributions

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

dynojson-0.2.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (334.7 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

dynojson-0.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (318.5 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

dynojson-0.2.0-cp310-abi3-win_amd64.whl (248.2 kB view details)

Uploaded CPython 3.10+Windows x86-64

dynojson-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (334.3 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

dynojson-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (318.2 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

dynojson-0.2.0-cp310-abi3-macosx_11_0_arm64.whl (290.4 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file dynojson-0.2.0.tar.gz.

File metadata

  • Download URL: dynojson-0.2.0.tar.gz
  • Upload date:
  • Size: 33.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dynojson-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e8b8eeb1ca0f6ef9279fbc4d4a61d9304e0a3e78db8d8d6b1d5f37e5dc07e78a
MD5 2e2ec6b159fe16130e8573d5e37f362f
BLAKE2b-256 0a7cc6d661e3af1e7a844314e6c965c56db2b003e60801bf1aa30fd88ca4fad6

See more details on using hashes here.

Provenance

The following attestation bundles were made for dynojson-0.2.0.tar.gz:

Publisher: CI.yml on cykruss/dynojson

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dynojson-0.2.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for dynojson-0.2.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 dd9492a93c9734056ba686943857c5b6f3af4dc4074f53d44dd619a7d5c79ec9
MD5 4afde4454c73dc43a3e4312d2b21c6b8
BLAKE2b-256 43028add1909e76df0943e6fee1c78322dd2ddacc61068910417e7d5c1d7d746

See more details on using hashes here.

Provenance

The following attestation bundles were made for dynojson-0.2.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: CI.yml on cykruss/dynojson

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dynojson-0.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for dynojson-0.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 8418b9da21045d7e6c5bd69fc25e71685090611e09c06bcd552ce28c94aff0fe
MD5 21e513366c17dad5ba6eed4a2e92b771
BLAKE2b-256 23ce2b8aac682217938c9e8cb8858b9e0539e92155134190cc2feb24e6c1008d

See more details on using hashes here.

Provenance

The following attestation bundles were made for dynojson-0.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: CI.yml on cykruss/dynojson

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dynojson-0.2.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: dynojson-0.2.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 248.2 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

Hashes for dynojson-0.2.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 4b01972f17618d97be1acc02ca40be7c7eb2ad5afc4d39c6aa9910c3f2f3c04b
MD5 7c6679b1501ed8b433cbb4f26f6879c3
BLAKE2b-256 10a45d9de8128e2b0ae3284217721458124ad79cf04132476ad84e8750731490

See more details on using hashes here.

Provenance

The following attestation bundles were made for dynojson-0.2.0-cp310-abi3-win_amd64.whl:

Publisher: CI.yml on cykruss/dynojson

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dynojson-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for dynojson-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 04e40ba35cdd44d0b84bbcd880d6c88bd4cbd48da0f8e0ae5cbe5a59f3498348
MD5 aef26ed95a6d7861b3be71fe857098de
BLAKE2b-256 6cc839c6ca3dfc10fbc09f7740ca9ad2ee0a2b72e6c2e4da93138bb83ecb87c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for dynojson-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: CI.yml on cykruss/dynojson

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dynojson-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for dynojson-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 aa96c1b435bc95843960d6c0d38eed86161a7b0b435bcec209b8e5d9c539c527
MD5 9f3fe4bc3be2453f1c57a2e866796755
BLAKE2b-256 cb75d8d995293484f39dc3c1884e46927847a41a5d195259a48336b7057affdd

See more details on using hashes here.

Provenance

The following attestation bundles were made for dynojson-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: CI.yml on cykruss/dynojson

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dynojson-0.2.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for dynojson-0.2.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 570868b3d473dd61d50d8b0664cc94d325b79264f683ff8ac4db14a8451ba3d2
MD5 dec5a33f91e14aec13f8fc32719ceaef
BLAKE2b-256 621c9a9d0f7de21885b642d74ba6675ee49a8f80775dec5a17b75b786951642e

See more details on using hashes here.

Provenance

The following attestation bundles were made for dynojson-0.2.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: CI.yml on cykruss/dynojson

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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