sysrepo-python-plugind
A Python reimplementation of sysrepo-plugind — the sysrepo plugin daemon.
The C daemon loads compiled .so plugins via dlopen. This daemon loads Python plugins discovered via entry points (importlib.metadata), giving plugin authors a pure-Python development experience against the existing sysrepo-python CFFI bindings.
The two daemons can run simultaneously: the Python daemon manages its own YANG subtree (python-plugin-order, python-loaded-plugins) and never touches the C daemon’s nodes.
Requirements
Python ≥ 3.10
sysrepo-python (and the underlying libsysrepo.so)
sysrepo core 4.2.10 (ships sysrepo-plugind@2022-08-26.yang)
Installation
pip install sysrepo-python-plugind
Then register the YANG augmentation module with sysrepo (requires write access to the sysrepo repository, typically run as root):
sysrepo-python-plugind-setup
This is idempotent — safe to run on every deployment or system boot. Pass --force to upgrade the module after a package update.
Writing a plugin
Subclass SysrepoPlugin and implement init(). Register the class via an entry point in your package’s pyproject.toml:
[project.entry-points."sysrepo_python.plugins"]
my-plugin = "my_package.plugin:MyPlugin"
Installing your package makes the plugin visible to the daemon immediately — no copying of files or environment variables required.
Minimal example:
import logging
import sysrepo
from sysrepo_python_plugind import SysrepoPlugin
LOG = logging.getLogger(__name__)
class MyPlugin(SysrepoPlugin):
def init(self, session: sysrepo.SysrepoSession) -> None:
self._counter = 0
session.subscribe_module_change(
"my-module", None, self._on_change, done_only=True
)
session.subscribe_oper_data_request(
"my-module", "/my-module:stats", self._on_oper
)
LOG.info("MyPlugin ready")
def cleanup(self, session: sysrepo.SysrepoSession) -> None:
LOG.info("MyPlugin stopping (counter=%d)", self._counter)
def _on_change(self, event, req_id, changes, priv):
self._counter += 1
def _on_oper(self, xpath, priv):
return {"my-module": {"stats": {"change-count": self._counter}}}
State that the C daemon stored in void *private_data is stored as instance attributes (self._counter above).
Each plugin is given its own dedicated SysrepoSession. The same session object is passed to init() and later to cleanup(), and the daemon stops it only after cleanup() returns — so cleanup() can still unsubscribe and access the datastore through it. (The C sysrepo-plugind shares a single session across every plugin; this daemon does not.)
Async callbacks
The daemon starts an asyncio event loop in a background thread before calling any init(), so plugins can use asyncio_register=True subscriptions without managing a loop themselves:
class AsyncMyPlugin(SysrepoPlugin):
def init(self, session: sysrepo.SysrepoSession) -> None:
session.subscribe_module_change(
"my-module", None, self._on_change,
done_only=True, asyncio_register=True,
)
async def _on_change(self, event, req_id, changes, priv):
...
Running the daemon
# Foreground, INFO-level logging to stderr:
sysrepo-python-plugind -d -v 2
# Background (daemonize), write PID file:
sysrepo-python-plugind -p /run/sysrepo-python-plugind.pid
CLI flags mirror those of the C sysrepo-plugind:
-d |
Stay in foreground; log to stderr instead of syslog |
-v LEVEL |
Verbosity: 0=ERROR 1=WARNING 2=INFO 3=DEBUG (default: 2) |
-p PATH |
Write PID file at PATH |
-f |
Exit if any plugin fails to initialise (default: skip and continue) |
Plugin ordering
By default plugins are initialised in entry-point discovery order. To override this, set the python-plugin-order leaf-list in sysrepo’s running datastore:
sysrepocfg -d running --edit
Add under /sysrepo-plugind:sysrepo-plugind:
<python-plugin-order xmlns="urn:sysrepo:python-plugind">
<plugin>my-plugin</plugin>
<plugin>other-plugin</plugin>
</python-plugin-order>
Plugins absent from the list are appended after the ordered set, preserving their discovery order. A trailing file extension in a configured name (e.g. my-plugin.so) is stripped before comparison, so operator configs written for the C daemon can be reused unchanged.
The list of successfully initialised plugins is published to the operational datastore at /sysrepo-plugind:sysrepo-plugind/sysrepo-python-plugind:python-loaded-plugins/plugin.
Systemd deployment
A service file is provided in the systemd/ directory of the source distribution:
cp systemd/sysrepo-python-plugind.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now sysrepo-python-plugind
The service runs sysrepo-python-plugind-setup as ExecStartPre=, ensuring the YANG module is present before the daemon starts.
If the daemon binary is not at /usr/bin/sysrepo-python-plugind (e.g. when installed into a virtual environment), update the ExecStartPre= and ExecStart= paths in the service file accordingly.
License
BSD-3-Clause — same as sysrepo-python.
Metadata
Release files for sysrepo-python-plugind 1.1.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 | |
|---|---|---|---|
| sysrepo_python_plugind-1.1.0.tar.gz | 19.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sysrepo_python_plugind-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.3 kB
Release files / sysrepo_python_plugind-1.1.0.tar.gz
| Download URL | sysrepo_python_plugind-1.1.0.tar.gz |
|---|---|
| Size | 19.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
01c2ad39d83eaa6868ee6a31f6ba7f00df4ad6456d87d24698aa5976205e90bf
|
|
BLAKE2b-256 checksum How to use checksums |
0c088b39702151133eda6b27c343023ea06850d4e1a1a30bfcef2fa4a3dc61f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.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 Sep 9, 2026.
Transparency logRelease files / sysrepo_python_plugind-1.1.0-py3-none-any.whl
| Download URL | sysrepo_python_plugind-1.1.0-py3-none-any.whl |
|---|---|
| Size | 19.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
76c81d50ae78990c122485dc548a0ca2326bc7c1f1e86e050f91bdd99b169b54
|
|
BLAKE2b-256 checksum How to use checksums |
4f5b640fc547e693a9fddb26525d096b9d1ad19bee64cd116906fbd526bf14d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.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 Sep 9, 2026.
Transparency log