ꘇ dat.json
Turn a wall of JSON into something a graph can read
- input
- table
- text
What it's for
You've got a JSON blob - a parameter dump, a list of presets, whatever an API node spat back - and you want to pull one number out of it and wire it to a widget. ꘇ dat.json is the node that turns that text into a table the rest of the Genereti operators can slice, filter and convert.
Within Genereti's own vocabulary it's the front door to the DAT family: a DAT here is a string table - CSV, basically - and every DAT node in this pack speaks the same two outputs, a GENERETI_DAT table and its CSV text. dat.json is how JSON gets into that world. It's the TouchDesigner DAT idea, minus the engine.
The mechanism, including the part that looks magic
The parsing is not a straight json.loads and dump. The shipped code branches on the shape of your JSON:
- An object becomes a two-column
key,valuetable, one row per key. - An array of objects becomes a proper header row - the union of all keys, in first-seen order - with one row per object, missing keys filled blank. This is the case you'll actually hit with API-ish payloads.
- An array of arrays becomes rows directly; a single scalar becomes a one-cell table.
So [{"speed":0.5,"influence":0.8}] (the default value) gives you a 2×2 table with a header, and dat.select can pull the speed column clean out of it.
Then there's the optional half of the node, which is where the real utility sits. input (GENERETI_DAT) is checked first; if nothing is wired there, it parses the json input; only then does it fall back to the text widget. That's a cascade - same pattern as Comfy's typing rules elsewhere - so you can leave the text box as a scratch pad and hot-swap to a wired source without rewiring anything downstream.
filter and selection then narrow the result. filter is a case-insensitive substring test run against the values of each entry (and for a top-level list, against the whole entry). selection is zero-based indices separated by commas - the author's tooltip: "Zero-based entry indices, separated by commas; empty selects all matches" - and it validates hard, raising Selection must contain zero-based row indices if you type anything else. The two compose: filter first, then keep only the selected indices among what matched. That indirection catches people, since the indices refer to the original ordering, not the filtered list.
Outputs are the standard pair: table (GENERETI_DAT) and text (CSV). Your selection only affects the JSON-shaped path in the way you'd expect; if the node is working from a plain table, you get the filtered rows back.
Wiring it in
Typical beginner graph, and the one worth copying: dat.json → dat.select (pick the row and columns) → dat.tochop (columns become channels) → the CHOP's value FLOAT into a sampler seed you converted to an input. Or stop halfway and send text into a dat.inspect if you just want to see what survived the filter.
If you only need one cell, skip the pipeline: dat.cell takes a table and a row/column pair and gives you a STRING and a FLOAT.
Install
It ships in the Genereti pack only. Manager → search Genereti (liuboto) → restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/languel/genereti.git genereti
then install the pack's requirements with the Python that belongs to your ComfyUI (./.venv/bin/python -m pip install -r custom_nodes/genereti/requirements.txt; python_embeded\python.exe on Portable). That file contains one line - comfyui-frontend-package>=1.53.6 - so there's nothing heavy to download and no models involved. The pack wants ComfyUI 0.38.2+ and Python 3.11+, and you must restart Comfy and refresh the browser tab, because the text editor widget is browser-side JavaScript.
Gotchas
- Invalid JSON is a hard failure. There's no lenient mode; a trailing comma kills the node with a Python exception. Paste it into
dat.inspectfirst if you're not sure. - The flag default assumes you want the widget. With everything optional unconnected, the node parses
text. That default string is valid JSON, so a fresh node doesn't error - it just produces a table you didn't ask for. selectionis order-of-original, not order-of-filter. Read the tooltip twice.- Alpha software. The README leads with "super alpha, early classroom testing - back up your workflows before updating." The DAT operators are the least exciting and most stable part of the pack, but the pack itself is moving.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | [{"speed":0.5,"influence":0.8}] | — |
| inputopt | GENERETI_DAT | — | |
| jsonopt | STRING | — | |
| filteropt | STRING | — | |
| selectionopt | STRING | Zero-based entry indices, separated by commas; empty selects all matches |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| table | GENERETI_DAT | — |
| text | STRING | — |