Design Decisions
Another SNMP package?
There are at least 3 more SNMP packages out there. Those are:
So why another package? API simplicity, Maintainability & MIB independence
The existing libraries all suffer from an overall complexity to use in simple applications. This complexity is partially dictated by the SNMP RFCs like RFC 3411. The focus on usage simplicity has driven many of the following design decisions.
While usage simplicity is one thing, maintainability is another. For that, see the point about RFC-divergence below.
Finally, all existing modules have a strong focus on MIBs, which can be
problematic at times. Especially for heterogenuous networks. puresnmp
makes it easy to work without MIBs.
Extensive Documentation
Simple and useful documentation is an additional focus of this library. The documentation provides a lot of example-code which should make usage of the library a lot easier. The examples in the documetnation are covered by doctests wherever possible. This forces the examples in the docstrings to be complete and should be fairly copy/pasteable.
Most of these examples are located in puresnmp.api.raw.Client
(aliased for convenience as puresnmp.Client
)
Note
When using the documentation examples from
puresnmp.api.raw.Client
also consider using
puresnmp.api.pythonic.PyWrapper
(aliased as
puresnmp.PyWrapper
) to decouple internal data-types from your
application.
Simple Data-Types
Using puresnmp.api.pythonic.PyWrapper
all data-types are
converted at the seam between the internal Python world and the SNMP worls
(with the exception of “SET” requests).
Applications using the PyWrapper
will be
strongly decoupled from any internal changes inside puresnmp
.
All internal datatypes inherit from x690.types.X690Type
and
provide the value
property to retrieve the
pure-Python value.
This may hide details from the exchanged data-types with the remote SNMP
device. For example, both Counter
and
Integer
are converted to pure-Python integers. For most
use-cases this is useful and convenient. But if needed, they can always be
accessed by using puresnmp.api.pythonic.PyWrapper.client
.
No MIB Support?
Experience has shown that MIB modules can be very fragile, especially on very heterogenuous networks. Raw OIDs are much more stable and reliable, at the expense of “human-readility”.
puresnmp
skips the processing of MIBs for this reason. Adding MIB support
is still possible as “wrapper” aruond the lower level primitives, but at the
moment there are no plans for development of this. Note that the library is
currently actively used on a large network with over 6k devices of various
manufacturers. All without MIBs, all without problems.
Effectively, MIBs sit between the user and the SNMP protocol.
puresnmp
provides low-level support for SNMP.
Not having native support for MIBs might seem very limiting at first. Let’s look at the benefits of MIBs:
They provide additional data-types (which are always sub-types of native/vanilla SNMP types)
They provide definitions for “tables”
They provide human-readable names for OIDs
All data-types used by puresnmp
are compatible with the data-types
defined in MIBs. Some more esoteric data-types may be reported as
x690.types.OctetString
without MIBs, but they always represent
the real value.
Low-level table support is provided by
puresnmp.api.pythonic.PyWrapper.table()
and
puresnmp.api.raw.Client.table()
but row-indeces may need to be
post-processed.
Converting OIDs to/from human-readable text should primarily be done on the UI level. This is not the responsibility of the library.
Divergence from RFC-3411
RFC 3411 dictates an overall architecture which is very generic. That architecture is “open” enough to allow it being implemented in many programming languages. Dynamic languages like Python allow for different implementations which would suffer from strict adherence to the RFC.
The RFC has one clear aim: Being future-proof by “pluggability”.
This pluggability is provided in puresnmp
by the use of “namespace
modules”. This allows us to provide new functionality in the future without
sacrificing “pythonic” code. It does therefore slightly diverge from the
RFC-3411 process of how “plugins” are looked up.
Finally, the library has a primary focus on being an SNMP client. Not an SNMP server. For this reason, a lot of implementations from the RFC have been skipped.
Like MIB support, adding support to respond to SNMP requests is not out of the question, but not planned either. Feel free to contact the author(s) if you want to provide support for this.
Type Hinting
The library is fully type-hinted providing a stable and maintainable code-base.
Async first
The library only provides async functions. This allows us to have one common code-base for everything. The previous version (v1.x) of puresnmp contained both a “sync” and “async” implementation, making maintainance cumbersome and error-prone.
puresnmp
can be easily integrated into a non-async application by using
asyncio.run()
.