Skip to content

Commit

Permalink
added documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
hh-h committed May 22, 2021
1 parent 2838f03 commit 57b42be
Show file tree
Hide file tree
Showing 14 changed files with 433 additions and 80 deletions.
58 changes: 0 additions & 58 deletions README.md

This file was deleted.

103 changes: 103 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
aiosnmp
=======


.. image:: https://dev.azure.com/6660879/aiosnmp/_apis/build/status/hh-h.aiosnmp?branchName=master
:target: https://dev.azure.com/6660879/aiosnmp/_build/results?buildId=38&view=results
:alt: Build Status


.. image:: https://img.shields.io/codecov/c/github/hh-h/aiosnmp/master.svg?style=flat
:target: https://codecov.io/github/hh-h/aiosnmp?branch=master
:alt: Code Coverage


.. image:: https://badge.fury.io/py/aiosnmp.svg
:target: https://badge.fury.io/py/aiosnmp
:alt: PyPI version


.. image:: https://img.shields.io/badge/license-MIT-brightgreen.svg
:target: https://img.shields.io/badge/license-MIT-brightgreen.svg
:alt: License


.. image:: https://img.shields.io/badge/code%20style-black-black.svg
:target: https://github.com/ambv/black
:alt: Code Style


.. image:: https://img.shields.io/badge/python-3.7%2B-brightgreen.svg
:target: https://img.shields.io/badge/python-3.7%2B-brightgreen.svg
:alt: Python version


aiosnmp is an asynchronous SNMP client for use with asyncio.

Installation
------------

.. code-block:: shell
pip install aiosnmp
Documentation
-------------

https://aiosnmp.readthedocs.io/en/latest/api.html

Notice
------

| Only snmp v2c supported, v3 version is not supported
| Oids should be like ``.1.3.6...`` or ``1.3.6...``. ``iso.3.6...`` is not supported
Source address (host and port) validation
-----------------------------------------

By default, v2c should not validate source addr, but in this library, it is enabled by default.
You can disable validation by passing ``validate_source_addr=False`` to ``Snmp``.

Basic Usage
-----------

.. code-block:: python
import asyncio
import aiosnmp
async def main():
async with aiosnmp.Snmp(host="127.0.0.1", port=161, community="public") as snmp:
for res in await snmp.get(".1.3.6.1.2.1.1.1.0"):
print(res.oid, res.value)
asyncio.run(main())
more in `/examples <https://github.com/hh-h/aiosnmp/tree/master/examples>`_

TODO
----

* snmp v3 support
* more tests

License
-------

aiosnmp is developed and distributed under the MIT license.

Run local tests
---------------

.. code-block:: shell
pip install -r requirements-dev.txt
tox
Before submitting PR
--------------------

.. code-block:: shell
pip install -r requirements-dev.txt
tox -e format
4 changes: 2 additions & 2 deletions aiosnmp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
__all__ = ("Snmp", "SnmpV2TrapMessage", "SnmpV2TrapServer", "exceptions")
__all__ = ("Snmp", "SnmpV2TrapMessage", "SnmpV2TrapServer", "exceptions", "SnmpVarbind")
__version__ = "0.4.0"
__author__ = "Valetov Konstantin"

from .message import SnmpV2TrapMessage
from .message import SnmpV2TrapMessage, SnmpVarbind
from .snmp import Snmp
from .trap import SnmpV2TrapServer
64 changes: 53 additions & 11 deletions aiosnmp/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,20 @@


class SnmpException(Exception):
pass
"""Base class for exceptions"""


class SnmpTimeoutError(SnmpException, TimeoutError):
pass
"""The operation exceeded the given deadline"""


class SnmpUnsupportedValueType(SnmpException):
pass
"""Provided value type is unsupported"""


class SnmpErrorStatus(SnmpException):
"""Base class for SNMP errors"""

message = ""

def __init__(self, index: int, oid: Optional[str] = None) -> None:
Expand All @@ -49,20 +51,29 @@ def __init__(self, index: int, oid: Optional[str] = None) -> None:


class SnmpErrorTooBig(SnmpErrorStatus):
message = "The agent could not place the results " "of the requested SNMP operation in a single SNMP message."
"""The agent could not place the results of the requested SNMP operation in a single SNMP message."""

message = "The agent could not place the results of the requested SNMP operation in a single SNMP message."


class SnmpErrorNoSuchName(SnmpErrorStatus):
"""The requested SNMP operation identified an unknown variable."""

message = "The requested SNMP operation identified an unknown variable."


class SnmpErrorBadValue(SnmpErrorStatus):
message = (
"The requested SNMP operation tried to change a variable " "but it specified either a syntax or value error."
)
"""The requested SNMP operation tried to change a variable but it specified either a syntax or value error."""

message = "The requested SNMP operation tried to change a variable but it specified either a syntax or value error."


class SnmpErrorReadOnly(SnmpErrorStatus):
"""
The requested SNMP operation tried to change a variable that was not allowed to change,
according to the community profile of the variable.
"""

