Command-Line Interface
Command-Line Interface¶
pyrs-yaml ships an optional command-line tool, pyrs-yaml, that exposes the library's core capabilities — round-trip formatting, JSONPath queries, in-place editing, schema validation, and format conversion — directly in your terminal.
Requirements
The CLI requires the optional cli extra and Python >= 3.10. The library itself keeps supporting older interpreters.
Installation¶
pip install "pyrs-yaml[cli]"
uv add --optional cli pyrs-yaml
Verify the installation:
pyrs-yaml --version
Command Overview¶
| Command | Purpose |
|---|---|
fmt |
Reformat YAML preserving comments, anchors, and order |
get |
Query values by JSONPath expression |
set |
Set a value at a path |
delete |
Remove a node at a path |
rename |
Rename a mapping key |
sort-keys |
Sort mapping keys at a path |
move |
Move a subtree to another existing path |
frontmatter |
Extract Markdown front matter as YAML |
validate |
Validate YAML against a schema |
to-json |
Convert YAML to JSON |
from-json |
Convert JSON to YAML |
compliance |
Report YAML Test Suite compliance |
Every command reads from stdin when the file argument is - or omitted, and writes to stdout unless -o/--output or -i/--inplace says otherwise. Stream-shaped input is handled with -A/--all-docs.
Formatting (fmt)¶
fmt re-serializes a document through the round-trip AST — comments, anchors, key order, and styles survive:
$ echo "a: 1 # keep me" | pyrs-yaml fmt -
a: 1 # keep me
Useful options:
pyrs-yaml fmt config.yaml --indent 4 # 4-space indentation
pyrs-yaml fmt config.yaml --inplace # rewrite the file in place (-i)
pyrs-yaml fmt config.yaml -o formatted.yaml # write to another file
Querying (get)¶
get evaluates a JSONPath-style expression and prints each match:
$ pyrs-yaml get deploy.yaml '$.servers[0].host'
db.example.com
$ pyrs-yaml get deploy.yaml '$..name' --format text # deep scan
web
db
$ pyrs-yaml get deploy.yaml '$.servers[*]' # subtrees as YAML (default)
Output formats via --format/-f: yaml (default), json, or text (raw scalar values).
Editing (set, delete, rename)¶
Editing commands target exactly one node per path (wildcards are rejected):
# VALUE is parsed as YAML — numbers, bools, and nested structures just work
pyrs-yaml set config.yaml "$.retries" 5
pyrs-yaml set config.yaml "$.tags" '[a, b]'
pyrs-yaml set config.yaml "$.token" '12345' --string # force string
pyrs-yaml set config.yaml "$.a.b.c" new --create-missing # create parents
pyrs-yaml delete config.yaml "$.legacy_key"
pyrs-yaml rename config.yaml "$.old_name" new_name
pyrs-yaml set config.yaml "$.port" 8080 --inplace # edit file in place
pyrs-yaml sort-keys config.yaml # sort root mapping keys
pyrs-yaml sort-keys config.yaml "$.meta" # sort one nested mapping
pyrs-yaml move deploy.yaml "$.staging" "$.environments.dev" # relocate a subtree
Edits preserve surrounding metadata — a comment above or beside the edited node stays put.
Notes:
setadds the final key of a path even without--create-missingwhen its parent exists; the flag is only needed for missing intermediate keys.sort-keysorders the keys of the mapping atpath(default root); it is not recursive.move's destination must already exist and its value is replaced by the moved subtree; wildcards are rejected on both ends.
Validation (validate)¶
validate checks a document against a schema definition file or a registered schema name — the two options are mutually exclusive:
pyrs-yaml validate app.yaml --schema-file schema.yaml
pyrs-yaml validate app.yaml --schema my_schema # registered via register_schema()
The command is silent on success and exits 0; on failure every violation is printed to stderr and the exit code is 1 — handy in CI:
# schema.yaml
name: app
extends: core
validate:
- path: $.port
type: int
required: true
See Custom Schemas for the full schema language.
Conversion (to-json, from-json)¶
Both directions compose naturally in pipelines:
$ pyrs-yaml to-json config.yaml
{
"b": {
"c": 2
}
}
$ echo '{"name": "x"}' | pyrs-yaml from-json -
name: x
Multi-document streams¶
Add -A/--all-docs to treat input as a stream of ----separated documents instead of just the first one:
pyrs-yaml fmt stream.yaml -A # reformat every document
pyrs-yaml get stream.yaml '$..name' --format text -A # query across documents
pyrs-yaml to-json stream.yaml -A # JSON array of documents
pyrs-yaml set stream.yaml "$.retries" 5 -A # edit every document
pyrs-yaml validate stream.yaml --schema-file s.yaml -A # failures report "document N"
Supported by fmt, get, set, delete, rename, sort-keys, validate, and to-json. Outputs are joined with standard --- separators; edit commands apply where the path resolves and fail only when no document matches.
Markdown front matter (frontmatter)¶
$ pyrs-yaml frontmatter post.md
title: Hello
$ pyrs-yaml frontmatter post.md --body-out body.md # also split out the body
Exits 1 when the page has no front matter. See Markdown Frontmatter for the library API.
YAML Test Suite compliance (compliance)¶
pyrs-yaml compliance [--json] [SUITE_DIR]
Runs the parser against the yaml-test-suite corpus (default checkout location: ./Reference/yaml-test-suite) and prints pass/fail statistics per suite section — useful when evaluating pyrs-yaml against other YAML implementations.
Exit Codes¶
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Runtime error — unreadable input, parse failure, no match, validation failure |
2 |
Usage error — unknown command or option |
Scripting
Because errors go to stderr and data to stdout, pyrs-yaml composes cleanly: pyrs-yaml get deploy.yaml '$..host' | sort -u.