Skip to main content

Budget‑constrained JSON preview renderer (Python bindings)

Project description

headson

Head/tail for JSON — but structure‑aware. Get a compact preview that shows both the shape and representative values of your data, all within a strict character budget.

Available as:

Install

Using Cargo:

cargo install headson

From source:

cargo build --release
target/release/headson --help

Features

  • Budgeted output: specify exactly how much JSON you want to see
  • Multiple output formats : json (machine‑readable), pseudo (human‑friendly), js (valid JavaScript, most detailed metadata).
  • Multiple inputs: preview many files at once with a shared or per‑file budget.
  • Fast: can process gigabyte-scale files in seconds (mostly disk-constrained)
  • Available as a CLI app and as a Python library

Fits into command line workflows

If you’re comfortable with tools like head and tail, use headson when you want a quick, structured peek into a JSON file without dumping the entire thing.

  • head/tail operate on bytes/lines - their output is not optimized for tree structures
  • jq you need to craft filters to preview large JSON files
  • headson is like head/tail for trees: zero config but it keeps structure and represents content as much as possible

Usage

headson [FLAGS] [INPUT...]
  • INPUT (optional, repeatable): file path(s). If omitted, reads JSON from stdin. Multiple input files are supported.
  • Prints the preview to stdout. On parse errors, exits non‑zero and prints an error to stderr.

Common flags:

  • -n, --budget <BYTES>: per‑file output budget. When multiple input files are provided, the total budget equals <BYTES> * number_of_inputs.
  • -N, --global-budget <BYTES>: total output budget across all inputs. Useful when you want a fixed-size preview across many files (may omit entire files). Mutually exclusive with --budget.
  • -f, --template <json|pseudo|js>: output style (default: pseudo)
  • -m, --compact: no indentation, no spaces, no newlines
  • --no-newline: single line output
  • --no-space: no space after : in objects
  • --indent <STR>: indentation unit (default: two spaces)
  • --string-cap <N>: max graphemes to consider per string (default: 500)
  • --head: prefer the beginning of arrays when truncating (keep first N). Strings are unaffected. In pseudo/js templates the omission marker appears near the end; json remains strict. Mutually exclusive with --tail.
  • --tail: prefer the end of arrays when truncating (keep last N). Strings are unaffected. In pseudo/js templates the omission marker appears at the start; json remains strict. Mutually exclusive with --head.

Notes:

  • With multiple input files:
    • JSON template outputs a single JSON object keyed by the input file paths.
    • Pseudo and JS templates render file sections with human-readable headers when newlines are enabled.
      • If you use --compact or --no-newline (both disable newlines), fileset output falls back to standard inline rendering (no per-file headers) to remain compact.
    • Using --global-budget may truncate or omit entire files to respect the total budget.
    • The tool finds the largest preview that fits the budget; if even the tiniest preview exceeds it, you still get a minimal, valid preview.
    • When passing file paths, directories and binary files are ignored; a notice is printed to stderr for each (e.g., Ignored binary file: ./path/to/file). Stdin mode reads the stream as-is.
    • Head vs Tail sampling: these options bias which part of arrays are kept before rendering. They guarantee the kept segment is contiguous at the chosen side (prefix for --head, suffix for --tail). Display templates may still insert additional internal gap markers inside that kept segment to honor very small budgets; json remains strict and unannotated.

