Opinionated Python bindings for the libyang library
Project description
Opinionated Python bindings for the libyang
library
Python bindings and packaging of libyang
.
We're focusing on parsing, validating and accessing YANG-modeled JSON data trees.
Essentially, just enough to get gnpy
going.
Want more?
Patches welcome.
Compared to the CFFI libyang bindings, this wrapper takes care of low-level memory management.
This means no more node.free()
and ctx.destroy()
.
We also produce prebuilt binary wheels to make installation very simple.
Usage
Loading YANG data
import oopt_gnpy_libyang as ly
c = ly.Context('tests/yang', ly.ContextOptions.AllImplemented | ly.ContextOptions.NoYangLibrary)
for m in ('iana-if-type', 'ietf-interfaces', 'ietf-ip'):
c.load_module(m)
blob = '''{
"ietf-interfaces:interfaces": {
"interface": [
{
"name": "lo",
"type": "iana-if-type:softwareLoopback",
"ietf-ip:ipv4": {
"address": [
{
"ip": "127.0.0.1",
"prefix-length": 8
}
]
},
"ietf-ip:ipv6": {
"address": [
{
"ip": "::1",
"prefix-length": 128
}
]
}
},
{
"name": "eth0",
"type": "iana-if-type:ethernetCsmacd"
}
]
}
}'''
data = c.parse_data(blob,
ly.DataFormat.JSON, ly.ParseOptions.Strict | ly.ParseOptions.Ordered,
ly.ValidationOptions.Present | ly.ValidationOptions.NoState)
Working with data
Libyang works with forests (sets of trees), this is how to process all the data:
for x in data.siblings():
print(f'a sibling: {x.path}')
for xx in x.children_dfs():
print(f' {"term " if xx.is_term else "child"}: {xx.path}')
if xx.is_term:
print(f' {xx.as_term()} {" (default)" if xx.as_term().is_default_value else ""}')
Data can be accessed via their known paths, of course. Either as a full, multi-level XPath:
data["interface[name='lo']/ietf-ip:ipv6/address[ip='::1']/prefix-length"].as_term().value == 128
Or individually, one item per index:
data["interface[name='lo']"]["ietf-ip:ipv6"]["address[ip='::1']"]["prefix-length"].as_term().value
Everything is an XPath, so it's possible to take a shortcut and skip specifying keys for single-element lists:
data["interface[name='lo']"]["ietf-ip:ipv6"]["address"]["prefix-length"].as_term().value == 128
The data are provided as native Python types:
type(data["interface[name='lo']"]["ietf-ip:ipv6"]["address"]["prefix-length"]
.as_term().value) == int
Absolute paths and generic XPath expressions can be used to retrieve arbitrary parts of the data forest, and to iterate over them:
for iface in data.find("/ietf-interfaces:interfaces/interface"):
print iface["name"].as_term().value
Relative XPath conditions can be also used at the root level (which is represented as NULL in the C level):
for iface in search_at_root(data)("ietf-interfaces:interfaces/interface"):
print iface["name"].as_term().value
New values can be created; use None
for non-terminals, or str
when a value is needed:
node = ctx.create("/ietf-interfaces:interfaces/interface[name='666']")
another = ctx.create("/ietf-interfaces:interfaces/interface[name='666']/ietf-ip:ipv6/enabled", "true")
data["interface[name='lo']"]["ietf-ip:ipv6"]["address"]["prefix-length"] = "64"
Validation errors
In libyang, if an operation fails, error details are available via context.errors()
:
import json
wrong = json.loads(blob)
wrong["ietf-interfaces:interfaces"]["interface"][0]\
["ietf-ip:ipv6"]["address"][0]["prefix-length"] = 666
try:
data = c.parse_data(json.dumps(wrong),
ly.DataFormat.JSON, ly.ParseOptions.Strict | ly.ParseOptions.Ordered,
ly.ValidationOptions.Present | ly.ValidationOptions.NoState)
assert False
except ly.Error:
for error in c.errors():
assert error.path == "Schema location \"/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address/prefix-length\", data location \"/ietf-ip:address[ip='::1']\", line number 1."
assert error.message == 'Value "666" is out of type uint8 min/max bounds.'
Installing
We're producing wheels for many popular platforms. The installation is as simple as:
$ pip install oopt-gnpy-libyang
Building from source
Since this library is a Python wrapper around a C++ wrapper around a C library, source-based builds are more complex. They require:
- a C++20 compiler (e.g., GCC 10+, clang 10+, MSVC 17.2+)
libyang
and its dependencieslibyang-cpp
and its dependencies- CMake 3.21+
Unlike the wheels already bundle all the required libraries, when building from source, libyang
, libyang-cpp
and all their dependencies will have to be installed first.
Also, in a from-source build these won't be bundled into the resulting package.
For an inspiration, consult our GitHub packaging recipes.
License
Copyright © 2021-2023 Telecom Infra Project and GNPy contributors. Licensed under the 3-clause BSD license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for oopt_gnpy_libyang-0.0.14-cp312-cp312-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 80ba5a3f253571325d459e6ae79c5d50642d322b5f3d8220c39c867d8d42db2c |
|
MD5 | ff6210d50065f88a05ec5a98d951cf9a |
|
BLAKE2b-256 | 4759ce680850b92c466a081a8b32996603ef71ed26765011a665ba774d509f73 |
Hashes for oopt_gnpy_libyang-0.0.14-cp312-cp312-manylinux_2_35_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 21ea44541586f2acd5eaee869c42ae2544d2d3073bbc8da1bc3a2d260022c8b6 |
|
MD5 | fd8732932e0bdce6326a4a0018815e78 |
|
BLAKE2b-256 | fdaf8a4df00c5aabf6384b757268e2f140d8b5ed1ce058e079d63724a796581a |
Hashes for oopt_gnpy_libyang-0.0.14-cp312-cp312-macosx_13_0_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1d305cff076816b172f892002d9f59288500ceafbba7754d1ec8ee87c3cef58e |
|
MD5 | 3a29281be4c48380cc00b516d1d404aa |
|
BLAKE2b-256 | ef95a320774e208d4d03034f76843e51b332d82e88f9df86a6749cf07aa947fc |
Hashes for oopt_gnpy_libyang-0.0.14-cp312-cp312-macosx_13_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | de71ef38eb849532d486b872b9f7d163d4514b9d027634a9582890ee5dfc0eb5 |
|
MD5 | 37afa5da74f4cadd0821b8a653a5e389 |
|
BLAKE2b-256 | 221e16649253e328e96da38b26102eae919c4898316e307e82bfc2fd7f569bb4 |
Hashes for oopt_gnpy_libyang-0.0.14-cp311-cp311-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a81bee9cb0257a69bd29e0dc43f47eb30241b82de352a83f85047344d3dce13c |
|
MD5 | 3dfb6c26672de9a0235ac9f0e49bccdf |
|
BLAKE2b-256 | b2835e39e7ca761bc4bc7e92a8100fed523a3af889afa623eb9ac593c774b0c0 |
Hashes for oopt_gnpy_libyang-0.0.14-cp311-cp311-manylinux_2_35_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5657f0db00ac66decb1303f5ef1ccf4f0c3d324f9242deb99f07d28fa3b196a2 |
|
MD5 | 624989bcd365ff43a027d219bd3fa109 |
|
BLAKE2b-256 | e35f8d79d35c001e6fa9a79c55a5071def4480d5be5c5b20a9849e7446bae864 |
Hashes for oopt_gnpy_libyang-0.0.14-cp311-cp311-macosx_12_0_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0d6a0a13279a5380d9b55ad24cef770cf6d08079aff80835c9093495031d8dcf |
|
MD5 | 6ee4ef66f2885d19dd0dccf0c68500d3 |
|
BLAKE2b-256 | 48f5a7614bc7f5f415455ebd17de1975fc3d8280b622654a3ad34b0d9a8a25fd |
Hashes for oopt_gnpy_libyang-0.0.14-cp310-cp310-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 65495556308598025a3f207153d210e53f8a9ca176604f82d3448d2a40327b34 |
|
MD5 | 7abf85c41ec77f291f95fdd6f581b336 |
|
BLAKE2b-256 | 2fcdb9e66521a6449c4e3f13acb088b583f64404fdc4fcf1c664274a52604a91 |
Hashes for oopt_gnpy_libyang-0.0.14-cp310-cp310-manylinux_2_31_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | dd134323142f980a024f9f592ca56fc5a0a52e036012e534d6a8ea28f81169ea |
|
MD5 | 93e2a2cf6bd27f35c49098f9f36283c9 |
|
BLAKE2b-256 | d2add3dbb4728a08be0cdfca415a6b6d3c190a129d55c9e94ca301bb4da129db |
Hashes for oopt_gnpy_libyang-0.0.14-cp310-cp310-macosx_12_0_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b637ce8bcf31f2f6c443bc5f4e739dc7f65353ee8ead09bfed959fdcc6b350ce |
|
MD5 | de458de4e16da1738b1c53d64218c05d |
|
BLAKE2b-256 | c77b7eacd4092b56527fb4d897fa0958babaa08008e29c79baf20c0d426fea1f |
Hashes for oopt_gnpy_libyang-0.0.14-cp39-cp39-manylinux_2_31_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0dcd39ec5eff24498fd9e090d4ca2b15b70afd880ea86ae0117690cdcee07230 |
|
MD5 | 9e404089eb924150c59b2ff862f8b395 |
|
BLAKE2b-256 | 7054c11973d9692ff17e77cc43bec0612ab52399a6e9c152ca789b2043642fa6 |
Hashes for oopt_gnpy_libyang-0.0.14-cp38-cp38-manylinux_2_31_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c42fcbcf24af0ee0c06c28040e48763f36196782e1624b5ee0873d7020ad9c44 |
|
MD5 | f4d9635e666dfa924bc5259b6125225f |
|
BLAKE2b-256 | 3dc808e4ef1f0034219c7e87c432d9d44047d35fb4031288195dc7c0e19cbb26 |