# pyang, validating and converting YANG models for network configuration

> pyang is a Python YANG validator, transformer and code generator, built for the data modeling language the IETF uses for NETCONF, and it is the tool that network equipment vendors and operators both reach for. It reads YANG, checks it against the grammar, and turns it into DSDL schemas, UML, tree diagrams and skeletons, with a plugin system for anything else.

**mbj4668/pyang** — An extensible YANG validator and converter in python

- Repository: https://github.com/mbj4668/pyang
- Stars: 572 · Forks: 368
- Language: Python
- License: ISC
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/mbj4668-pyang

## A validator for the language network devices are configured in

pyang is described as a YANG validator, transformator and code generator written in Python, and it can be used to validate YANG modules for correctness, to transform YANG modules into other formats, and to write plugins to generate code from the modules.

The context matters more than the tool. YANG is a data modeling language for NETCONF, defined in RFC 7950, developed by the IETF NETMOD working group. NETCONF is the protocol that network devices use to be configured, and YANG is how the shape of that configuration is described, as a tree of typed leaves and groupings.

So pyang sits in the path between a person writing a model and the software that uses it. A model that is syntactically wrong will be rejected by any device that loads it, and a model that is semantically wrong, where a leaf references a type that does not exist, will pass a syntax check and fail later. pyang is the check that runs before either of those.

The audience is specific and slightly unusual: network equipment vendors writing their models, operators and automation teams consuming them, and the documentation pipelines in between. The project is under the `mbj4668` GitHub account, the licence is ISC, and the recorded releases are 2.7.1 and 2.7.0, both on 2025-08-29, and pyang-2.6.1 from 2024-05-23. The last push to the repository was on 2026-06-24.

What makes pyang more than a validator is the output side, and that is where most of the tool's value sits for a team that already has models and wants to do something with them.

## Every output is a plugin, and the plugin API is the extension point

The feature list makes the shape of the tool clear. Validation is one item on it. The others are conversions, and every one of them is described as an output plugin.

The code structure section spells out the mechanism. `pyang/plugin.py` defines the plugin API and the `PyangPlugin` class which all plugins inherit from, and the documentation notes that all output handlers are written as plugins. The `pyang/plugins/` directory is where plugins can be installed, and every plugin in that directory is automatically initialized when the library is initialized. The `pyang/translators/` directory holds the output plugins for YANG, YIN and DSDL translation, and the `pyang/scripts/` directory holds the Python command line scripts, which are installed as an entry point.

That last point is the one to internalise. The set of output formats is not a hardcoded list in the parser, it is a directory of plugins that get loaded on start-up. Writing a new output means writing a plugin, not patching the core.

Underneath the plugin layer the parsing is separated by format. `pyang/yang_parser.py` is the YANG tokenizer and parser, `pyang/yin_parser.py` is the YIN parser, and the documentation notes that it uses the expat library for XML parsing. `pyang/syntax.py` holds generic syntax checking for YANG and YIN statements and defines regular expressions for argument checking of core statements, and `pyang/grammar.py` holds the generic grammar, including `chk_module_statements()` which validates a parse tree according to that grammar. `pyang/statements.py` defines the generic Statement class and all validation code, and `pyang/types.py` contains the code for checking built-in types.

The session model is two classes. `pyang/context.py` defines the Context class, which represents a parsing session, and `pyang/repository.py` defines the Repository class, which is used to access modules. A Repository is how pyang finds the modules a model imports, which is the part of the design that matters most for real-world use, since a model in the wild imports half a dozen others and a validator that cannot resolve them is useless.

## Installing pyang, and the environment variables it needs

Installation is a pip install, and the source route is the one worth reading because the environment variables are the part people get wrong.

From PyPI it is one command.

```sh
# pip install pyang
```

From source, a clone and an editable install, with the documentation recommending a Python virtual environment.

```sh
  git clone https://github.com/mbj4668/pyang.git
  cd pyang
  pip install -e .
```

Installing to a different prefix takes a different form.

```sh
  python setup.py install --prefix=/usr/local
```

And then the documentation explains the part that causes confusion. If you install this way, it is recommended to set the environment variable `YANG_INSTALL` to the prefix directory, which ensures that pyang will find standard YANG modules. In addition, make sure that `PYTHONPATH` is set, for example to `/usr/local/lib/python3.10/site-packages` or whatever version of Python you are running.

