Asynchronous: asyncore
**********************

With "asyncore" API your scripts get CPU time on "socket" events being
watched for by "select" dispatcher. Your code live mostly in isolated
functions (or any callable objects).

In most examples approximate analogues of well known Net-SNMP snmp*
tools command line options are shown. That may help those readers who,
by chance are familiar with Net-SNMP tools, better understanding what
example code doe

Here's a quick example on a simple SNMP GET by high-level API:

   * with SNMPv1, community 'public'

   * over IPv4/UDP

   * to an Agent at demo.snmplabs.com:161

   * for two instances of SNMPv2-MIB::sysDescr.0 MIB object,

   from pysnmp.hlapi.asyncore import *


   # noinspection PyUnusedLocal,PyUnusedLocal,PyUnusedLocal
   def cbFun(snmpEngine, sendRequestHandle, errorIndication,
             errorStatus, errorIndex, varBinds, cbCtx):
       if errorIndication:
           print(errorIndication)
           return
       elif errorStatus:
           print('%s at %s' % (errorStatus.prettyPrint(),
                               errorIndex and varBindTable[-1][int(errorIndex) - 1][0] or '?'))
           return
       else:
           for varBind in varBinds:
               print(' = '.join([x.prettyPrint() for x in varBind]))


   snmpEngine = SnmpEngine()

   getCmd(snmpEngine,
          CommunityData('public'),
          UdpTransportTarget(('demo.snmplabs.com', 161)),
          ContextData(),
          ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)),
          cbFun=cbFun)

   snmpEngine.transportDispatcher.runDispatcher()

To make use of SNMPv3 and USM, the following code performs a series of
SNMP GETNEXT operations effectively fetching a table of SNMP variables
from SNMP Agent:

* with SNMPv3, user 'usr-md5-none', MD5 authentication, no privacy

* over IPv4/UDP

* to an Agent at demo.snmplabs.com:161

* for all OIDs in IF-MIB

   from pysnmp.hlapi.asyncore import *


   # noinspection PyUnusedLocal,PyUnusedLocal,PyUnusedLocal
   def cbFun(snmpEngine, sendRequestHandle, errorIndication,
             errorStatus, errorIndex, varBindTable, cbCtx):
       if errorIndication:
           print(errorIndication)
           return
       elif errorStatus:
           print('%s at %s' % (errorStatus.prettyPrint(),
                               errorIndex and varBindTable[-1][int(errorIndex) - 1][0] or '?'))
           return
       else:
           for varBindRow in varBindTable:
               for varBind in varBindRow:
                   print(' = '.join([x.prettyPrint() for x in varBind]))

       return True  # request lower layers to do GETNEXT and call us back


   snmpEngine = SnmpEngine()

   nextCmd(snmpEngine,
           UsmUserData('usr-md5-none', 'authkey1'),
           UdpTransportTarget(('demo.snmplabs.com', 161)),
           ContextData(),
           ObjectType(ObjectIdentity('SNMPv2-MIB', 'system')),
           ObjectType(ObjectIdentity('IF-MIB', 'ifTable')),
           cbFun=cbFun)

   snmpEngine.transportDispatcher.runDispatcher()

More examples on Command Generator API usage follow.

* Various SNMP versions

  * SNMPv2c

  * Walk whole MIB

* Walking operations

  * Walk whole MIB

* Advanced Command Generator

  * Walk multiple Agents at once

  * Multiple SNMP engines

  * Multiple concurrent queries

Sending SNMP TRAP's and INFORM's is as easy with PySNMP library. The
following code sends SNMP TRAP:

* SNMPv1

* with community name 'public'

* over IPv4/UDP

* send TRAP notification

* with Generic Trap #1 (warmStart) and Specific Trap 0

* with default Uptime

* with default Agent Address

* with Enterprise OID 1.3.6.1.4.1.20408.4.1.1.2

* include managed object information '1.3.6.1.2.1.1.1.0' = 'my system'

   from pysnmp.hlapi.asyncore import *

   snmpEngine = SnmpEngine()

   sendNotification(
       snmpEngine,
       CommunityData('public', mpModel=0),
       UdpTransportTarget(('demo.snmplabs.com', 162)),
       ContextData(),
       'trap',
       NotificationType(
           ObjectIdentity('1.3.6.1.6.3.1.1.5.2')
       ).addVarBinds(
           ('1.3.6.1.6.3.1.1.4.3.0', '1.3.6.1.4.1.20408.4.1.1.2'),
           ('1.3.6.1.2.1.1.1.0', OctetString('my system'))
       )
   )

   snmpEngine.transportDispatcher.runDispatcher()

More examples on Notification Originator API usage follow.

* Common notifications

  * SNMPv1 TRAP with defaults

* Advanced Notification Originator

  * Multiple concurrent queries

  * Multiple concurrent notifications

  * Multiple SNMP Engines

More sophisticated or less popular SNMP operations can still be
performed with PySNMP through its Native API to Standard SNMP
Applications.
