name: processing-yaml description: Creates, reads, modifies, and validates YAML files with Python. Use when the user asks to parse, edit, generate, or fix a .yaml or .yml file, mentions YAML syntax errors, or works with YAML-based config files such as docker-compose.yml, Kubernetes manifests, or GitHub Actions workflow files. Do not use for JSON files or for authoring the logic of CI pipelines — only the YAML file mechanics.
Processing YAML
When to use / when NOT to use
- Use for: creating, reading, editing, or validating
.yaml/.ymlfiles — app configs, docker-compose, Kubernetes manifests, CI workflow files (the file mechanics). - Do NOT use for: JSON files (use
jsondirectly) or designing the logic of CI pipelines — this skill covers YAML file handling, not what the pipeline should do.
Quick reference
Default: PyYAML (pip install pyyaml). Escape hatch: ruamel.yaml (pip install ruamel.yaml) only when comments and formatting must survive a round-trip edit — PyYAML discards them.
python
import yaml
# Read — safe_load ONLY
with open("config.yaml") as f:
data = yaml.safe_load(f) # returns dict/list/scalars
# Modify
data["server"]["port"] = 8080
# Write
with open("config.yaml", "w") as f:
yaml.safe_dump(data, f, default_flow_style=False,
sort_keys=False, allow_unicode=True)Comment-preserving edit (ruamel.yaml):
python
from ruamel.yaml import YAML
y = YAML() # round-trip mode by default
doc = y.load(open("config.yaml"))
doc["server"]["port"] = 8080
y.dump(doc, open("config.yaml", "w"))Rules
- NEVER
yaml.load()withoutSafeLoader— it executes arbitrary Python object constructors.safe_load/safe_dumpalways. - Quote strings that YAML would reinterpret:
"no","on","yes", version strings like"1.10", country codes like"NO". - 2-space indentation; never tabs (tabs are a YAML syntax error).
- If the file has comments the user wants kept, use ruamel.yaml — a PyYAML round-trip silently deletes them.
Workflow
- Determine the operation and whether comments/formatting must survive (→ ruamel.yaml).
- Parse with
yaml.safe_load; onyaml.YAMLError, report its message with line/column verbatim and stop — do not guess. - Modify the loaded structure (recipes in references/recipes.md), quoting ambiguous scalars.
- Write with
safe_dump(default_flow_style=False, sort_keys=False, allow_unicode=True)to keep block style, key order, and non-ASCII text. - Validate: re-parse the written file with
safe_load; for multi-document files confirm document count is unchanged. Fix and repeat step 3 until clean.
Edge cases & failure modes
- PyYAML missing →
pip install pyyaml; ruamel.yaml missing →pip install ruamel.yaml. - Malformed YAML → relay the parser error (it includes line/column); common causes to mention: tabs, unquoted
:in values, bad indentation. - Multi-document files (
---separators) → useyaml.safe_load_all()/yaml.safe_dump_all(); plainsafe_loadraises on the second document. - Encoding → open files as UTF-8;
allow_unicode=Trueon dump prevents\uXXXXescaping of accented text. - Huge files → YAML has no practical streaming parser; for >50 MB data files, question whether the data belongs in YAML at all and suggest JSON/CSV.
References
Deeper copy-paste recipes (anchors, multi-doc, schema validation, JSON conversion): see references/recipes.md.