pythonpysnmp

pysnmp - ValueError: too many values to unpack (expected 4)


If I try something like this, I got

ValueError: too many values to unpack (expected 4)

Can someone explain why?

from pysnmp.hlapi import *

errorIndication, errorStatus, errorIndex, varBinds =  nextCmd(
    SnmpEngine(),
    CommunityData('public', mpModel=1),
    UdpTransportTarget(('giga-int-2', 161)),
    ContextData(),
    ObjectType(ObjectIdentity('1.3.6.1.2.1.31.1.1.1.1')),
   lexicographicMode=False
)
if errorIndication:
    print(errorIndication)
elif errorStatus:
    print('%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
else:
    for v in varBinds:
        for name, val in v:
            print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))

Solution

  • The nextCmd() function (as well as other pysnmp functions) returns a single Python generator object which you should iterate over:

    >>> from pysnmp.hlapi import *
    >>> g = nextCmd(SnmpEngine(),
    ...             CommunityData('public'),
    ...             UdpTransportTarget(('demo.pysnmp.com', 161)),
    ...             ContextData(),
    ...             ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr')))
    >>> next(g)
    (None, 0, 0, [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.1.1.0')),
                  DisplayString('SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m'))])
    

    You can use this generator like any Python iterable, for example in a loop. Or, if you need to run just a single request/response, you can simply call next on it.

    On each iteration pysnmp sends out a request (one or more depending of circumstances) asking for a single OID which is greater than the previous one. That way you "walk" the SNMP agent till you break out of the loop or exhaust OIDs on agent's side.

    Your mistake here is that you are expecting pysnmp's nextCmd to run SNMP query immediately and return a value. Instead pysnmp gives you a generator-coroutine which you can use repeatedly to perform multiple queries (you can also .send() it OIDs to query).