aiogNMI
About
This Python library provides an efficient and lightweight gNMI client implementation that leverages asynchronous approach.
Supported RPCs:
- Capabilities
- Get
- Set
- Subscribe (under development)
Tested on:
- Arista EOS
- Nokia SR OS
Repository contains protobuf files from the gNMI repo,
vendored from OpenConfig gNMI release v0.14.1. The upstream core gnmi_service proto option remains 0.10.0.
Earlier gNMI versions should work too; 0.7.0 has been tested successfully.
NOTE: At this moment supporting of the secure connections (with encryption or certificate) is in alpha version. You can use them, but I don't guarantee stable work.
Install
Install with uv:
uv add aiognmi
Or install into the current environment:
uv pip install aiognmi
Examples
Capabilities RPC
import asyncio
from aiognmi import AsyncgNMIClient
async def main():
async with AsyncgNMIClient(host="test-1", port=6030, username="admin", password="admin", insecure=True) as client:
resp = await client.get_capabilities()
print(resp.result)
if __name__ == "__main__":
asyncio.run(main())
Get RPC
import asyncio
from aiognmi import AsyncgNMIClient
async def main():
async with AsyncgNMIClient(host="test-1", port=6030, username="admin", password="admin", insecure=True) as client:
resp = await client.get(
paths=[
"/interfaces/interface[name=Management0]",
]
)
print(resp.result)
if __name__ == "__main__":
asyncio.run(main())
Limit the returned subtree with the depth extension convenience option:
resp = await client.get(
paths=[
"/interfaces/interface[name=Management0]",
],
depth=2,
)
The depth applies to every path in the Get request, matching the gNMI depth extension semantics. A depth of 0
means no depth limit.
Set RPC
import asyncio
from aiognmi import AsyncgNMIClient
async def main():
async with AsyncgNMIClient(host="test-1", port=6030, username="admin", password="admin", insecure=True) as client:
resp = await client.set(
update=[
{"path": "/interfaces/interface[name=Management0]/config", "data": {"description": "gnmi update test"}}
]
)
print(resp.result)
if __name__ == "__main__":
asyncio.run(main())
Commit-confirmed Set operations
Pass a client-generated commit_id and a positive rollback duration (in seconds) to start a commit-confirmed Set.
Use the same ID to confirm, cancel, or change the rollback duration of the active commit:
# Start a commit that rolls back after 60 seconds unless it is confirmed.
await client.set(
update=[{"path": "/system/config", "data": {"hostname": "router-1"}}],
commit_id="change-1",
commit_rollback_duration=60,
)
# Confirm the active commit.
await client.set(commit_id="change-1", commit_confirm=True)
# Or cancel the active commit before it is confirmed.
await client.set(commit_id="change-1", commit_cancel=True)
# Or extend its rollback window to 120 seconds.
await client.set(commit_id="change-1", commit_set_rollback_duration=120)
Only one commit action can be sent in each Set request. Commit-confirmed support varies by target; unsupported or invalid operations are returned by the target through the usual gRPC/gNMI error handling.
Prebuilt gNMI extensions can be passed to get() and set() with the extensions argument. Commit-confirmed
operations are supported through the set() arguments shown above, and get(depth=...) builds the depth extension
automatically. Other feature-specific extensions can still be passed as prebuilt Extension messages.
import asyncio
from aiognmi import AsyncgNMIClient, Extension, ExtensionID, RegisteredExtension
async def main():
extension = Extension(
registered_ext=RegisteredExtension(id=ExtensionID.Value("EID_EXPERIMENTAL"), msg=b"custom-payload")
)
async with AsyncgNMIClient(host="test-1", port=6030, username="admin", password="admin", insecure=True) as client:
resp = await client.get(
paths=[
"/interfaces/interface[name=Management0]",
],
extensions=[extension],
)
print(resp.result)
if __name__ == "__main__":
asyncio.run(main())
TLS
NOTE: At this moment supporting of the secure connections (with encryption or certificate) is in alpha version. You can use them, but I don't guarantee stable work.
Secure connections are controlled by the verify argument on AsyncgNMIClient (insecure=True bypasses TLS
entirely and verify has no effect in that case):
verify=True(default) — the server certificate is actually verified. Ifpath_root_certis provided, it is used as the trust anchor; otherwise the system trust store is used.verify=False— the client fetches the target's certificate over the network and trusts it (trust-on-first-use), overriding gRPC's hostname check to match the fetched certificate. A warning is logged whenever verification is disabled. In this modepath_root_certis ignored, whilepath_private_keyandpath_cert_chaincontinue to provide client credentials for mTLS. The target certificate must contain at least a SAN or a subject CN; gRPC always verifies the certificate identity, soconnect()raisesValueErrorif no identity can be extracted from the fetched certificate.
Behavior change: earlier versions silently auto-fetched and trusted the server certificate even with the default settings. If you relied on that behavior, pass
verify=Falseexplicitly — with the current default (verify=True) an untrusted certificate will now cause the connection to fail.
import asyncio
from aiognmi import AsyncgNMIClient
async def main():
async with AsyncgNMIClient(
host="test-1", port=6030, username="admin", password="admin", verify=False
) as client:
resp = await client.get_capabilities()
print(resp.result)
if __name__ == "__main__":
asyncio.run(main())
Credits
My work is inspired by these people:
- Anton Karneliuk and his pyGNMI library
- Carl Montanari and his scrapli library
Metadata
Release files for aiognmi 0.2.0
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 |
|---|---|---|---|---|
| aiognmi-0.2.0.tar.gz | 26.2 kB | Without provenance | Details for aiognmi-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| aiognmi-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for aiognmi-0.2.0-py3-none-any.whl |
Total release size: 53.7 kB
Release files / aiognmi-0.2.0.tar.gz
| Download URL | aiognmi-0.2.0.tar.gz |
|---|---|
| Size | 26.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1e20c658544f8ca69286cad9c1d781d06df98642dc689d1455dbe6d96f31099c
|
|
BLAKE2b-256 checksum How to use checksums |
47c63dfb1daa56d0567f7286dfaf73488f713562f2a679a179758e2b51d9fc28
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.13
|
Release files / aiognmi-0.2.0-py3-none-any.whl
| Download URL | aiognmi-0.2.0-py3-none-any.whl |
|---|---|
| Size | 27.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4bc78abfca09722a78c4f0b14617db592f28c0ffab8ae798e1f08640f316ef93
|
|
BLAKE2b-256 checksum How to use checksums |
37fdc87ff6ce5516d24e3206efd040792090949c297640cceddbef08781738e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.13
|
Security for aiognmi 0.2.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A 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.