# 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.