So `YANG_INSTALL` is about finding the standard module library, and `PYTHONPATH` is about Python finding the installed package. They are separate problems and the documentation treats them separately.

There is a third mode for people who just want to try it: running locally without installing, by setting a group of environment variables pointing at the checkout.

```sh
export PATH=`pwd`/bin:$PATH
export MANPATH=`pwd`/man:$MANPATH
export PYTHONPATH=`pwd`:$PYTHONPATH
export YANG_MODPATH=`pwd`/modules:$YANG_MODPATH
export PYANG_XSLT_DIR=`pwd`/xslt
export PYANG_RNG_LIBDIR=`pwd`/schema
```

`YANG_MODPATH` is the one that matters for real work, since it is where pyang looks for the standard IETF and IANA modules, and `PYANG_XSLT_DIR` and `PYANG_RNG_LIBDIR` point at the XSLT stylesheets and the RELAX NG schemas that ship with the repository.

The runtime dependency list is one line, `lxml`, which is what the DSDL translation and the XSLT pipeline need. The build has its own extras in `dev-requirements.txt`.

## The output formats, and what each is for

The feature list is a catalogue of conversions, and each one answers a different question about a model.

YIN is the intermediate form. The documentation says pyang can convert YANG modules to YIN, and YIN to YANG, and `pyang/yin_parser.py` is the parser for it. YIN is a normalised XML rendering of the module, and the round trip is useful for diffing models, for storing a canonical form, and for feeding tools that expect XML.

DSDL is the validation output. YANG data models can be translated to DSDL schemas, which can be used for validating various XML instance documents, and the instance validation page is the documentation link for that.

UML is the modelling view. The documentation describes generating UML diagrams from YANG models, with a wiki page showing an example.

The tree output is the quick visualisation, a compact tree representation of YANG models for quick visualization, with its own wiki page and example.

Then there is the skeleton instance document, a skeleton XML instance document generated from the data model, which is how you find out what a valid configuration for a model looks like before you have one.

And the JSON translation, schema-aware translation of instance documents encoded in XML to JSON and vice-versa, with a wiki page for it. That one matters for anyone building a NETCONF or RESTCONF front end, because the wire format and the configuration format are often different.

Behind several of these sits the XSLT machinery. The `xslt` directory contains XSLT style sheets for generating RELAX NG, Schematron and DSRL schemas and validating instance documents, and it includes a free implementation of ISO Schematron by Rick Jelliffe, with the files `iso_schematron_skeleton_for_xslt1.xsl`, `iso_abstract_expand.xsl` and `iso_svrl_for_xslt1.xsl`. The `schema` directory contains RELAX NG schemas and pattern libraries.

So the tool is not just a checker. It is a front end to a validation and translation pipeline, and the plugin API is there so that a vendor with an unusual output can add it without touching the parser.

## The compatibility list is the real specification of what it handles

pyang publishes the list of IETF documents it is compatible with, and that list is more informative than the feature list, because it tells you which generation of YANG and which extensions are in scope.

The list covers RFC 6020, YANG as a data modeling language for NETCONF, RFC 6087 on guidelines for authors and reviewers of YANG data model documents, RFC 6110 on mapping YANG to document schema definition languages and validating NETCONF content, RFC 6643 on translating SMIv2 MIB modules to YANG, RFC 7950 for the YANG 1.1 data modeling languages, RFC 7952 on defining and using metadata with YANG, RFC 8040 on RESTCONF, RFC 8407 on guidelines for authors and reviewers of documents containing YANG data models, RFC 8791 on YANG data structure extensions, and RFC 9595 on the YANG schema item identifier.

Two things stand out in that list. RFC 7950 is the 1.1 version, so this is not a YANG 1.0-only tool. And RFC 8791 is the data structure extension, which is what makes nested lists and leafs of leafs expressible, and which is a common source of trouble in a model that has to interoperate with older tooling. The presence of RFC 9595 for the YANG SID says the tool tracks the current extensions rather than the 2016 core.

The restriction is worth stating too, because the list is of documents rather than of features. A module that uses a vendor extension from outside the IETF registry, which is most real modules, is outside what the compatibility list covers, and whether pyang accepts it depends on whether it can validate the extension's arguments against a known pattern. The `pyang/statements.py` file holds all validation code and the `pyang/syntax.py` file holds regular expressions for argument checking of core statements, so extensions are handled through plugins that register their own patterns.

