oopt-gnpy-libyang


Nameoopt-gnpy-libyang JSON
Version 0.0.14 PyPI version JSON
download
home_pagehttps://github.com/Telecominfraproject/oopt-gnpy-libyang
SummaryOpinionated Python bindings for the libyang library
upload_time2024-01-24 19:13:57
maintainer
docs_urlNone
authorTelecom Infra Project
requires_python>=3.8
licenseBSD-3-Clause
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Opinionated Python bindings for the `libyang` library

[![Install via pip](https://img.shields.io/pypi/v/oopt-gnpy-libyang)](https://pypi.org/project/oopt-gnpy-libyang/)
[![Python versions](https://img.shields.io/pypi/pyversions/oopt-gnpy-libyang)](https://pypi.org/project/oopt-gnpy-libyang/)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/Telecominfraproject/oopt-gnpy-libyang/ci.yaml)](https://github.com/Telecominfraproject/oopt-gnpy-libyang/actions/workflows/ci.yaml)

Python bindings and packaging of [`libyang`](https://github.com/CESNET/libyang).
We're focusing on parsing, validating and accessing YANG-modeled JSON data trees.
Essentially, just enough to get [`gnpy`](https://github.com/Telecominfraproject/oopt-gnpy) going.
Want more?
Patches welcome.

Compared to the [CFFI libyang bindings](https://github.com/CESNET/libyang-python), this wrapper takes care of low-level memory management.
This means no more `node.free()` and `ctx.destroy()`.
We also produce prebuilt binary [wheels](https://realpython.com/python-wheels/) to make installation very simple.

## Usage

### Loading YANG data

```python
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:
```python
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:

```python
data["interface[name='lo']/ietf-ip:ipv6/address[ip='::1']/prefix-length"].as_term().value == 128
```
Or individually, one item per index:
```python
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:
```python
data["interface[name='lo']"]["ietf-ip:ipv6"]["address"]["prefix-length"].as_term().value == 128
```
The data are provided as native Python types:
```python
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:
```python
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):
```python
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:
```python
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()`:
```python
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:
```console-session
$ 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`](https://github.com/CESNET/libyang) and its dependencies
- [`libyang-cpp`](https://github.com/CESNET/libyang-cpp/) and its dependencies
- [CMake](https://cmake.org/) 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](./.github/workflows/ci.yaml).

## License

Copyright © 2021-2023 Telecom Infra Project and GNPy contributors.
Licensed under the [3-clause BSD license](LICENSE).

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Telecominfraproject/oopt-gnpy-libyang",
    "name": "oopt-gnpy-libyang",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "",
    "author": "Telecom Infra Project",
    "author_email": "jan.kundrat@telecominfraproject.com",
    "download_url": "https://files.pythonhosted.org/packages/cd/51/75f55c8c71a303023c495337f5c8f3d535f3ffd2cbc9f7a215bbb658f991/oopt-gnpy-libyang-0.0.14.tar.gz",
    "platform": null,
    "description": "# Opinionated Python bindings for the `libyang` library\n\n[![Install via pip](https://img.shields.io/pypi/v/oopt-gnpy-libyang)](https://pypi.org/project/oopt-gnpy-libyang/)\n[![Python versions](https://img.shields.io/pypi/pyversions/oopt-gnpy-libyang)](https://pypi.org/project/oopt-gnpy-libyang/)\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/Telecominfraproject/oopt-gnpy-libyang/ci.yaml)](https://github.com/Telecominfraproject/oopt-gnpy-libyang/actions/workflows/ci.yaml)\n\nPython bindings and packaging of [`libyang`](https://github.com/CESNET/libyang).\nWe're focusing on parsing, validating and accessing YANG-modeled JSON data trees.\nEssentially, just enough to get [`gnpy`](https://github.com/Telecominfraproject/oopt-gnpy) going.\nWant more?\nPatches welcome.\n\nCompared to the [CFFI libyang bindings](https://github.com/CESNET/libyang-python), this wrapper takes care of low-level memory management.\nThis means no more `node.free()` and `ctx.destroy()`.\nWe also produce prebuilt binary [wheels](https://realpython.com/python-wheels/) to make installation very simple.\n\n## Usage\n\n### Loading YANG data\n\n```python\nimport oopt_gnpy_libyang as ly\n\nc = ly.Context('tests/yang', ly.ContextOptions.AllImplemented | ly.ContextOptions.NoYangLibrary)\nfor m in ('iana-if-type', 'ietf-interfaces', 'ietf-ip'):\n    c.load_module(m)\nblob = '''{\n  \"ietf-interfaces:interfaces\": {\n    \"interface\": [\n      {\n        \"name\": \"lo\",\n        \"type\": \"iana-if-type:softwareLoopback\",\n        \"ietf-ip:ipv4\": {\n          \"address\": [\n            {\n              \"ip\": \"127.0.0.1\",\n              \"prefix-length\": 8\n            }\n          ]\n        },\n        \"ietf-ip:ipv6\": {\n          \"address\": [\n            {\n              \"ip\": \"::1\",\n              \"prefix-length\": 128\n            }\n          ]\n        }\n      },\n      {\n        \"name\": \"eth0\",\n        \"type\": \"iana-if-type:ethernetCsmacd\"\n      }\n    ]\n  }\n}'''\n\ndata = c.parse_data(blob,\n    ly.DataFormat.JSON, ly.ParseOptions.Strict | ly.ParseOptions.Ordered,\n    ly.ValidationOptions.Present | ly.ValidationOptions.NoState)\n```\n### Working with data\n\nLibyang works with forests (sets of trees), this is how to process all the data:\n```python\nfor x in data.siblings():\n    print(f'a sibling: {x.path}')\n    for xx in x.children_dfs():\n        print(f' {\"term \" if xx.is_term else \"child\"}: {xx.path}')\n        if xx.is_term:\n            print(f'  {xx.as_term()} {\" (default)\" if xx.as_term().is_default_value else \"\"}')\n```\nData can be accessed via their known paths, of course. Either as a full, multi-level XPath:\n\n```python\ndata[\"interface[name='lo']/ietf-ip:ipv6/address[ip='::1']/prefix-length\"].as_term().value == 128\n```\nOr individually, one item per index:\n```python\ndata[\"interface[name='lo']\"][\"ietf-ip:ipv6\"][\"address[ip='::1']\"][\"prefix-length\"].as_term().value\n```\nEverything is an XPath, so it's possible to take a shortcut and skip specifying keys for single-element lists:\n```python\ndata[\"interface[name='lo']\"][\"ietf-ip:ipv6\"][\"address\"][\"prefix-length\"].as_term().value == 128\n```\nThe data are provided as native Python types:\n```python\ntype(data[\"interface[name='lo']\"][\"ietf-ip:ipv6\"][\"address\"][\"prefix-length\"]\n    .as_term().value) == int\n```\nAbsolute paths and generic XPath expressions can be used to retrieve arbitrary parts of the data forest, and to iterate over them:\n```python\nfor iface in data.find(\"/ietf-interfaces:interfaces/interface\"):\n    print iface[\"name\"].as_term().value\n```\nRelative XPath conditions can be also used at the root level (which is represented as NULL in the C level):\n```python\nfor iface in search_at_root(data)(\"ietf-interfaces:interfaces/interface\"):\n    print iface[\"name\"].as_term().value\n```\nNew values can be created; use `None` for non-terminals, or `str` when a value is needed:\n```python\nnode = ctx.create(\"/ietf-interfaces:interfaces/interface[name='666']\")\nanother = ctx.create(\"/ietf-interfaces:interfaces/interface[name='666']/ietf-ip:ipv6/enabled\", \"true\")\ndata[\"interface[name='lo']\"][\"ietf-ip:ipv6\"][\"address\"][\"prefix-length\"] = \"64\"\n```\n\n### Validation errors\nIn libyang, if an operation fails, error details are available via `context.errors()`:\n```python\nimport json\nwrong = json.loads(blob)\nwrong[\"ietf-interfaces:interfaces\"][\"interface\"][0]\\\n    [\"ietf-ip:ipv6\"][\"address\"][0][\"prefix-length\"] = 666\ntry:\n    data = c.parse_data(json.dumps(wrong),\n        ly.DataFormat.JSON, ly.ParseOptions.Strict | ly.ParseOptions.Ordered,\n        ly.ValidationOptions.Present | ly.ValidationOptions.NoState)\n    assert False\nexcept ly.Error:\n    for error in c.errors():\n        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.\"\n        assert error.message == 'Value \"666\" is out of type uint8 min/max bounds.'\n```\n\n## Installing\n\nWe're producing wheels for many popular platforms.\nThe installation is as simple as:\n```console-session\n$ pip install oopt-gnpy-libyang\n```\n\n### Building from source\n\nSince this library is a Python wrapper around a C++ wrapper around a C library, source-based builds are more complex.\nThey require:\n\n- a C++20 compiler (e.g., GCC 10+, clang 10+, MSVC 17.2+)\n- [`libyang`](https://github.com/CESNET/libyang) and its dependencies\n- [`libyang-cpp`](https://github.com/CESNET/libyang-cpp/) and its dependencies\n- [CMake](https://cmake.org/) 3.21+\n\nUnlike 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.\nAlso, in a from-source build these won't be bundled into the resulting package.\nFor an inspiration, consult our [GitHub packaging recipes](./.github/workflows/ci.yaml).\n\n## License\n\nCopyright \u00a9 2021-2023 Telecom Infra Project and GNPy contributors.\nLicensed under the [3-clause BSD license](LICENSE).\n",
    "bugtrack_url": null,
    "license": "BSD-3-Clause",
    "summary": "Opinionated Python bindings for the libyang library",
    "version": "0.0.14",
    "project_urls": {
        "Download": "https://pypi.org/project/oopt-gnpy-libyang/",
        "Homepage": "https://github.com/Telecominfraproject/oopt-gnpy-libyang"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c77b7eacd4092b56527fb4d897fa0958babaa08008e29c79baf20c0d426fea1f",
                "md5": "de458de4e16da1738b1c53d64218c05d",
                "sha256": "b637ce8bcf31f2f6c443bc5f4e739dc7f65353ee8ead09bfed959fdcc6b350ce"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp310-cp310-macosx_12_0_x86_64.whl",
            "has_sig": false,
            "md5_digest": "de458de4e16da1738b1c53d64218c05d",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.8",
            "size": 2095700,
            "upload_time": "2024-01-24T19:13:38",
            "upload_time_iso_8601": "2024-01-24T19:13:38.122961Z",
            "url": "https://files.pythonhosted.org/packages/c7/7b/7eacd4092b56527fb4d897fa0958babaa08008e29c79baf20c0d426fea1f/oopt_gnpy_libyang-0.0.14-cp310-cp310-macosx_12_0_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d2add3dbb4728a08be0cdfca415a6b6d3c190a129d55c9e94ca301bb4da129db",
                "md5": "93e2a2cf6bd27f35c49098f9f36283c9",
                "sha256": "dd134323142f980a024f9f592ca56fc5a0a52e036012e534d6a8ea28f81169ea"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp310-cp310-manylinux_2_31_x86_64.whl",
            "has_sig": false,
            "md5_digest": "93e2a2cf6bd27f35c49098f9f36283c9",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.8",
            "size": 1126619,
            "upload_time": "2024-01-24T19:13:40",
            "upload_time_iso_8601": "2024-01-24T19:13:40.374251Z",
            "url": "https://files.pythonhosted.org/packages/d2/ad/d3dbb4728a08be0cdfca415a6b6d3c190a129d55c9e94ca301bb4da129db/oopt_gnpy_libyang-0.0.14-cp310-cp310-manylinux_2_31_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2fcdb9e66521a6449c4e3f13acb088b583f64404fdc4fcf1c664274a52604a91",
                "md5": "7abf85c41ec77f291f95fdd6f581b336",
                "sha256": "65495556308598025a3f207153d210e53f8a9ca176604f82d3448d2a40327b34"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp310-cp310-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "7abf85c41ec77f291f95fdd6f581b336",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.8",
            "size": 1214718,
            "upload_time": "2024-01-24T19:13:42",
            "upload_time_iso_8601": "2024-01-24T19:13:42.207474Z",
            "url": "https://files.pythonhosted.org/packages/2f/cd/b9e66521a6449c4e3f13acb088b583f64404fdc4fcf1c664274a52604a91/oopt_gnpy_libyang-0.0.14-cp310-cp310-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "48f5a7614bc7f5f415455ebd17de1975fc3d8280b622654a3ad34b0d9a8a25fd",
                "md5": "6ee4ef66f2885d19dd0dccf0c68500d3",
                "sha256": "0d6a0a13279a5380d9b55ad24cef770cf6d08079aff80835c9093495031d8dcf"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp311-cp311-macosx_12_0_x86_64.whl",
            "has_sig": false,
            "md5_digest": "6ee4ef66f2885d19dd0dccf0c68500d3",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.8",
            "size": 2097334,
            "upload_time": "2024-01-24T19:13:43",
            "upload_time_iso_8601": "2024-01-24T19:13:43.666998Z",
            "url": "https://files.pythonhosted.org/packages/48/f5/a7614bc7f5f415455ebd17de1975fc3d8280b622654a3ad34b0d9a8a25fd/oopt_gnpy_libyang-0.0.14-cp311-cp311-macosx_12_0_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e35f8d79d35c001e6fa9a79c55a5071def4480d5be5c5b20a9849e7446bae864",
                "md5": "624989bcd365ff43a027d219bd3fa109",
                "sha256": "5657f0db00ac66decb1303f5ef1ccf4f0c3d324f9242deb99f07d28fa3b196a2"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp311-cp311-manylinux_2_35_x86_64.whl",
            "has_sig": false,
            "md5_digest": "624989bcd365ff43a027d219bd3fa109",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.8",
            "size": 1136023,
            "upload_time": "2024-01-24T19:13:45",
            "upload_time_iso_8601": "2024-01-24T19:13:45.372614Z",
            "url": "https://files.pythonhosted.org/packages/e3/5f/8d79d35c001e6fa9a79c55a5071def4480d5be5c5b20a9849e7446bae864/oopt_gnpy_libyang-0.0.14-cp311-cp311-manylinux_2_35_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b2835e39e7ca761bc4bc7e92a8100fed523a3af889afa623eb9ac593c774b0c0",
                "md5": "3dfb6c26672de9a0235ac9f0e49bccdf",
                "sha256": "a81bee9cb0257a69bd29e0dc43f47eb30241b82de352a83f85047344d3dce13c"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "3dfb6c26672de9a0235ac9f0e49bccdf",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.8",
            "size": 1215799,
            "upload_time": "2024-01-24T19:13:47",
            "upload_time_iso_8601": "2024-01-24T19:13:47.258487Z",
            "url": "https://files.pythonhosted.org/packages/b2/83/5e39e7ca761bc4bc7e92a8100fed523a3af889afa623eb9ac593c774b0c0/oopt_gnpy_libyang-0.0.14-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "221e16649253e328e96da38b26102eae919c4898316e307e82bfc2fd7f569bb4",
                "md5": "37afa5da74f4cadd0821b8a653a5e389",
                "sha256": "de71ef38eb849532d486b872b9f7d163d4514b9d027634a9582890ee5dfc0eb5"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp312-cp312-macosx_13_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "37afa5da74f4cadd0821b8a653a5e389",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.8",
            "size": 1889350,
            "upload_time": "2024-01-24T19:13:48",
            "upload_time_iso_8601": "2024-01-24T19:13:48.779932Z",
            "url": "https://files.pythonhosted.org/packages/22/1e/16649253e328e96da38b26102eae919c4898316e307e82bfc2fd7f569bb4/oopt_gnpy_libyang-0.0.14-cp312-cp312-macosx_13_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ef95a320774e208d4d03034f76843e51b332d82e88f9df86a6749cf07aa947fc",
                "md5": "3a29281be4c48380cc00b516d1d404aa",
                "sha256": "1d305cff076816b172f892002d9f59288500ceafbba7754d1ec8ee87c3cef58e"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp312-cp312-macosx_13_0_x86_64.whl",
            "has_sig": false,
            "md5_digest": "3a29281be4c48380cc00b516d1d404aa",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.8",
            "size": 2028992,
            "upload_time": "2024-01-24T19:13:50",
            "upload_time_iso_8601": "2024-01-24T19:13:50.640488Z",
            "url": "https://files.pythonhosted.org/packages/ef/95/a320774e208d4d03034f76843e51b332d82e88f9df86a6749cf07aa947fc/oopt_gnpy_libyang-0.0.14-cp312-cp312-macosx_13_0_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fdaf8a4df00c5aabf6384b757268e2f140d8b5ed1ce058e079d63724a796581a",
                "md5": "fd8732932e0bdce6326a4a0018815e78",
                "sha256": "21ea44541586f2acd5eaee869c42ae2544d2d3073bbc8da1bc3a2d260022c8b6"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp312-cp312-manylinux_2_35_x86_64.whl",
            "has_sig": false,
            "md5_digest": "fd8732932e0bdce6326a4a0018815e78",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.8",
            "size": 1134523,
            "upload_time": "2024-01-24T19:13:51",
            "upload_time_iso_8601": "2024-01-24T19:13:51.973609Z",
            "url": "https://files.pythonhosted.org/packages/fd/af/8a4df00c5aabf6384b757268e2f140d8b5ed1ce058e079d63724a796581a/oopt_gnpy_libyang-0.0.14-cp312-cp312-manylinux_2_35_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4759ce680850b92c466a081a8b32996603ef71ed26765011a665ba774d509f73",
                "md5": "ff6210d50065f88a05ec5a98d951cf9a",
                "sha256": "80ba5a3f253571325d459e6ae79c5d50642d322b5f3d8220c39c867d8d42db2c"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp312-cp312-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "ff6210d50065f88a05ec5a98d951cf9a",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.8",
            "size": 1214916,
            "upload_time": "2024-01-24T19:13:53",
            "upload_time_iso_8601": "2024-01-24T19:13:53.354322Z",
            "url": "https://files.pythonhosted.org/packages/47/59/ce680850b92c466a081a8b32996603ef71ed26765011a665ba774d509f73/oopt_gnpy_libyang-0.0.14-cp312-cp312-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3dc808e4ef1f0034219c7e87c432d9d44047d35fb4031288195dc7c0e19cbb26",
                "md5": "f4d9635e666dfa924bc5259b6125225f",
                "sha256": "c42fcbcf24af0ee0c06c28040e48763f36196782e1624b5ee0873d7020ad9c44"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp38-cp38-manylinux_2_31_x86_64.whl",
            "has_sig": false,
            "md5_digest": "f4d9635e666dfa924bc5259b6125225f",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": ">=3.8",
            "size": 1126524,
            "upload_time": "2024-01-24T19:13:54",
            "upload_time_iso_8601": "2024-01-24T19:13:54.651901Z",
            "url": "https://files.pythonhosted.org/packages/3d/c8/08e4ef1f0034219c7e87c432d9d44047d35fb4031288195dc7c0e19cbb26/oopt_gnpy_libyang-0.0.14-cp38-cp38-manylinux_2_31_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7054c11973d9692ff17e77cc43bec0612ab52399a6e9c152ca789b2043642fa6",
                "md5": "9e404089eb924150c59b2ff862f8b395",
                "sha256": "0dcd39ec5eff24498fd9e090d4ca2b15b70afd880ea86ae0117690cdcee07230"
            },
            "downloads": -1,
            "filename": "oopt_gnpy_libyang-0.0.14-cp39-cp39-manylinux_2_31_x86_64.whl",
            "has_sig": false,
            "md5_digest": "9e404089eb924150c59b2ff862f8b395",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.8",
            "size": 1126987,
            "upload_time": "2024-01-24T19:13:56",
            "upload_time_iso_8601": "2024-01-24T19:13:56.643215Z",
            "url": "https://files.pythonhosted.org/packages/70/54/c11973d9692ff17e77cc43bec0612ab52399a6e9c152ca789b2043642fa6/oopt_gnpy_libyang-0.0.14-cp39-cp39-manylinux_2_31_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cd5175f55c8c71a303023c495337f5c8f3d535f3ffd2cbc9f7a215bbb658f991",
                "md5": "4183e079a8f34a9fd5f25daad36b9a04",
                "sha256": "c7f9c5c20682f5831c1e1d5c0264f45b297ed2167f50a6474f7ad7ad2378604b"
            },
            "downloads": -1,
            "filename": "oopt-gnpy-libyang-0.0.14.tar.gz",
            "has_sig": false,
            "md5_digest": "4183e079a8f34a9fd5f25daad36b9a04",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 45249,
            "upload_time": "2024-01-24T19:13:57",
            "upload_time_iso_8601": "2024-01-24T19:13:57.936816Z",
            "url": "https://files.pythonhosted.org/packages/cd/51/75f55c8c71a303023c495337f5c8f3d535f3ffd2cbc9f7a215bbb658f991/oopt-gnpy-libyang-0.0.14.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-24 19:13:57",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Telecominfraproject",
    "github_project": "oopt-gnpy-libyang",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "oopt-gnpy-libyang"
}
        
Elapsed time: 0.16863s