yaml

Read and write YAML, the human-friendly data format Sigma rules, CI pipelines and many configs use. Reads maps, lists, [flow] values, quoted and plain text, | and > text blocks, comments, several documents (---), anchors (&name), aliases (*name), merge keys (<<: *base) and the core !!tags.

import yaml

Example

import yaml

let config = yaml.parse(
  "defaults: &d\n  level: high\n  notify: [soc]\nrules:\n  - name: brute force\n    <<: *d\n  - name: scan\n    level: low\n",
)
for r in config.rules {
  say(f"{r.name}: {r.level}")
}
say(yaml.stringify({"name": "Tanisha", "tags": ["a", "b"]}))
say(len(yaml.parse_all("a: 1\n---\nb: 2\n")))

Functions

parse(text)

returns value

Turn YAML text into TB values: maps, lists, text, numbers, true/false and nil. The text must hold one document; use parse_all() for a file with several (--- lines).

Visualizehow yaml.parse works

yaml.parse("name: tb\nports:\n - 80\n - 443\ntls:\n cert: site.pem") gives {"name": "tb", "ports": [80, 443], "tls": {"cert": "site.pem"}}

yaml.parse: inputs flowing into the function and the resulttextname: tbports: - 80 - 443tls: cert: site.pemyaml.parsemaps and lists, nested the same wayname"tb"ports[80, 443]tls{map}cert"site.pem"

Real result: worked out by running this example with TB while the site was built.

parse_all(text)

returns list

Every document in the YAML text (separated by --- lines), as a list of values.

Visualizehow yaml.parse_all works

yaml.parse_all("name: web01\n---\nname: web02\n---\nname: db01") gives [{"name": "web01"}, {"name": "web02"}, {"name": "db01"}]

yaml.parse_all: inputs flowing into the function and the resulttextname: web01---name: web02---name: db01yaml.parse_allone value per --- documentnameweb01web02db01

Real result: worked out by running this example with TB while the site was built.

stringify(value, indent?)

returns text

Turn a TB value into YAML text (block style: one key per line, lists with "- ", text with line breaks as a | block). indent is the number of spaces per level (default 2).

Visualizehow yaml.stringify works

yaml.stringify({"name": "tb", "ports": [80, 443], "tls": {"cert": "site.pem"}}, 2) gives "name: tb\nports:\n- 80\n- 443\ntls:\n cert: site.pem\n"

yaml.stringify: inputs flowing into the function and the resultvaluename"tb"ports[80, 443]tls{map}cert"site.pem"indent?2yaml.stringifyYAML text, one key per linename: tbports:- 80- 443tls: cert: site.pemvaluename"tb"ports[80, 443]tls{map}cert"site.pem"indent?4yaml.stringifyYAML text, one key per linename: tbports:- 80- 443tls: cert: site.pem

Real result: worked out by running this example with TB while the site was built.

read(path)

returns value

Read a .yml / .yaml file with one document into TB values.

Visualizehow yaml.read works

yaml.read("config.yml") gives {"name": "tb", "ports": [80, 443]}

yaml.read: inputs flowing into the function and the resultpath"config.yml"config.ymlname: tbports: - 80 - 443yaml.readTB valuesname"tb"ports[80, 443]

Real result: worked out by running this example with TB while the site was built.

read_all(path)

returns list

Read every document (--- separated) in a YAML file.

Visualizehow yaml.read_all works

yaml.read_all("hosts.yml") gives [{"name": "web01"}, {"name": "db01"}]

yaml.read_all: inputs flowing into the function and the resultpath"hosts.yml"hosts.ymlname: web01---name: db01yaml.read_alla list: one value per documentnameweb01db01

Real result: worked out by running this example with TB while the site was built.

write(path, value, indent?)

returns nil

Write a TB value to a file as YAML.

Visualizehow yaml.write works

yaml.write("out.yml", {"name": "tb", "tls": {"cert": "site.pem"}}, 2)

yaml.write: inputs flowing into the function and the resultpath"out.yml"indent?2valuename"tb"tls{map}cert"site.pem"yaml.writeout.yml afterwards (read back)name: tbtls: cert: site.pempath"out.yml"indent?4valuename"tb"tls{map}cert"site.pem"yaml.writeout.yml afterwards (read back)name: tbtls: cert: site.pem

Real result: worked out by running this example with TB while the site was built.