The repository layout backs this up with a `modules/` directory, and the setup script globs `modules/iana/*.yang` and `modules/ietf/*.yang` to bundle the standard module library with the package. Those are the modules pyang will find without a path configuration, and they are shipped inside the distribution, which is why a plain pip install mostly works.

## Where pyang is the wrong tool

The tool is good at what it does, and it is worth being precise about the boundary.

First, pyang validates models, and it validates instances separately. The DSDL translation produces schemas that can validate instance documents, and the schema-aware XML to JSON translation operates on a document against a model, but the model validation and the instance validation are two different operations with two different invocations. If your problem is that a device is rejecting your running configuration, pyang is a piece of the answer rather than the answer.

Second, the output side is where the work lands, and pyang does not generate your device configuration code for you. It generates a skeleton, a tree, a UML diagram, a schema, or whatever your plugin produces, and turning a YANG model into working C or Go structs is a plugin you write or a generator someone else wrote. The feature list is explicit that code generation is a plugin framework, not a built-in set of language backends.

Third, the tool is Python and the schema pipeline is XSLT-based, which means an lxml dependency and a stylesheet engine in the path. That is a perfectly reasonable choice for a build-time or documentation-time tool and a poor one for something you want to embed in a running service on every request.

The alternative to weigh against is not another Python YANG library so much as a different placement in the pipeline. A vendor with a large model set and a code generator that must match their C runtime may write their own generator plugin on top of pyang rather than replacing pyang, since the parsing, grammar and type checking are the expensive part to reimplement. A team that only needs to check a handful of models in CI may find a much lighter option sufficient, because pyang's validation depth is more than a syntax check.

For the common case, though, the case for pyang is that it is the tool the ecosystem already assumes. Models in the wild, documentation pipelines, and other tools all assume a pyang-compatible world, and that compatibility is the feature you are actually buying.

## Conclusion

pyang suits anyone who writes or consumes YANG models, whether for a network device vendor, a NETCONF client, or a documentation pipeline, and it is the pragmatic choice because it is already the tool most of the ecosystem assumes. It does not suit a team that needs schema-aware validation of real device configuration against a live model, since pyang validates models and instances separately rather than acting as a running configuration checker. Verify first that the RFC versions and extensions your models rely on are covered by the version you take, that the plugins you need exist for your output format, and that the lxml dependency, which is listed in the requirements, installs cleanly in your environment.

## FAQ

### What is pyang used for?

pyang is a YANG validator, transformer and code generator written in Python. It validates YANG modules for correctness, transforms them into other formats such as YIN, DSDL schemas, UML diagrams, tree views and skeleton instances, and it can be extended with plugins to generate other outputs such as code.

### How do I install pyang?

From PyPI with pip install pyang, or from source by cloning the repository and running pip install -e ., which the documentation recommends inside a Python virtual environment. To run from a checkout without installing, set PATH, MANPATH, PYTHONPATH, YANG_MODPATH, PYANG_XSLT_DIR and PYANG_RNG_LIBDIR as the README shows, or source ./env.sh.

### What is the YANG_INSTALL environment variable for?

When pyang is installed to a non-default prefix with python setup.py install --prefix, setting YANG_INSTALL to that prefix directory makes pyang find the standard YANG modules. It is separate from PYTHONPATH, which is what makes Python find the installed package itself.

### How do I add a new output format to pyang?

By writing a plugin. The pyang/plugin.py file defines the PyangPlugin class that all plugins inherit from, all output handlers are written as plugins, and every plugin placed in the pyang/plugins directory is automatically initialized when the library is initialized.

### What licence is pyang released under?

ISC, with the LICENSE file at the top of the repository. The runtime dependency list is a single entry, lxml, which the DSDL translation and XSLT pipeline require.

## Sources

- [Issues](https://github.com/mbj4668/pyang/issues)
- [License: ISC](https://github.com/mbj4668/pyang/blob/master/LICENSE)
- [mbj4668/pyang on GitHub](https://github.com/mbj4668/pyang)
- [README](https://github.com/mbj4668/pyang/blob/master/README.md)
- [Releases](https://github.com/mbj4668/pyang/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mbj4668-pyang