message = (
"The requested SNMP operation tried to change a variable "
"that was not allowed to change, "
Expand All @@ -71,64 +82,95 @@ class SnmpErrorReadOnly(SnmpErrorStatus):


class SnmpErrorGenErr(SnmpErrorStatus):
message = "An error other than one of those listed here " "occurred during the requested SNMP operation."
"""An error other than one of those listed here occurred during the requested SNMP operation.s"""

message = "An error other than one of those listed here occurred during the requested SNMP operation."


class SnmpErrorNoAccess(SnmpErrorStatus):
"""The specified SNMP variable is not accessible."""

message = "The specified SNMP variable is not accessible."


class SnmpErrorWrongType(SnmpErrorStatus):
message = "The value specifies a type that is inconsistent " "with the type required for the variable."
"""The value specifies a type that is inconsistent with the type required for the variable."""

message = "The value specifies a type that is inconsistent with the type required for the variable."


class SnmpErrorWrongLength(SnmpErrorStatus):
message = "The value specifies a length that is inconsistent " "with the length required for the variable."
"""The value specifies a length that is inconsistent with the length required for the variable."""

message = "The value specifies a length that is inconsistent with the length required for the variable."


class SnmpErrorWrongEncoding(SnmpErrorStatus):
"""The value contains an Abstract Syntax Notation One (ASN.1) encoding
that is inconsistent with the ASN.1 tag of the field."""

message = (
"The value contains an Abstract Syntax Notation One (ASN.1) encoding "
"that is inconsistent with the ASN.1 tag of the field."
)


class SnmpErrorWrongValue(SnmpErrorStatus):
"""The value cannot be assigned to the variable."""

message = "The value cannot be assigned to the variable."


class SnmpErrorNoCreation(SnmpErrorStatus):
"""The variable does not exist, and the agent cannot create it."""

message = "The variable does not exist, and the agent cannot create it."


class SnmpErrorInconsistentValue(SnmpErrorStatus):
"""The value is inconsistent with values of other managed objects."""

message = "The value is inconsistent with values of other managed objects."


class SnmpErrorResourceUnavailable(SnmpErrorStatus):
message = "Assigning the value to the variable requires allocation of resources " "that are currently unavailable."
"""Assigning the value to the variable requires allocation of resources that are currently unavailable."""

message = "Assigning the value to the variable requires allocation of resources that are currently unavailable."


class SnmpErrorCommitFailed(SnmpErrorStatus):
"""No validation errors occurred, but no variables were updated."""

message = "No validation errors occurred, but no variables were updated."


class SnmpErrorUndoFailed(SnmpErrorStatus):
"""No validation errors occurred. Some variables were updated
because it was not possible to undo their assignment."""

message = (
"No validation errors occurred. Some variables were updated "
"because it was not possible to undo their assignment."
)


class SnmpErrorAuthorizationError(SnmpErrorStatus):
"""An authorization error occurred."""

message = "An authorization error occurred."


class SnmpErrorNotWritable(SnmpErrorStatus):
"""The variable exists but the agent cannot modify it."""

message = "The variable exists but the agent cannot modify it."


class SnmpErrorInconsistentName(SnmpErrorStatus):
"""The variable does not exist; the agent cannot create it because
the named object instance is inconsistent with the values of other managed objects."""

message = (
"The variable does not exist; "
"the agent cannot create it because the named object instance "
Expand Down
35 changes: 29 additions & 6 deletions aiosnmp/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,28 @@ class PDUType(enum.IntEnum):


class SnmpVarbind:
__slots__ = ("_oid", "value")
__slots__ = ("_oid", "_value")

def __init__(
self,
oid: str,
value: Union[None, str, int, bytes, ipaddress.IPv4Address] = None,
) -> None:
self._oid: str = oid.lstrip(".")
self.value: Union[None, str, int, bytes, ipaddress.IPv4Address] = value
self._value: Union[None, str, int, bytes, ipaddress.IPv4Address] = value

@property
def oid(self) -> str:
"""This property stores oid of the message"""

return f".{self._oid}"

@property
def value(self) -> Union[None, str, int, bytes, ipaddress.IPv4Address]:
"""This property stores value of the message"""

return self._value

def encode(self, encoder: Encoder) -> None:
with encoder.enter(Number.Sequence):
encoder.write(self._oid, Number.ObjectIdentifier)
Expand Down Expand Up @@ -183,12 +191,27 @@ def decode(cls, data: bytes) -> "SnmpResponse":


class SnmpV2TrapMessage:
__slots__ = ("version", "community", "data")
__slots__ = ("_version", "_community", "_data")

def __init__(self, version: SnmpVersion, community: str, data: PDU) -> None:
self.version: SnmpVersion = version
self.community: str = community
self.data: PDU = data
self._version: SnmpVersion = version
self._community: str = community
self._data: PDU = data

@property
def version(self) -> SnmpVersion:
"""Returns version of the message"""
return self._version

@property
def community(self) -> str:
"""Returns community of the message"""
return self._community

@property
def data(self) -> PDU:
"""Returns :class:`protocol data unit <PDU>` of the message"""
return self._data

@classmethod
def decode(cls, data: bytes) -> Optional["SnmpV2TrapMessage"]:
Expand Down
Loading

0 comments on commit 57b42be

Please sign in to comment.