xYang
Parse YANG modules, validate JSON instance data, and export JSON Schema—without a NETCONF stack.
xYang targets real-world modules and pipelines: agents, CI, and schema tooling that need RFC 7950-style checks (must, when, if-feature, built-in types, leafrefs, and the rest) on one consolidated JSON document (RFC 7951). It can also emit a JSON Schema (2020-12) view with x-yang metadata for round-trip where supported.
The same feature set is implemented twice:
Python (xyang) |
TypeScript (@exergy-connect/xyang) |
|
|---|---|---|
| Package | PyPI xyang |
npm @exergy-connect/xyang |
| CLI | xyang |
xyang-ts |
| Runtime | Python ≥ 3.10, zero required deps | Node ≥ 24 |
| Source | src/xyang/ |
ts/src/ |
Not every YANG statement is modeled; unsupported constructs are skipped with a warning so mixed modules still load. See FEATURES.md for the full matrix, JSON hybrid format, and known gaps.
Repository: github.com/exergy-connect/xYang · npm: @exergy-connect/xyang · Issues: github.com/exergy-connect/xYang/issues
MIT licensed.
Install
Python
pip install xyang
# development: pip install -e .
Optional: PyYAML for .yaml / .yml instance files on xyang validate.
TypeScript
npm install @exergy-connect/xyang
# from checkout:
cd ts && npm install && npm run build
Quick start
CLI
# Python
xyang parse examples/meta-model.yang
xyang validate examples/meta-model.yang data.json
xyang convert examples/meta-model.yang -o meta-model.yang.json
# TypeScript (after build, or npx from package)
xyang-ts parse examples/meta-model.yang
xyang-ts validate examples/meta-model.yang data.json
xyang-ts convert examples/meta-model.yang
Shared flags: --include-path DIR (repeatable) for imports; on validate, --anydata-validation off|complete|candidate and --anydata-module PATH for validating RFC 7951 qualified JSON under anydata (see below).
Python API
from xyang import parse_yang_file, YangValidator
module = parse_yang_file("examples/meta-model.yang")
validator = YangValidator(module)
data = {"data-model": {"name": "example", "entities": []}}
is_valid, errors, warnings = validator.validate(data)
TypeScript API
import { parseYangFile, YangValidator } from "@exergy-connect/xyang";
const module = parseYangFile("examples/meta-model.yang");
const validator = new YangValidator(module);
const result = validator.validate({ "data-model": { name: "example", entities: [] } });
Example: IETF YANG Push notification
Under examples/ietf-yang-push/ there is a captured device notification: 27-push-update.json uses the RFC 8791 envelope (ietf-yp-notification:envelope) with a ietf-yang-push:push-change-update payload in contents anydata. The modules/ directory is the publisher YANG library.
Validate the envelope and the qualified subtree under contents:
Python
xyang validate \
examples/ietf-yang-push/modules/ietf-yp-notification@2025-06-04.yang \
examples/ietf-yang-push/27-push-update.json \
--include-path examples/ietf-yang-push/modules \
--anydata-validation complete \
--anydata-module examples/ietf-yang-push/modules/ietf-yang-push@2019-09-09.yang \
--anydata-module examples/ietf-yang-push/modules/ietf-distributed-notif@2024-04-21.yang \
--anydata-module examples/ietf-yang-push/modules/ietf-yp-observation@2025-02-24.yang \
--anydata-module examples/ietf-yang-push/modules/ietf-alarms@2019-09-11.yang \
--anydata-module examples/ietf-yang-push/modules/ietf-alarms-x733@2019-09-11.yang
TypeScript (same flags; run from repo root after cd ts && npm run build)
node ts/dist/cli.js validate \
examples/ietf-yang-push/modules/ietf-yp-notification@2025-06-04.yang \
examples/ietf-yang-push/27-push-update.json \
--include-path examples/ietf-yang-push/modules \
--anydata-validation complete \
--anydata-module examples/ietf-yang-push/modules/ietf-yang-push@2019-09-09.yang \
--anydata-module examples/ietf-yang-push/modules/ietf-distributed-notif@2024-04-21.yang \
--anydata-module examples/ietf-yang-push/modules/ietf-yp-observation@2025-02-24.yang \
--anydata-module examples/ietf-yang-push/modules/ietf-alarms@2019-09-11.yang \
--anydata-module examples/ietf-yang-push/modules/ietf-alarms-x733@2019-09-11.yang
- Host module —
ietf-yp-notificationdefinesenvelope(event-time,hostname,sequence-number,contentsanydata). --anydata-validation complete— validates RFC 7951module:nodemembers undercontents(push update, observation timestamps, nested alarm notification in ayang-patchedit, etc.).--anydata-module— loads only the modules needed for that subtree; imports resolve via--include-path. Omit it to scan every*.yangunder the include path (slower).
Use candidate instead of complete for structural checks only (no must / when / types on the anydata subtree). More detail: examples/ietf-yang-push/README.md, examples/anydata_validation_usage.py.
What xYang does (and does not)
Does
- Parse YANG 1.1-shaped modules: containers, lists, leaves, choices, groupings, augments, features, imports, and common constraints.
- Validate a single JSON instance tree against the module data model (types, cardinality,
must/when,if-feature, leafrefs, identityrefs, etc.). - Optional anydata subtree validation for opaque payloads (YANG Push notifications, RPC output shapes, etc.) per draft-ietf-netmod-yang-anydata-validation.
- Export JSON Schema with
x-yangannotations for tooling and round-trip where supported.
Does not (today)
- NETCONF/RESTCONF servers, XML instance encoding, or incremental edit validation.
- Full RFC 7950 surface (
rpc/notification/deviationinstance validation is limited or skipped—see FEATURES.md). - A generic XPath 1.0 engine; expressions are evaluated in schema context for
must/when(subset documented in FEATURES.md).
Repository layout
xYang/
├── src/xyang/ # Python library + xyang CLI
├── ts/ # TypeScript package (@exergy-connect/xyang) + xyang-ts CLI
├── examples/ # meta-model.yang, ietf-yang-push/, samples
├── tests/ # Python tests
├── FEATURES.md # Authoritative feature list
└── pyproject.toml # PEP 517/621 project metadata and tooling config
Development
Python
pip install -e ".[dev]"
pytest
TypeScript
cd ts && npm install && npm test
typescript is pinned to 6.x (not 7) because tsup 8.5.1 bundles rollup-plugin-dts for dts: true builds, and that toolchain fails under TypeScript 7 with useCaseSensitiveFileNames errors during .d.ts generation. Revisit when tsup#1405 is resolved or tsup ships a compatible rollup-plugin-dts.
GitHub Actions
Workflows in this repository
| Workflow | File | Purpose |
|---|---|---|
| Tests (TypeScript) | .github/workflows/tests-ts.yml |
npm run lint, npm run build:check, and npm test in ts/ on Node 24 |
| Build TypeScript CI artifacts | .github/workflows/build-ts-dist.yml |
Runs npm run build:ci and keeps committed build artifacts in sync |
Both workflows run on pushes to main and on pull requests that touch ts/** (and related paths).
Committed CI artifacts
The Build TypeScript CI artifacts workflow commits two bundled outputs produced by ts/scripts/build-ci-artifacts.mjs:
| File | Role |
|---|---|
artifacts/xyang-ts.mjs |
Single-file Node CLI (parse, validate, convert) |
docs/xyang.umd.min.js |
Browser IIFE library bundle |
Regenerate locally:
cd ts && npm install && npm run build:ci
git add -f artifacts/xyang-ts.mjs docs/xyang.umd.min.js
On same-repo PRs and pushes to main, the workflow auto-commits when artifacts drift. On fork PRs, the check fails instead (no write access to the contributor branch).
The full npm package under ts/dist/ is not committed; use npm run build:check for publish-style validation.
xyang-ts composite action (other repositories)
Reuse .github/actions/xyang-ts to check out xYang and run the CLI from committed artifacts/xyang-ts.mjs — no npm install or build step in the consumer workflow.
Minimal validate job:
jobs:
validate-yang:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: exergy-connect/xYang/.github/actions/xyang-ts@main
with:
ref: main
command: validate
yang-file: model/example.yang
data-file: data/instance.json
include-path: model/
Inputs
| Input | Default | Description |
|---|---|---|
repository |
exergy-connect/xYang |
xYang GitHub repository |
ref |
main |
Branch, tag, or SHA (must include committed artifacts/xyang-ts.mjs) |
path |
.xyang |
Checkout directory under the workflow workspace |
command |
(empty) | parse, validate, or convert. Omit to only expose xyang-ts on PATH |
yang-file |
(empty) | YANG module path (required when command is set) |
data-file |
(empty) | JSON instance path for validate |
include-path |
(empty) | Module search directories (--include-path, one per line) |
working-directory |
(empty) | Directory for the xyang-ts invocation |
Outputs: cli (path to artifacts/xyang-ts.mjs), xyang-root (xYang repo root).
Setup only (run multiple commands in later steps):
- uses: exergy-connect/xYang/.github/actions/xyang-ts@main
id: xyang
with:
ref: v0.1.4
- run: xyang-ts parse model/example.yang
- run: xyang-ts convert model/example.yang
Anydata validation (use setup-only mode; flags are CLI-only):
- uses: exergy-connect/xYang/.github/actions/xyang-ts@main
with:
ref: main
- run: |
xyang-ts validate modules/host.yang data/envelope.json \
--include-path modules/ \
--anydata-validation complete \
--anydata-module modules/payload.yang
Pin ref to a release tag or SHA once this workflow is on main.
License
MIT License
Metadata
Release files for xyang 0.1.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| xyang-0.1.7.tar.gz | 170.0 kB | With provenance | Details for xyang-0.1.7.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| xyang-0.1.7-py3-none-any.whl | Python 3 | none | any | Details for xyang-0.1.7-py3-none-any.whl |
Total release size: 312.7 kB
Release files / xyang-0.1.7.tar.gz
| Download URL | xyang-0.1.7.tar.gz |
|---|---|
| Size | 170.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ed53173a2d672fb0fb73a77fc135864a6839cd176e0b4df627d0f29449d79c35
|
|
BLAKE2b-256 checksum How to use checksums |
e3f3ecf23ca6039ba102fb1707319c4f0dcb0f864063fe889331f7af6a659ea5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.
Transparency logRelease files / xyang-0.1.7-py3-none-any.whl
| Download URL | xyang-0.1.7-py3-none-any.whl |
|---|---|
| Size | 142.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
70a4acda9f46f3f6706f5a1cf3a9d53c5bff00941fe58685da50c67556e6dce4
|
|
BLAKE2b-256 checksum How to use checksums |
f78e51dd3baa87b431ef91b188d26a5ab93a62b585b9eb7b09a74da7f8ba4d72
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.
Transparency logSecurity for xyang 0.1.7
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for xyang-0.1.7.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.