<===

ProNotes

2026-02-16 11:36:29
Проверяем синтаксис YAML своими руками на Python
При работе с Prometheus и другими системами конфигурации на YAML удобно иметь быстрый CLI‑инструмент, который просто отвечает: “конфиг валиден / конфиг битый”. В этой мини‑статье сделаем две реализации на Python:

Вариант 1 — дополнительный линт отступов и табов.

Вариант 2 — проверка через парсер PyYAML.


########## test yml самодостаточный ###########################
#!/usr/bin/env python3
import argparse
import sys
from pathlib import Path

import yaml  # pip install pyyaml [web:21][web:24]

def check_yaml(path: Path) -> bool:
    try:
        with path.open("r", encoding="utf-8") as f:
            yaml.safe_load(f)
        print(f"[OK] {path}")
        return True
    except yaml.YAMLError as e:
        print(f"[ERROR] {path}")
        print(e)
        return False
    except OSError as e:
        print(f"[ERROR] {path}: {e}")
        return False

def iter_paths(targets, recursive: bool):
    for t in targets:
        p = Path(t)
        if p.is_dir():
            if recursive:
                for f in p.rglob("*.yml"):
                    yield f
                for f in p.rglob("*.yaml"):
                    yield f
            else:
                for f in p.glob("*.yml"):
                    yield f
                for f in p.glob("*.yaml"):
                    yield f
        else:
            yield p

def main(argv=None) -> int:
    parser = argparse.ArgumentParser(
        prog="pyyamllint",
        description="Simple YAML syntax checker based on PyYAML.",
    )  # [web:42][web:49]

    parser.add_argument(
        "paths",
        nargs="+",
        help="Files or directories to check (YAML files).",
    )
    parser.add_argument(
        "-r",
        "--recursive",
        action="store_true",
        help="Recurse into directories.",
    )
    args = parser.parse_args(argv)

    ok = True
    for path in iter_paths(args.paths, args.recursive):
        if not check_yaml(path):
            ok = False

    return 0 if ok else 1

if __name__ == "__main__":
    raise SystemExit(main())

########## test yml ###########################
#!/usr/bin/env python3
import sys
import yaml

def check_yaml(path: str) -> int:
    try:
        with open(path, "r", encoding="utf-8") as f:
            yaml.safe_load(f)  # пробуем распарсить [web:21][web:24]
        print(f"[OK] {path}")
        return 0
    except yaml.YAMLError as e:
        print(f"[ERROR] {path}")
        # PyYAML обычно даёт строку/колонку
        print(e)
        return 1

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} file1.yml [file2.yml ...]")
        sys.exit(1)

    rc = 0
    for p in sys.argv[1:]:
        rc |= check_yaml(p)
    sys.exit(rc)



######## example #################
---
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets:
          - "localhost:9090"

alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - "alertmanager:9093"
...   
← Previous Next →
Back to list