Quick one‑liners:

  • Peek a big JSON stream (keeps structure):

    zstdcat huge.json.zst | headson -n 800 -f pseudo
    
  • Many files with a fixed overall size:

    headson -N 1200 -f json logs/*.json
    
  • Glance at a file, JavaScript‑style comments for omissions:

    headson -n 400 -f js data.json
    

Show help:

headson --help

Examples: head vs headson

Input:

{"users":[{"id":1,"name":"Ana","roles":["admin","dev"]},{"id":2,"name":"Bo"}],"meta":{"count":2,"source":"db"}}

Naive cut (can break mid‑token):

jq -c . users.json | head -c 80
# {"users":[{"id":1,"name":"Ana","roles":["admin","dev"]},{"id":2,"name":"Bo"}],"me

Structured preview with headson (pseudo):

headson -n 120 -f pseudo users.json
# {
#   users: [
#     { id: 1, name: "Ana", roles: [ "admin", … ] },
#     …
#   ]
#   meta: { count: 2, … }
# }

Machine‑readable preview (json):

headson -n 120 -f json users.json
# {"users":[{"id":1,"name":"Ana","roles":["admin"]}],"meta":{"count":2}}

Python Bindings

A thin Python extension module is available on PyPI as headson.

  • Install: pip install headson (ABI3 wheels for Python 3.10+ on Linux/macOS/Windows).
  • API:
    • headson.summarize(text: str, *, template: str = "pseudo", character_budget: int | None = None, skew: str = "balanced") -> str
      • template: one of "json" | "pseudo" | "js"
      • character_budget: maximum output size in characters (default: 500)
      • skew: one of "balanced" | "head" | "tail" (focus arrays on start vs end; only affects display templates; json remains strict).

Example:

import json
import headson

data = {"foo": [1, 2, 3], "bar": {"x": "y"}}
preview = headson.summarize(json.dumps(data), template="json", character_budget=200)
print(preview)

# Prefer the tail of arrays (annotations show in pseudo/js only)
print(
    headson.summarize(
        json.dumps(list(range(100))),
        template="pseudo",
        character_budget=80,
        skew="tail",
    )
)

Algorithm

%%{init: {"themeCSS": ".cluster > rect { fill: transparent; stroke: transparent; } .clusterLabel > text { font-size: 16px; font-weight: 600; } .clusterLabel span { padding: 6px 10px; font-size: 16px; font-weight: 600; }"}}%%
flowchart TD
    subgraph Deserialization
        direction TB
        A["Input file(s)"]
        A -- Single --> C["Parse into optimized tree (with array pre‑sampling) ¹"]
        A -- Multiple --> D["Parse each file and wrap into a fileset object"]
        D --> C
    end
    subgraph Prioritization
        direction TB
        E["Build priority order ²"]
        F["Choose top N nodes ³"]
    end
    subgraph Serialization
        direction TB
        G["Render attempt ⁴"]
        H["Output preview string"]
    end
    C --> E
    E --> F
    F --> G
    G --> F
    F --> H
    %% Color classes for categories
    classDef des fill:#eaf2ff,stroke:#3b82f6,stroke-width:1px,color:#0f172a;
    classDef prio fill:#ecfdf5,stroke:#10b981,stroke-width:1px,color:#064e3b;
    classDef ser fill:#fff1f2,stroke:#f43f5e,stroke-width:1px,color:#7f1d1d;
    class A,C,D des;
    class E,F prio;
    class G,H ser;
    style Deserialization fill:transparent,stroke:transparent
    style Prioritization fill:transparent,stroke:transparent
    style Serialization fill:transparent,stroke:transparent

Footnotes

  • [1] Optimized tree representation: An arena‑style tree stored in flat, contiguous buffers. Each node records its kind and value plus index ranges into shared child and key arrays. Arrays are ingested in a single pass and may be deterministically pre‑sampled: the first element is always kept; additional elements are selected via a fixed per‑index inclusion test; for kept elements, original indices are stored and full lengths are counted. This enables accurate omission info and internal gap markers later, while minimizing pointer chasing.
  • [2] Priority order: Nodes are scored so previews surface representative structure and values first. Arrays can favor head/mid/tail coverage (default) or strictly the head; tail preference flips head/tail when configured. Object properties are ordered by key, and strings expand by grapheme with early characters prioritized over very deep expansions.
  • [3] Choose top N nodes (binary search): Iteratively picks N so that the rendered preview fits within the character budget, looping between “choose N” and a render attempt to converge quickly.
  • [4] Render attempt: Serializes the currently included nodes using the selected template. Omission summaries and per-file section headers appear in display templates (pseudo/js); json remains strict. For arrays, display templates may insert internal gap markers between non‑contiguous kept items using original indices.

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

headson-0.5.0.tar.gz (43.2 kB view details)

Uploaded Source

Built Distributions

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

headson-0.5.0-cp310-abi3-win_amd64.whl (228.3 kB view details)

Uploaded CPython 3.10+Windows x86-64

headson-0.5.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (336.9 kB view details)

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

headson-0.5.0-cp310-abi3-macosx_11_0_arm64.whl (286.9 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file headson-0.5.0.tar.gz.

File metadata

  • Download URL: headson-0.5.0.tar.gz
  • Upload date:
  • Size: 43.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.9.6

File hashes

Hashes for headson-0.5.0.tar.gz
Algorithm Hash digest
SHA256 3b779cff12a4e9d4f24acffd922d4868bfa2a4c78f15cdf31dbc3b0334341a63
MD5 7cdfb1db821251ed45274d6c95b14ca3
BLAKE2b-256 fbcfdff37fb7f9d3163a8bb4b75c80a0b4fbfb7f26fb5e1cc547cccdd9e679ff

See more details on using hashes here.

File details

Details for the file headson-0.5.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: headson-0.5.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 228.3 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.9.6

File hashes

Hashes for headson-0.5.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 22ccf11e30a7a36cbe4fbc8e8005a1422b9367b419f5e2f971853fcd0b3992bb
MD5 ddb71bedd9d1ceec57cb2f25ff8cfae0
BLAKE2b-256 778b8a5927d76694c0d6f6d1e80bdc1ae649270807a5e15a32822c1118742429

See more details on using hashes here.

File details

Details for the file headson-0.5.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for headson-0.5.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d4499875d717ac3a96e664a21c1f4d5e2266199e5313f644cbb75b8dd8512bb5
MD5 98ff3325af7d70afb5d28c13ded43566
BLAKE2b-256 52971b7e9736874ceb49ace73ce7997d0ed4487d66fdb48057cad956f08d12b8

See more details on using hashes here.

File details

Details for the file headson-0.5.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for headson-0.5.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 dee3c438c3664f42826917c83820824dead6acf413656571c61a51b3f77c479a
MD5 e1fb7c6a21c9b176341f9ea1f7af9955
BLAKE2b-256 9674707c5ab790e663774c8746cad1ccfa3638ecd703d6afb2a2245c5b0f3446

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