Search code examples
python-3.xpysnmp

Can arguments passed to function that is assigned to a variable?


I am working with PySNMP. Throughout my program I need to perform various SNMP transactions that reuse the same arguments for different functions nextCmd, getCmd, and setCmd. For simplicity of this post, let's say that I am only working with the getCmd functions. I am aware that this function can operate on multiple OID's, but that is not my current need. Below I have just pulled the systemName for a managed device.

errorIndication, errorStatus, errorIndex, varBinds = next(
    getCmd(SnmpEngine(),
           CommunityData(snmp_community, mpModel=1),
           UdpTransportTarget((target, 161)),
           ContextData(),
           ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysName', 0))
           ))

Let's say that later in my script I need to poll the up time from the same device. Instead of having to create most of the code again, like so:

errorIndication, errorStatus, errorIndex, varBinds = next(
    getCmd(SnmpEngine(),
           CommunityData(snmp_community, mpModel=1),
           UdpTransportTarget((target, 161)),
           ContextData(),
          ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysUpTime', 0))
           ))

How can I store the getCmd function with the other static arguments and just pass the OID into the variable/function so that I can minimize my code?


Solution

  • The simplest way is just to wrap it in another function:

    def standard_call(oid):
        cmd = getCmd(SnmpEngine(), 
                     CommunityData(snmp_community, mpModel=1), 
                     UdpTransportTarget((target, 161)), 
                     ContextData(),
                     # Plug in the oid
                     ObjectType(ObjectIdentity('SNMPv2-MIB', oid, 0)))
    
        return next(cmd) 
    
    standard_call('sysUpTime')
    standard_call('sysName')
    

    Note how the part that changes was made a parameter, and everything else was made the body of the function. Generally, this is how to approach "generalization problems".


    This could be expanded by constructing the ObjectTypes from tuples passed in:

    def standard_call(*identity_args):
        # Construct the ObjectTypes we need
        obj_types = [ObjectType(ObjectIdentity(*arg_tup)) for arg_tup in identity_args]
    
        cmd = getCmd(SnmpEngine(),
                     CommunityData(snmp_community, mpModel=1),
                     UdpTransportTarget((target, 161)),
                     ContextData(),
                     # Spread the list of ObjectTypes as arguments to getCmd
                     *obj_types)
    
        return next(cmd)
    
    standard_call(('SNMPv2-MIB', 'sysName', 0),
                  ('SNMPv2-MIB', 'sysServices', 0),
                  ('CISCO-FLASH-MIB', 'ciscoFlashCopyEntryStatus', 13))