python-opennms
An unofficial, dependency-minimal Python 3 client for the OpenNMS REST API (Horizon 30+ and Meridian). 100% coverage of the Meridian 2025 REST API reference, live-validated read and write — see Compatibility.
OpenNMS resources: Docs · REST API reference · Community forum
Features
- Covers every v1 (
/opennms/rest/) and v2 (/opennms/api/v2/) endpoint - Plain dicts in, plain dicts out — the few endpoints that require XML or form-encoded bodies are handled internally
- Single runtime dependency:
requests - Synchronous and straightforward — no async complexity
TypedDictschemas for all write payloads — field names, types, and docs in your IDE- Typed exception hierarchy — catch
NotFoundError,ForbiddenError, etc. without importingrequests - Pagination helper —
client.paginate()yields all items from any list endpoint automatically - Full test suite with method coverage (mocked HTTP — no live server required)
- Read and write smoke tests live-validated against the Meridian 2025 foundation
Installation
pip install python-opennms
From source (latest development version):
git clone https://github.com/cnewkirk/python-opennms.git
cd python-opennms
pip install .
Quick start
import opennms
client = opennms.OpenNMS(
url="https://opennms.example.com:8443",
username="admin",
password="admin",
)
# Server info
info = client.get_info()
print(info["displayVersion"])
# List alarms
alarms = client.get_alarms(limit=25, order_by="lastEventTime", order="desc")
for alarm in alarms["alarm"]:
print(alarm["id"], alarm["severity"], alarm["nodeLabel"])
# Acknowledge an alarm
client.ack_alarm(alarm_id=42)
# List alarms with FIQL filter (v2)
alarms = client.get_alarms_v2(fiql="severity==MAJOR")
Error handling
HTTP errors raise typed exceptions — no need to import requests:
import opennms
try:
node = client.get_node(99999)
except opennms.NotFoundError:
print("Node does not exist")
except opennms.ForbiddenError:
print("Insufficient permissions")
except opennms.AuthenticationError:
print("Check your credentials")
except opennms.OpenNMSError:
print("Unexpected error")
Full hierarchy: OpenNMSHTTPError (base, exposes .status_code and
.response) → BadRequestError (400), AuthenticationError (401),
ForbiddenError (403), NotFoundError (404), ConflictError (409),
ServerError (5xx).
Pagination
client.paginate() transparently handles limit/offset pagination and
yields individual items:
# Fetch every MAJOR alarm — no manual offset loop required
for alarm in client.paginate(client.get_alarms, "alarm", severity="MAJOR"):
print(alarm["id"], alarm["nodeLabel"])
# Works with any list endpoint
for node in client.paginate(client.get_nodes, "node"):
print(node["id"], node["label"])
The optional page_size argument (default 100) controls how many items are
fetched per request.
API coverage
| Resource group | Methods |
|---|---|
| Alarms (v1 + v2) | list, get, count, ack/unack/clear/escalate, bulk ops |
| Alarm statistics | stats, stats by severity |
| Alarm history | history, history at timestamp, state changes |
| Events | list, get, count, create, ack/unack, bulk ack/unack |
| Nodes | full CRUD + IP interfaces, SNMP interfaces, services, categories, assets, hardware |
| Outages | list, get, count, node outages |
| Notifications | list, get, count, trigger destination path |
| Acknowledgements | list, get, count, create, ack/unack notification |
| Requisitions | full CRUD including nodes, interfaces, services, categories, assets |
| Foreign sources | full CRUD including detectors and policies |
| SNMP configuration | get, set |
| Groups | full CRUD + user and category membership |
| Users | full CRUD + role assignment |
| Categories | full CRUD + node and group associations |
| Scheduled outages | full CRUD + daemon associations |
| KSC reports | list, get, count, create, update |
| Resources | list, get, get for node, select, delete |
| Measurements | single attribute (GET), multi-source (POST) |
| Heatmap | outages + alarms × categories / foreign sources / services / nodes |
| Maps | full CRUD + map elements (pre-Horizon 16 servers only — API removed upstream) |
| Topology graphs | containers, graph, graph view (POST), search suggestions, search results |
| Flows | count, exporters, applications, conversations, hosts |
| Device configuration | list, get, get by interface, latest, download, backup |
| Situations (v2) | list, create, add alarms, clear, accept, remove alarms |
| Business services (v2) | full CRUD |
| Metadata (v2) | full CRUD for node, interface, and service metadata |
| Server info | get |
| Discovery (v2) | submit scan configuration |
| IP interfaces (v2) | list with FIQL |
| SNMP interfaces (v2) | list with FIQL |
| EnLinkd (v2) | aggregate, LLDP/CDP/OSPF/IS-IS/Bridge links and elements |
| Monitoring locations | list, get, default, count, create, update, delete |
| Minions | list, get, count |
| If services | list (v1), update (v1), list with FIQL (v2) |
| Availability | summary, by category, by node, per-category-node |
| Health | health check, probe |
| Whoami | current user info |
| Classifications | rules CRUD, groups CRUD, classify, protocols, CSV import |
| Situation feedback | tags, get/submit feedback |
| User-defined links (v2) | list, get, create, delete |
| Applications (v2) | list, get, create, delete |
| Perspective poller (v2) | application status, service status |
| Foreign sources config | policies, detectors, services, assets, categories |
| Requisition names | list all names |
| SNMP metadata (v2) | get by node |
| Provisiond (v2) | daemon status, job status |
| Event configuration (v2) | filter, sources, CRUD, upload, enable/disable, vendors |
| Monitoring systems | main system info |
| Asset suggestions | field suggestions |
| Secure credentials vault | full CRUD |
| Configuration management | names, schemas, config CRUD, sub-parts |
| SNMP trap NBI config | config, status, trap sink CRUD |
| Email NBI config | config, status, destination CRUD |
| Syslog NBI config | config, status, destination CRUD |
| Javamail config | defaults, readmails/sendmails/end2ends CRUD |
| Status (v2) | severity summaries + filterable lists for nodes/applications/business services |
| Outage timelines | header, image, empty, HTML |
| Reports | templates, run, persisted, scheduled, download |
| Search (v2) | global context search |
| GraphML | get, create, delete |
| Grafana endpoints | CRUD, verify, dashboards |
| Geocoding (v2) | config, geocoders, activate, configure |
| Geolocation (v2) | tile-server config, node location query |
| Logs | list files, file contents |
| Filesystem | list, extensions, help, contents CRUD |
| Data choices | usage stats report/status/meta, product update |
| News feed (v2) | latest items |
Compatibility
Certified coverage baseline: OpenNMS Meridian 2025. This library
covers 100% of the resource areas in the
Meridian 2025 REST API reference
apart from the three web-UI-internal APIs (Menu, Web Assets,
UI Extension) — 66 of 69 documented areas. COVERAGE.md has the full
matrix. Read and write paths are smoke-tested against the Meridian
2025 foundation build (opennms/horizon:foundation-2025,
Horizon 34.0.1) via tests/live/compose.yaml.
Expected server range: Horizon 30+ and corresponding Meridian releases. The v1 write contracts this library speaks (XML creates, form-encoded updates, per the OpenNMS REST docs) are stable across versions, and the JSON-first endpoints rely on JSON support present since Horizon 30. Horizon releases before 30 are end-of-life and not supported. Only the certified baseline above is verified by live testing; reports from other versions are welcome.
Per-method version exceptions (also noted in the affected docstrings):
- Event configuration (
/api/v2/eventconf) requires Horizon 35+. - Maps (
/rest/maps) was removed upstream in Horizon 16; those methods only function on pre-16 servers.
Validation history: 0.4.5 was smoke-tested read-only against Meridian 2024.3.0; 0.5.0 is smoke-tested read and write against the Meridian 2025 foundation.
Authentication
Basic authentication is used. Pass verify_ssl=False to disable certificate
verification (useful for self-signed certs in lab environments):
client = opennms.OpenNMS(
url="https://opennms.example.com:8443",
username="admin",
password="admin",
verify_ssl=False,
)
Smoke testing
smoke_test.py exercises the wrapper against a real OpenNMS server. It is
intended for use against a dev or staging instance before each release — not
as a substitute for the mocked unit suite.
Tests that depend on optional plugins or heavy endpoints are reported as WARN (non-fatal) rather than FAIL. Each warning includes the specific plugin or feature required.
Read-only mode (default) is safe to run against any server, including production. It issues only GET requests and makes no changes.
export OPENNMS_URL="https://opennms.example.com:8443"
export OPENNMS_USER="admin"
export OPENNMS_PASSWORD="secret"
export OPENNMS_VERIFY_SSL="false" # omit or set to "true" for valid certs
export OPENNMS_TIMEOUT="60" # per-request timeout in seconds (default 60)
python smoke_test.py
Write mode creates and then deletes objects on the server (events,
categories, groups, requisitions, etc.). It will prompt for explicit
confirmation and print the target URL before running a single write.
Only use write mode against a dev or staging instance — never
production. The throwaway instance in tests/live/compose.yaml is a
safe target.
python smoke_test.py --write # interactive prompt required
python smoke_test.py --write --yes # skip prompt (CI pipelines only)
python smoke_test.py --no-color # plain output for log files
python smoke_test.py --skip get_resources,get_flow # skip slow tests
The --skip flag accepts a prefix — --skip get_flow skips all tests
whose label starts with get_flow.
Development
git clone https://github.com/cnewkirk/python-opennms.git
cd python-opennms
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest tests/ -v
Contributing
Bug reports and pull requests are welcome on GitHub.
Acknowledgements
All API shapes are derived from the official OpenNMS REST API documentation.
requests handles all HTTP communication. MkDocs Material renders the documentation site.
GitHub, Read the Docs, and PyPI generously provide source hosting, CI, versioned docs, and package distribution free of charge for open source projects.
Release files for python-opennms 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| python_opennms-0.6.1.tar.gz | 98.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| python_opennms-0.6.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 180.7 kB
Release files / python_opennms-0.6.1.tar.gz
| Download URL | python_opennms-0.6.1.tar.gz |
|---|---|
| Size | 98.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
67f3089f4dcfbf20fc1aac028eacc956f2d3fa092178c811ffea70b90455886d
|
|
BLAKE2b-256 checksum How to use checksums |
c18695834806f8d038218d826c2587dd2d9cfed345b93412f098739f96d1c23c
|
| 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 Aug 20, 2026.
Transparency logRelease files / python_opennms-0.6.1-py3-none-any.whl
| Download URL | python_opennms-0.6.1-py3-none-any.whl |
|---|---|
| Size | 82.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
30e779eee0ba4be488c56ae81f8e50b3ec31e5fdf311a8a744312f543d402ac4
|
|
BLAKE2b-256 checksum How to use checksums |
6449b8bd3642e3f5935f32864dfc4928c1f9f65ac4e12bc750d42694c9837b60
|
| 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 Aug 20, 2026.
Transparency log