From 5e11539b442e3f7dde09b37fdbd39138793e4a45 Mon Sep 17 00:00:00 2001
From: Pim van Pelt <pim@ipng.nl>
Date: Sun, 8 Jan 2023 13:05:42 +0100
Subject: [PATCH] Format with black

---
 agentx/__init__.py |   8 +-
 agentx/agent.py    |  32 ++---
 agentx/dataset.py  |  30 +++--
 agentx/network.py  |  70 ++++++-----
 agentx/pdu.py      | 221 ++++++++++++++++----------------
 vpp-snmp-agent.py  | 304 ++++++++++++++++++++++++++++++++-------------
 vppapi.py          |  25 ++--
 vppstats.py        | 205 ++++++++++++++++--------------
 8 files changed, 540 insertions(+), 355 deletions(-)

diff --git a/agentx/__init__.py b/agentx/__init__.py
index f4f6762..1cd8f77 100644
--- a/agentx/__init__.py
+++ b/agentx/__init__.py
@@ -11,19 +11,23 @@ import logging
 from agentx.agent import Agent
 from agentx.dataset import DataSet
 
+
 def setup_logging(debug=False):
     if debug:
         level = logging.DEBUG
     else:
         level = logging.INFO
-    logger = logging.getLogger('agentx')
+    logger = logging.getLogger("agentx")
     logger.setLevel(level)
-    formatter = logging.Formatter('[%(levelname)-8s] %(name)17s - %(funcName)-15s: %(message)s')
+    formatter = logging.Formatter(
+        "[%(levelname)-8s] %(name)17s - %(funcName)-15s: %(message)s"
+    )
     ch = logging.StreamHandler()
     ch.setLevel(level)
     ch.setFormatter(formatter)
     logger.addHandler(ch)
 
+
 AGENTX_EMPTY_PDU = 1
 AGENTX_OPEN_PDU = 1
 AGENTX_CLOSE_PDU = 2
diff --git a/agentx/agent.py b/agentx/agent.py
index 184dab0..9a493ba 100644
--- a/agentx/agent.py
+++ b/agentx/agent.py
@@ -12,14 +12,15 @@ import agentx
 from agentx.dataset import DataSet
 from agentx.network import Network
 
+
 class NullHandler(logging.Handler):
     def emit(self, record):
         pass
 
 
 class Agent(object):
-    def __init__(self, server_address='/var/agentx/master', period=30.0):
-        self.logger = logging.getLogger('agentx.agent')
+    def __init__(self, server_address="/var/agentx/master", period=30.0):
+        self.logger = logging.getLogger("agentx.agent")
         self.logger.addHandler(NullHandler())
 
         self._servingset = DataSet()
@@ -27,7 +28,7 @@ class Agent(object):
         self._lastupdate = 0
         self._update_period = period  # Seconds
 
-        self._net = Network(server_address = server_address)
+        self._net = Network(server_address=server_address)
 
         self._oid_list = []
 
@@ -41,43 +42,44 @@ class Agent(object):
         return True
 
     def run(self):
-        self.logger.info('Calling setup')
+        self.logger.info("Calling setup")
         if not self.setup():
-            self.logger.error('Setup failed - exiting')
+            self.logger.error("Setup failed - exiting")
             return
 
-        self.logger.info('Initial update')
+        self.logger.info("Initial update")
         self._update()
 
         while True:
             if not self._net.is_connected():
-              self.logger.info('Opening AgentX connection')
-              self._net.start(self._oid_list)
+                self.logger.info("Opening AgentX connection")
+                self._net.start(self._oid_list)
 
             if time.time() - self._lastupdate > self._update_period:
                 if not self._update():
-                    self.logger.warning('Update failed, last successful update was %s' % self._lastupdate)
+                    self.logger.warning(
+                        "Update failed, last successful update was %s"
+                        % self._lastupdate
+                    )
                     time.sleep(1)
 
             try:
                 self._net.run()
             except Exception as e:
-                self.logger.error('An exception occurred: %s' % e)
-                self.logger.error('Reconnecting')
+                self.logger.error("An exception occurred: %s" % e)
+                self.logger.error("Reconnecting")
                 self._net.disconnect()
                 time.sleep(0.1)
 
     def stop(self):
-        self.logger.debug('Stopping')
+        self.logger.debug("Stopping")
         self._net.disconnect()
         pass
 
-
     def setup(self):
         # Override this
         pass
 
-
     def update(self):
         # Override this
         pass
@@ -88,5 +90,5 @@ class Agent(object):
 
         for oid in oid_list:
             if not oid in self._oid_list:
-                self.logger.debug('Adding %s to list' % oid)
+                self.logger.debug("Adding %s to list" % oid)
                 self._oid_list.append(oid)
diff --git a/agentx/dataset.py b/agentx/dataset.py
index 06f141d..84bb359 100644
--- a/agentx/dataset.py
+++ b/agentx/dataset.py
@@ -9,38 +9,36 @@ from __future__ import (
 import time
 import agentx
 
+
 class DataSetError(Exception):
     pass
 
-class DataSet():
+
+class DataSet:
     def __init__(self):
         self._data = {}
 
     def set(self, oid, oid_type, value):
-        if oid_type.startswith('int'):
+        if oid_type.startswith("int"):
             t = agentx.TYPE_INTEGER
-        elif oid_type.startswith('str'):
+        elif oid_type.startswith("str"):
             t = agentx.TYPE_OCTETSTRING
-        elif oid_type.startswith('oid'):
+        elif oid_type.startswith("oid"):
             t = agentx.TYPE_OBJECTIDENTIFIER
-        elif oid_type.startswith('ip'):
+        elif oid_type.startswith("ip"):
             t = agentx.TYPE_IPADDRESS
-        elif oid_type == 'counter32' or oid_type == 'uint32' or oid_type == 'u32':
+        elif oid_type == "counter32" or oid_type == "uint32" or oid_type == "u32":
             t = agentx.TYPE_COUNTER32
-        elif oid_type == 'gauge32':
+        elif oid_type == "gauge32":
             t = agentx.TYPE_GAUGE32
-        elif oid_type.startswith('time') or oid_type.startswith('tick'):
+        elif oid_type.startswith("time") or oid_type.startswith("tick"):
             t = agentx.TYPE_TIMETICKS
-        elif oid_type.startswith('opaque'):
+        elif oid_type.startswith("opaque"):
             t = agentx.TYPE_OPAQUE
-        elif oid_type == 'counter64' or oid_type == 'uint64' or oid_type == 'u64':
+        elif oid_type == "counter64" or oid_type == "uint64" or oid_type == "u64":
             t = agentx.TYPE_COUNTER64
         else:
-            raise DataSetErrror('Invalid oid_type: %s' % (oid_type))
+            raise DataSetErrror("Invalid oid_type: %s" % (oid_type))
             return
 
-        self._data[oid] = {
-            'name': oid,
-            'type': t,
-            'value': value
-        }
+        self._data[oid] = {"name": oid, "type": t, "value": value}
diff --git a/agentx/network.py b/agentx/network.py
index ee72029..4bfeb67 100644
--- a/agentx/network.py
+++ b/agentx/network.py
@@ -17,15 +17,17 @@ class NullHandler(logging.Handler):
     def emit(self, record):
         pass
 
-logger = logging.getLogger('agentx.network')
+
+logger = logging.getLogger("agentx.network")
 logger.addHandler(NullHandler())
 
+
 class NetworkError(Exception):
     pass
 
 
-class Network():
-    def __init__(self, server_address = '/var/agentx/master'):
+class Network:
+    def __init__(self, server_address="/var/agentx/master"):
 
         self.session_id = 0
         self.transaction_id = 0
@@ -35,8 +37,7 @@ class Network():
         self.data_idx = []
         self._connected = False
         self._server_address = server_address
-        self._timeout = 0.1 # Seconds
-
+        self._timeout = 0.1  # Seconds
 
     def connect(self):
         if self._connected:
@@ -44,12 +45,12 @@ class Network():
 
         try:
             logger.info("Connecting to %s" % self._server_address)
-            if self._server_address.startswith('/'):
+            if self._server_address.startswith("/"):
                 self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
                 self.socket.connect(self._server_address)
             else:
                 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-                host, port=self._server_address.split(':')
+                host, port = self._server_address.split(":")
 
                 self.socket.connect((host, int(port)))
             self.socket.settimeout(self._timeout)
@@ -76,7 +77,9 @@ class Network():
         self.data = newdata.copy()
 
         del self.data_idx
-        self.data_idx = sorted(self.data.keys(), key=lambda k: tuple(int(part) for part in k.split('.')))
+        self.data_idx = sorted(
+            self.data.keys(), key=lambda k: tuple(int(part) for part in k.split("."))
+        )
 
     def new_pdu(self, type):
         pdu = PDU(type)
@@ -93,15 +96,18 @@ class Network():
         return pdu
 
     def send_pdu(self, pdu):
-        if self.debug: pdu.dump()
+        if self.debug:
+            pdu.dump()
         self.socket.send(pdu.encode())
 
     def recv_pdu(self):
         buf = self.socket.recv(100000)
-        if not buf: return None
+        if not buf:
+            return None
         pdu = PDU()
         pdu.decode(buf)
-        if self.debug: pdu.dump()
+        if self.debug:
+            pdu.dump()
         return pdu
 
     # =========================================
@@ -109,7 +115,7 @@ class Network():
     def _get_next_oid(self, oid, endoid):
         if oid in self.data:
             # Exact match found
-            #logger.debug('get_next_oid, exact match of %s' % oid)
+            # logger.debug('get_next_oid, exact match of %s' % oid)
             idx = self.data_idx.index(oid)
             if idx == (len(self.data_idx) - 1):
                 # Last Item in MIB, No match!
@@ -117,11 +123,11 @@ class Network():
             return self.data_idx[idx + 1]
         else:
             # No exact match, find prefix
-            #logger.debug('get_next_oid, no exact match of %s' % oid)
-            slist = oid.split('.')
-            elist = endoid.split('.')
+            # logger.debug('get_next_oid, no exact match of %s' % oid)
+            slist = oid.split(".")
+            elist = endoid.split(".")
             for tmp_oid in self.data_idx:
-                tlist = tmp_oid.split('.')
+                tlist = tmp_oid.split(".")
                 for i in range(len(tlist)):
                     try:
                         sok = int(slist[i]) <= int(tlist[i])
@@ -166,13 +172,13 @@ class Network():
     def is_connected(self):
         return self._connected
 
-    def run(self, timeout = 0.1):
+    def run(self, timeout=0.1):
         if not self._connected:
-            raise NetworkError('Not connected')
+            raise NetworkError("Not connected")
 
         if timeout != self._timeout:
-          self.socket.settimeout(timeout)
-          self._timeout = timeout
+            self.socket.settimeout(timeout)
+            self._timeout = timeout
 
         try:
             request = self.recv_pdu()
@@ -195,11 +201,13 @@ class Network():
                     response.values.append(self.data[oid])
                 else:
                     logger.debug("OID Not Found!")
-                    response.values.append({
-                        'type': agentx.TYPE_NOSUCHOBJECT,
-                        'name': rvalue[0],
-                        'value': 0
-                    })
+                    response.values.append(
+                        {
+                            "type": agentx.TYPE_NOSUCHOBJECT,
+                            "name": rvalue[0],
+                            "value": 0,
+                        }
+                    )
 
         elif request.type == agentx.AGENTX_GETNEXT_PDU:
             logger.debug("Received GET_NEXT PDU")
@@ -209,11 +217,13 @@ class Network():
                 if oid:
                     response.values.append(self.data[oid])
                 else:
-                    response.values.append({
-                        'type': agentx.TYPE_ENDOFMIBVIEW,
-                        'name': rvalue[0],
-                        'value': 0
-                    })
+                    response.values.append(
+                        {
+                            "type": agentx.TYPE_ENDOFMIBVIEW,
+                            "name": rvalue[0],
+                            "value": 0,
+                        }
+                    )
 
         else:
             logger.warn("Received unsupported PDU %d" % request.type)
diff --git a/agentx/pdu.py b/agentx/pdu.py
index 0e6c567..b38c6b6 100644
--- a/agentx/pdu.py
+++ b/agentx/pdu.py
@@ -12,10 +12,13 @@ import pprint
 import logging
 import agentx
 
+
 class NullHandler(logging.Handler):
     def emit(self, record):
         pass
-logger = logging.getLogger('agentx.pdu')
+
+
+logger = logging.getLogger("agentx.pdu")
 logger.addHandler(NullHandler())
 
 
@@ -27,34 +30,32 @@ class PDU(object):
         self.packet_id = 0
         self.error = agentx.ERROR_NOAGENTXERROR
         self.error_index = 0
-        self.decode_buf = ''
+        self.decode_buf = ""
         self.state = {}
         self.values = []
 
     def dump(self):
         name = agentx.PDU_TYPE_NAME[self.type]
-        logger.debug('PDU DUMP: New PDU')
+        logger.debug("PDU DUMP: New PDU")
         logger.debug(
-            'PDU DUMP: Meta      : [%s: %d %d %d]' %
-            (name, self.session_id, self.transaction_id, self.packet_id))
-        if 'payload_length' in self.state:
-            logger.debug('PDU DUMP: Length    : %s' %
-                         self.state['payload_length'])
-        if hasattr(self, 'response'):
-            logger.debug('PDU DUMP: Response  : %s' % self.response)
-        if hasattr(self, 'values'):
-            logger.debug('PDU DUMP: Values    : %s' %
-                         pprint.pformat(self.values))
-        if hasattr(self, 'range_list'):
-            logger.debug('PDU DUMP: Range list: %s' %
-                         pprint.pformat(self.range_list))
+            "PDU DUMP: Meta      : [%s: %d %d %d]"
+            % (name, self.session_id, self.transaction_id, self.packet_id)
+        )
+        if "payload_length" in self.state:
+            logger.debug("PDU DUMP: Length    : %s" % self.state["payload_length"])
+        if hasattr(self, "response"):
+            logger.debug("PDU DUMP: Response  : %s" % self.response)
+        if hasattr(self, "values"):
+            logger.debug("PDU DUMP: Values    : %s" % pprint.pformat(self.values))
+        if hasattr(self, "range_list"):
+            logger.debug("PDU DUMP: Range list: %s" % pprint.pformat(self.range_list))
 
     # ====================================================
     # encode functions
 
     def encode_oid(self, oid, include=0):
         oid = oid.strip()
-        oid = oid.split('.')
+        oid = oid.split(".")
         oid = [int(i) for i in oid]
         if len(oid) > 5 and oid[:4] == [1, 3, 6, 1]:
             # prefix
@@ -63,66 +64,70 @@ class PDU(object):
         else:
             # no prefix
             prefix = 0
-        buf = struct.pack('BBBB', len(oid), prefix, include, 0)
+        buf = struct.pack("BBBB", len(oid), prefix, include, 0)
         for i in range(len(oid)):
-            buf += struct.pack('!L', oid[i])
+            buf += struct.pack("!L", oid[i])
         return buf
 
     def encode_octet(self, octet):
         octet = octet.encode("utf-8")
-        buf = struct.pack('!L', len(octet))
+        buf = struct.pack("!L", len(octet))
         buf += octet
         padding = (4 - (len(octet) % 4)) % 4
         buf += chr(0).encode() * padding
         return buf
 
     def encode_value(self, type, name, value):
-        buf = struct.pack('!HH', type, 0)
+        buf = struct.pack("!HH", type, 0)
         buf += self.encode_oid(name)
         if type in [agentx.TYPE_INTEGER]:
-            buf += struct.pack('!l', value)
+            buf += struct.pack("!l", value)
         elif type in [
-                agentx.TYPE_COUNTER32, agentx.TYPE_GAUGE32,
-                agentx.TYPE_TIMETICKS
+            agentx.TYPE_COUNTER32,
+            agentx.TYPE_GAUGE32,
+            agentx.TYPE_TIMETICKS,
         ]:
-            buf += struct.pack('!L', value)
+            buf += struct.pack("!L", value)
         elif type in [agentx.TYPE_COUNTER64]:
-            buf += struct.pack('!Q', value)
+            buf += struct.pack("!Q", value)
         elif type in [agentx.TYPE_OBJECTIDENTIFIER]:
             buf += self.encode_oid(value)
         elif type in [
-                agentx.TYPE_IPADDRESS, agentx.TYPE_OPAQUE,
-                agentx.TYPE_OCTETSTRING
+            agentx.TYPE_IPADDRESS,
+            agentx.TYPE_OPAQUE,
+            agentx.TYPE_OCTETSTRING,
         ]:
             buf += self.encode_octet(value)
         elif type in [
-                agentx.TYPE_NULL, agentx.TYPE_NOSUCHOBJECT,
-                agentx.TYPE_NOSUCHINSTANCE, agentx.TYPE_ENDOFMIBVIEW
+            agentx.TYPE_NULL,
+            agentx.TYPE_NOSUCHOBJECT,
+            agentx.TYPE_NOSUCHINSTANCE,
+            agentx.TYPE_ENDOFMIBVIEW,
         ]:
             # No data
             pass
         else:
-            logger.error('Unknown Type:' % type)
+            logger.error("Unknown Type:" % type)
         return buf
 
     def encode_header(self, pdu_type, payload_length=0, flags=0):
         flags = flags | 0x10  # Bit 5 = all ints in NETWORK_BYTE_ORDER
-        buf = struct.pack('BBBB', 1, pdu_type, flags, 0)
-        buf += struct.pack('!L', self.session_id)  # sessionID
-        buf += struct.pack('!L', self.transaction_id)  # transactionID
-        buf += struct.pack('!L', self.packet_id)  # packetID
-        buf += struct.pack('!L', payload_length)
+        buf = struct.pack("BBBB", 1, pdu_type, flags, 0)
+        buf += struct.pack("!L", self.session_id)  # sessionID
+        buf += struct.pack("!L", self.transaction_id)  # transactionID
+        buf += struct.pack("!L", self.packet_id)  # packetID
+        buf += struct.pack("!L", payload_length)
         return buf
 
     def encode(self):
-        buf = b''
+        buf = b""
         if self.type == agentx.AGENTX_OPEN_PDU:
             # timeout
-            buf += struct.pack('!BBBB', 5, 0, 0, 0)
+            buf += struct.pack("!BBBB", 5, 0, 0, 0)
             # agent OID
-            buf += struct.pack('!L', 0)
+            buf += struct.pack("!L", 0)
             # Agent Desc
-            buf += self.encode_octet('MyAgent')
+            buf += self.encode_octet("MyAgent")
 
         elif self.type == agentx.AGENTX_PING_PDU:
             # No extra data
@@ -132,15 +137,14 @@ class PDU(object):
             range_subid = 0
             timeout = 5
             priority = 127
-            buf += struct.pack('BBBB', timeout, priority, range_subid, 0)
+            buf += struct.pack("BBBB", timeout, priority, range_subid, 0)
             # Sub Tree
             buf += self.encode_oid(self.oid)
 
         elif self.type == agentx.AGENTX_RESPONSE_PDU:
-            buf += struct.pack('!LHH', 0, self.error, self.error_index)
+            buf += struct.pack("!LHH", 0, self.error, self.error_index)
             for value in self.values:
-                buf += self.encode_value(value['type'], value['name'],
-                                         value['value'])
+                buf += self.encode_value(value["type"], value["name"], value["value"])
 
         else:
             # Unsupported PDU type
@@ -156,27 +160,27 @@ class PDU(object):
 
     def decode_oid(self):
         try:
-            t = struct.unpack('!BBBB', self.decode_buf[:4])
+            t = struct.unpack("!BBBB", self.decode_buf[:4])
             self.decode_buf = self.decode_buf[4:]
             ret = {
-                'n_subid': t[0],
-                'prefix': t[1],
-                'include': t[2],
-                'reserved': t[3],
+                "n_subid": t[0],
+                "prefix": t[1],
+                "include": t[2],
+                "reserved": t[3],
             }
             sub_ids = []
-            if ret['prefix']:
+            if ret["prefix"]:
                 sub_ids = [1, 3, 6, 1]
-                sub_ids.append(ret['prefix'])
-            for i in range(ret['n_subid']):
-                t = struct.unpack('!L', self.decode_buf[:4])
+                sub_ids.append(ret["prefix"])
+            for i in range(ret["n_subid"]):
+                t = struct.unpack("!L", self.decode_buf[:4])
                 self.decode_buf = self.decode_buf[4:]
                 sub_ids.append(t[0])
-            oid = '.'.join(str(i) for i in sub_ids)
-            return oid, ret['include']
+            oid = ".".join(str(i) for i in sub_ids)
+            return oid, ret["include"]
         except Exception as e:
-            logger.exception('Invalid packing OID header')
-            logger.debug('%s' % pprint.pformat(self.decode_buf))
+            logger.exception("Invalid packing OID header")
+            logger.debug("%s" % pprint.pformat(self.decode_buf))
 
     def decode_search_range(self):
         start_oid, include = self.decode_oid()
@@ -193,115 +197,122 @@ class PDU(object):
 
     def decode_octet(self):
         try:
-            t = struct.unpack('!L', self.decode_buf[:4])
+            t = struct.unpack("!L", self.decode_buf[:4])
             l = t[0]
             self.decode_buf = self.decode_buf[4:]
             padding = 4 - (l % 4)
             buf = self.decode_buf[:l]
-            self.decode_buf = self.decode_buf[l + padding:]
+            self.decode_buf = self.decode_buf[l + padding :]
             return buf
         except Exception as e:
-            logger.exception('Invalid packing octet header')
+            logger.exception("Invalid packing octet header")
 
     def decode_value(self):
         try:
-            vtype, _ = struct.unpack('!HH', self.decode_buf[:4])
+            vtype, _ = struct.unpack("!HH", self.decode_buf[:4])
             self.decode_buf = self.decode_buf[4:]
         except Exception as e:
-            logger.exception('Invalid packing value header')
+            logger.exception("Invalid packing value header")
         oid, _ = self.decode_oid()
         if vtype in [
-                agentx.TYPE_INTEGER, agentx.TYPE_COUNTER32,
-                agentx.TYPE_GAUGE32, agentx.TYPE_TIMETICKS
+            agentx.TYPE_INTEGER,
+            agentx.TYPE_COUNTER32,
+            agentx.TYPE_GAUGE32,
+            agentx.TYPE_TIMETICKS,
         ]:
-            data = struct.unpack('!L', self.decode_buf[:4])
+            data = struct.unpack("!L", self.decode_buf[:4])
             data = data[0]
             self.decode_buf = self.decode_buf[4:]
         elif vtype in [agentx.TYPE_COUNTER64]:
-            data = struct.unpack('!Q', self.decode_buf[:8])
+            data = struct.unpack("!Q", self.decode_buf[:8])
             data = data[0]
             self.decode_buf = self.decode_buf[8:]
         elif vtype in [agentx.TYPE_OBJECTIDENTIFIER]:
             data, _ = self.decode_oid()
         elif vtype in [
-                agentx.TYPE_IPADDRESS, agentx.TYPE_OPAQUE,
-                agentx.TYPE_OCTETSTRING
+            agentx.TYPE_IPADDRESS,
+            agentx.TYPE_OPAQUE,
+            agentx.TYPE_OCTETSTRING,
         ]:
             data = self.decode_octet()
         elif vtype in [
-                agentx.TYPE_NULL, agentx.TYPE_NOSUCHOBJECT,
-                agentx.TYPE_NOSUCHINSTANCE, agentx.TYPE_ENDOFMIBVIEW
+            agentx.TYPE_NULL,
+            agentx.TYPE_NOSUCHOBJECT,
+            agentx.TYPE_NOSUCHINSTANCE,
+            agentx.TYPE_ENDOFMIBVIEW,
         ]:
             # No data
             data = None
         else:
-            logger.error('Unknown Type: %s' % vtype)
-        return {'type': vtype, 'name': oid, 'data': data}
+            logger.error("Unknown Type: %s" % vtype)
+        return {"type": vtype, "name": oid, "data": data}
 
     def decode_header(self):
         try:
-            t = struct.unpack('!BBBBLLLL', self.decode_buf[:20])
+            t = struct.unpack("!BBBBLLLL", self.decode_buf[:20])
             self.decode_buf = self.decode_buf[20:]
             ret = {
-                'version': t[0],
-                'pdu_type': t[1],
-                'pdu_type_name': agentx.PDU_TYPE_NAME[t[1]],
-                'flags': t[2],
-                'reserved': t[3],
-                'session_id': t[4],
-                'transaction_id': t[5],
-                'packet_id': t[6],
-                'payload_length': t[7],
+                "version": t[0],
+                "pdu_type": t[1],
+                "pdu_type_name": agentx.PDU_TYPE_NAME[t[1]],
+                "flags": t[2],
+                "reserved": t[3],
+                "session_id": t[4],
+                "transaction_id": t[5],
+                "packet_id": t[6],
+                "payload_length": t[7],
             }
             self.state = ret
-            self.type = ret['pdu_type']
-            self.session_id = ret['session_id']
-            self.packet_id = ret['packet_id']
-            self.transaction_id = ret['transaction_id']
-            self.decode_buf = self.decode_buf[:ret['payload_length']]
-            if ret['flags'] & 0x08:  # content present
+            self.type = ret["pdu_type"]
+            self.session_id = ret["session_id"]
+            self.packet_id = ret["packet_id"]
+            self.transaction_id = ret["transaction_id"]
+            self.decode_buf = self.decode_buf[: ret["payload_length"]]
+            if ret["flags"] & 0x08:  # content present
                 context = self.decode_octet()
-                logger.debug('Context: %s' % context)
+                logger.debug("Context: %s" % context)
             return ret
         except Exception as e:
-            logger.exception('Invalid packing: %d' % len(self.decode_buf))
-            logger.debug('%s' % pprint.pformat(self.decode_buf))
+            logger.exception("Invalid packing: %d" % len(self.decode_buf))
+            logger.debug("%s" % pprint.pformat(self.decode_buf))
 
     def decode(self, buf):
         self.set_decode_buf(buf)
         ret = self.decode_header()
-        if ret['pdu_type'] == agentx.AGENTX_RESPONSE_PDU:
+        if ret["pdu_type"] == agentx.AGENTX_RESPONSE_PDU:
             # Decode Response Header
-            t = struct.unpack('!LHH', self.decode_buf[:8])
+            t = struct.unpack("!LHH", self.decode_buf[:8])
             self.decode_buf = self.decode_buf[8:]
             self.response = {
-                'sysUpTime': t[0],
-                'error': t[1],
-                'error_name': agentx.ERROR_NAMES[t[1]],
-                'index': t[2],
+                "sysUpTime": t[0],
+                "error": t[1],
+                "error_name": agentx.ERROR_NAMES[t[1]],
+                "index": t[2],
             }
             # Decode VarBindList
             self.values = []
             while len(self.decode_buf):
                 self.values.append(self.decode_value())
 
-        elif ret['pdu_type'] == agentx.AGENTX_GET_PDU:
+        elif ret["pdu_type"] == agentx.AGENTX_GET_PDU:
             self.range_list = self.decode_search_range_list()
 
-        elif ret['pdu_type'] == agentx.AGENTX_GETNEXT_PDU:
+        elif ret["pdu_type"] == agentx.AGENTX_GETNEXT_PDU:
             self.range_list = self.decode_search_range_list()
 
-        elif ret['pdu_type'] == agentx.AGENTX_TESTSET_PDU:
+        elif ret["pdu_type"] == agentx.AGENTX_TESTSET_PDU:
             # Decode VarBindList
             self.values = []
             while len(self.decode_buf):
                 self.values.append(self.decode_value())
-        elif ret['pdu_type'] in [
-                agentx.AGENTX_COMMITSET_PDU, agentx.AGENTX_UNDOSET_PDU,
-                agentx.AGENTX_CLEANUPSET_PDU
+        elif ret["pdu_type"] in [
+            agentx.AGENTX_COMMITSET_PDU,
+            agentx.AGENTX_UNDOSET_PDU,
+            agentx.AGENTX_CLEANUPSET_PDU,
         ]:
             pass
         else:
             pdu_type_str = agentx.PDU_TYPE_NAME.get(
-                ret['pdu_type'], 'Unknown:' + str(ret['pdu_type']))
-            logger.error('Unsupported PDU type:' + pdu_type_str)
+                ret["pdu_type"], "Unknown:" + str(ret["pdu_type"])
+            )
+            logger.error("Unsupported PDU type:" + pdu_type_str)
diff --git a/vpp-snmp-agent.py b/vpp-snmp-agent.py
index fcaa377..1c070e9 100755
--- a/vpp-snmp-agent.py
+++ b/vpp-snmp-agent.py
@@ -13,9 +13,10 @@ except ImportError:
     print("ERROR: install argparse manually: sudo pip install argparse")
     sys.exit(2)
 
+
 def get_phy_by_sw_if_index(ifaces, sw_if_index):
     try:
-        for k,v in ifaces.items():
+        for k, v in ifaces.items():
             if v.sw_if_index == sw_if_index:
                 return v
     except:
@@ -25,7 +26,7 @@ def get_phy_by_sw_if_index(ifaces, sw_if_index):
 
 def get_lcp_by_host_sw_if_index(lcp, host_sw_if_index):
     try:
-        for k,v in lcp.items():
+        for k, v in lcp.items():
             if v.host_sw_if_index == host_sw_if_index:
                 return v
     except:
@@ -35,27 +36,27 @@ def get_lcp_by_host_sw_if_index(lcp, host_sw_if_index):
 
 def get_description_by_ifname(config, name):
     try:
-        if 'interfaces' in config:
-            for ifname, iface in config['interfaces'].items():
+        if "interfaces" in config:
+            for ifname, iface in config["interfaces"].items():
                 if ifname == name:
-                    return iface['description']
-                if 'sub-interfaces' in iface:
-                    for sub_id, sub_iface in iface['sub-interfaces'].items():
+                    return iface["description"]
+                if "sub-interfaces" in iface:
+                    for sub_id, sub_iface in iface["sub-interfaces"].items():
                         sub_ifname = "%s.%d" % (ifname, sub_id)
                         if name == sub_ifname:
-                            return sub_iface['description']
-        if 'loopbacks' in config:
-            for ifname, iface in config['loopbacks'].items():
+                            return sub_iface["description"]
+        if "loopbacks" in config:
+            for ifname, iface in config["loopbacks"].items():
                 if ifname == name:
-                    return iface['description']
-        if 'taps' in config:
-            for ifname, iface in config['taps'].items():
+                    return iface["description"]
+        if "taps" in config:
+            for ifname, iface in config["taps"].items():
                 if ifname == name:
-                    return iface['description']
-        if 'vxlan_tunnels' in config:
-            for ifname, iface in config['vxlan_tunnels'].items():
+                    return iface["description"]
+        if "vxlan_tunnels" in config:
+            for ifname, iface in config["vxlan_tunnels"].items():
                 if ifname == name:
-                    return iface['description']
+                    return iface["description"]
     except:
         pass
     return None
@@ -70,32 +71,31 @@ class MyAgent(agentx.Agent):
             try:
                 with open(args.config, "r") as f:
                     self.logger.info("Loading configfile %s" % args.config)
-                    self.config = yaml.load(f, Loader = yaml.FullLoader)
+                    self.config = yaml.load(f, Loader=yaml.FullLoader)
                     self.logger.debug("Config: %s" % self.config)
             except:
                 self.logger.error("Couldn't read config from %s" % args.config)
 
         try:
             self.logger.info("Connecting to VPP Stats Segment")
-            vppstat = VPPStats(socketname='/run/vpp/stats.sock', timeout=2)
+            vppstat = VPPStats(socketname="/run/vpp/stats.sock", timeout=2)
             vppstat.connect()
         except:
             self.logger.error("Could not connect to VPPStats segment")
             return False
 
         try:
-            vpp = VPPApi(clientname='vpp-snmp-agent')
+            vpp = VPPApi(clientname="vpp-snmp-agent")
             vpp.connect()
         except:
             self.logger.error("Could not connect to VPP API")
             return False
 
-        self.register('1.3.6.1.2.1.2.2.1')
-        self.register('1.3.6.1.2.1.31.1.1.1')
+        self.register("1.3.6.1.2.1.2.2.1")
+        self.register("1.3.6.1.2.1.31.1.1.1")
 
         return True
 
-
     def update(self):
         global vppstat, vpp, args
 
@@ -115,51 +115,61 @@ class MyAgent(agentx.Agent):
         ifaces = vpp.get_ifaces()
         lcp = vpp.get_lcp()
 
-        num_ifaces=len(ifaces)
-        num_vppstat=len(vppstat['/if/names'])
-        num_lcp=len(lcp)
+        num_ifaces = len(ifaces)
+        num_vppstat = len(vppstat["/if/names"])
+        num_lcp = len(lcp)
         self.logger.debug("LCP: %s" % (lcp))
-        self.logger.debug("Retrieved Interfaces: vppapi=%d vppstats=%d lcp=%d" % (num_ifaces, num_vppstat, num_lcp))
+        self.logger.debug(
+            "Retrieved Interfaces: vppapi=%d vppstats=%d lcp=%d"
+            % (num_ifaces, num_vppstat, num_lcp)
+        )
 
         if num_ifaces != num_vppstat:
-            self.logger.warning("Interfaces count mismatch: vppapi=%d vppstats=%d" % (num_ifaces, num_vppstat))
+            self.logger.warning(
+                "Interfaces count mismatch: vppapi=%d vppstats=%d"
+                % (num_ifaces, num_vppstat)
+            )
 
-        for i in range(len(vppstat['/if/names'])):
-            ifname = vppstat['/if/names'][i]
-            idx = 1000+i
+        for i in range(len(vppstat["/if/names"])):
+            ifname = vppstat["/if/names"][i]
+            idx = 1000 + i
 
-            ds.set('1.3.6.1.2.1.2.2.1.1.%u' % (idx), 'int', idx)
+            ds.set("1.3.6.1.2.1.2.2.1.1.%u" % (idx), "int", idx)
 
-            ifName=ifname
-            ifAlias=None
+            ifName = ifname
+            ifAlias = None
             try:
-                if self.config and ifname.startswith('tap'):
+                if self.config and ifname.startswith("tap"):
                     host_sw_if_index = ifaces[ifname].sw_if_index
                     lip = get_lcp_by_host_sw_if_index(lcp, host_sw_if_index)
                     if lip:
                         phy = get_phy_by_sw_if_index(ifaces, lip.phy_sw_if_index)
                         ifName = lip.host_if_name
-                        self.logger.debug("Setting ifName of %s to '%s'" % (ifname, ifName))
+                        self.logger.debug(
+                            "Setting ifName of %s to '%s'" % (ifname, ifName)
+                        )
                         if phy:
-                            ifAlias = "LCP %s (%s)" % (phy.interface_name,ifname)
-                            self.logger.debug("Setting ifAlias of %s to '%s'" % (ifname, ifAlias))
+                            ifAlias = "LCP %s (%s)" % (phy.interface_name, ifname)
+                            self.logger.debug(
+                                "Setting ifAlias of %s to '%s'" % (ifname, ifAlias)
+                            )
             except:
                 self.logger.debug("No config entry found for ifname %s" % (ifname))
                 pass
 
-            ds.set('1.3.6.1.2.1.2.2.1.2.%u' % (idx), 'str', ifName)
+            ds.set("1.3.6.1.2.1.2.2.1.2.%u" % (idx), "str", ifName)
 
             if ifname.startswith("loop"):
-                ds.set('1.3.6.1.2.1.2.2.1.3.%u' % (idx), 'int', 24)  # softwareLoopback
+                ds.set("1.3.6.1.2.1.2.2.1.3.%u" % (idx), "int", 24)  # softwareLoopback
             else:
-                ds.set('1.3.6.1.2.1.2.2.1.3.%u' % (idx), 'int', 6)   # ethermet-csmacd
+                ds.set("1.3.6.1.2.1.2.2.1.3.%u" % (idx), "int", 6)  # ethermet-csmacd
 
             mtu = 0
             if not ifname in ifaces:
                 self.logger.warning("Could not get MTU for interface %s", ifname)
             else:
                 mtu = ifaces[ifname].mtu[0]
-            ds.set('1.3.6.1.2.1.2.2.1.4.%u' % (idx), 'int', mtu)
+            ds.set("1.3.6.1.2.1.2.2.1.4.%u" % (idx), "int", mtu)
 
             speed = 0
             if ifname.startswith("loop") or ifname.startswith("tap"):
@@ -168,26 +178,30 @@ class MyAgent(agentx.Agent):
                 self.logger.warning("Could not get link speed for interface %s", ifname)
             else:
                 speed = ifaces[ifname].link_speed * 1000
-            if speed >= 2**32:
-                speed = 2**32 - 1
-            ds.set('1.3.6.1.2.1.2.2.1.5.%u' % (idx), 'gauge32', speed)
+            if speed >= 2 ** 32:
+                speed = 2 ** 32 - 1
+            ds.set("1.3.6.1.2.1.2.2.1.5.%u" % (idx), "gauge32", speed)
 
             mac = "00:00:00:00:00:00"
             if not ifname in ifaces:
-                self.logger.warning("Could not get PhysAddress for interface %s", ifname)
+                self.logger.warning(
+                    "Could not get PhysAddress for interface %s", ifname
+                )
             else:
                 mac = str(ifaces[ifname].l2_address)
-            ds.set('1.3.6.1.2.1.2.2.1.6.%u' % (idx), 'str', mac)
+            ds.set("1.3.6.1.2.1.2.2.1.6.%u" % (idx), "str", mac)
 
             admin_status = 3  # testing
             if not ifname in ifaces:
-                self.logger.warning("Could not get AdminStatus for interface %s", ifname)
+                self.logger.warning(
+                    "Could not get AdminStatus for interface %s", ifname
+                )
             else:
                 if int(ifaces[ifname].flags) & 1:
                     admin_status = 1  # up
                 else:
                     admin_status = 2  # down
-            ds.set('1.3.6.1.2.1.2.2.1.7.%u' % (idx), 'int', admin_status)
+            ds.set("1.3.6.1.2.1.2.2.1.7.%u" % (idx), "int", admin_status)
 
             oper_status = 3  # testing
             if not ifname in ifaces:
@@ -197,36 +211,124 @@ class MyAgent(agentx.Agent):
                     oper_status = 1  # up
                 else:
                     oper_status = 2  # down
-            ds.set('1.3.6.1.2.1.2.2.1.8.%u' % (idx), 'int', oper_status)
+            ds.set("1.3.6.1.2.1.2.2.1.8.%u" % (idx), "int", oper_status)
 
-            ds.set('1.3.6.1.2.1.2.2.1.9.%u' % (idx), 'ticks', 0)
-            ds.set('1.3.6.1.2.1.2.2.1.10.%u' % (idx), 'u32', vppstat['/if/rx'][:, i].sum_octets() % 2**32)
-            ds.set('1.3.6.1.2.1.2.2.1.11.%u' % (idx), 'u32', vppstat['/if/rx'][:, i].sum_packets() % 2**32)
-            ds.set('1.3.6.1.2.1.2.2.1.12.%u' % (idx), 'u32', vppstat['/if/rx-multicast'][:, i].sum_packets() % 2**32)
-            ds.set('1.3.6.1.2.1.2.2.1.13.%u' % (idx), 'u32', vppstat['/if/rx-no-buf'][:, i].sum() % 2**32)
-            ds.set('1.3.6.1.2.1.2.2.1.14.%u' % (idx), 'u32', vppstat['/if/rx-error'][:, i].sum() % 2**32)
+            ds.set("1.3.6.1.2.1.2.2.1.9.%u" % (idx), "ticks", 0)
+            ds.set(
+                "1.3.6.1.2.1.2.2.1.10.%u" % (idx),
+                "u32",
+                vppstat["/if/rx"][:, i].sum_octets() % 2 ** 32,
+            )
+            ds.set(
+                "1.3.6.1.2.1.2.2.1.11.%u" % (idx),
+                "u32",
+                vppstat["/if/rx"][:, i].sum_packets() % 2 ** 32,
+            )
+            ds.set(
+                "1.3.6.1.2.1.2.2.1.12.%u" % (idx),
+                "u32",
+                vppstat["/if/rx-multicast"][:, i].sum_packets() % 2 ** 32,
+            )
+            ds.set(
+                "1.3.6.1.2.1.2.2.1.13.%u" % (idx),
+                "u32",
+                vppstat["/if/rx-no-buf"][:, i].sum() % 2 ** 32,
+            )
+            ds.set(
+                "1.3.6.1.2.1.2.2.1.14.%u" % (idx),
+                "u32",
+                vppstat["/if/rx-error"][:, i].sum() % 2 ** 32,
+            )
 
-            ds.set('1.3.6.1.2.1.2.2.1.16.%u' % (idx), 'u32', vppstat['/if/tx'][:, i].sum_octets() % 2**32)
-            ds.set('1.3.6.1.2.1.2.2.1.17.%u' % (idx), 'u32', vppstat['/if/tx'][:, i].sum_packets() % 2**32)
-            ds.set('1.3.6.1.2.1.2.2.1.18.%u' % (idx), 'u32', vppstat['/if/tx-multicast'][:, i].sum_packets() % 2**32)
-            ds.set('1.3.6.1.2.1.2.2.1.19.%u' % (idx), 'u32', vppstat['/if/drops'][:, i].sum() % 2**32)
-            ds.set('1.3.6.1.2.1.2.2.1.20.%u' % (idx), 'u32', vppstat['/if/tx-error'][:, i].sum() % 2**32)
+            ds.set(
+                "1.3.6.1.2.1.2.2.1.16.%u" % (idx),
+                "u32",
+                vppstat["/if/tx"][:, i].sum_octets() % 2 ** 32,
+            )
+            ds.set(
+                "1.3.6.1.2.1.2.2.1.17.%u" % (idx),
+                "u32",
+                vppstat["/if/tx"][:, i].sum_packets() % 2 ** 32,
+            )
+            ds.set(
+                "1.3.6.1.2.1.2.2.1.18.%u" % (idx),
+                "u32",
+                vppstat["/if/tx-multicast"][:, i].sum_packets() % 2 ** 32,
+            )
+            ds.set(
+                "1.3.6.1.2.1.2.2.1.19.%u" % (idx),
+                "u32",
+                vppstat["/if/drops"][:, i].sum() % 2 ** 32,
+            )
+            ds.set(
+                "1.3.6.1.2.1.2.2.1.20.%u" % (idx),
+                "u32",
+                vppstat["/if/tx-error"][:, i].sum() % 2 ** 32,
+            )
 
-            ds.set('1.3.6.1.2.1.31.1.1.1.1.%u' % (idx), 'str', ifName)
-            ds.set('1.3.6.1.2.1.31.1.1.1.2.%u' % (idx), 'u32', vppstat['/if/rx-multicast'][:, i].sum_packets() % 2**32)
-            ds.set('1.3.6.1.2.1.31.1.1.1.3.%u' % (idx), 'u32', vppstat['/if/rx-broadcast'][:, i].sum_packets() % 2**32)
-            ds.set('1.3.6.1.2.1.31.1.1.1.4.%u' % (idx), 'u32', vppstat['/if/tx-multicast'][:, i].sum_packets() % 2**32)
-            ds.set('1.3.6.1.2.1.31.1.1.1.5.%u' % (idx), 'u32', vppstat['/if/tx-broadcast'][:, i].sum_packets() % 2**32)
+            ds.set("1.3.6.1.2.1.31.1.1.1.1.%u" % (idx), "str", ifName)
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.2.%u" % (idx),
+                "u32",
+                vppstat["/if/rx-multicast"][:, i].sum_packets() % 2 ** 32,
+            )
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.3.%u" % (idx),
+                "u32",
+                vppstat["/if/rx-broadcast"][:, i].sum_packets() % 2 ** 32,
+            )
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.4.%u" % (idx),
+                "u32",
+                vppstat["/if/tx-multicast"][:, i].sum_packets() % 2 ** 32,
+            )
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.5.%u" % (idx),
+                "u32",
+                vppstat["/if/tx-broadcast"][:, i].sum_packets() % 2 ** 32,
+            )
 
-            ds.set('1.3.6.1.2.1.31.1.1.1.6.%u' % (idx), 'u64', vppstat['/if/rx'][:, i].sum_octets())
-            ds.set('1.3.6.1.2.1.31.1.1.1.7.%u' % (idx), 'u64', vppstat['/if/rx'][:, i].sum_packets())
-            ds.set('1.3.6.1.2.1.31.1.1.1.8.%u' % (idx), 'u64', vppstat['/if/rx-multicast'][:, i].sum_packets())
-            ds.set('1.3.6.1.2.1.31.1.1.1.9.%u' % (idx), 'u64', vppstat['/if/rx-broadcast'][:, i].sum_packets())
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.6.%u" % (idx),
+                "u64",
+                vppstat["/if/rx"][:, i].sum_octets(),
+            )
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.7.%u" % (idx),
+                "u64",
+                vppstat["/if/rx"][:, i].sum_packets(),
+            )
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.8.%u" % (idx),
+                "u64",
+                vppstat["/if/rx-multicast"][:, i].sum_packets(),
+            )
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.9.%u" % (idx),
+                "u64",
+                vppstat["/if/rx-broadcast"][:, i].sum_packets(),
+            )
 
-            ds.set('1.3.6.1.2.1.31.1.1.1.10.%u' % (idx), 'u64', vppstat['/if/tx'][:, i].sum_octets())
-            ds.set('1.3.6.1.2.1.31.1.1.1.11.%u' % (idx), 'u64', vppstat['/if/tx'][:, i].sum_packets())
-            ds.set('1.3.6.1.2.1.31.1.1.1.12.%u' % (idx), 'u64', vppstat['/if/tx-multicast'][:, i].sum_packets())
-            ds.set('1.3.6.1.2.1.31.1.1.1.13.%u' % (idx), 'u64', vppstat['/if/tx-broadcast'][:, i].sum_packets())
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.10.%u" % (idx),
+                "u64",
+                vppstat["/if/tx"][:, i].sum_octets(),
+            )
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.11.%u" % (idx),
+                "u64",
+                vppstat["/if/tx"][:, i].sum_packets(),
+            )
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.12.%u" % (idx),
+                "u64",
+                vppstat["/if/tx-multicast"][:, i].sum_packets(),
+            )
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.13.%u" % (idx),
+                "u64",
+                vppstat["/if/tx-broadcast"][:, i].sum_packets(),
+            )
 
             speed = 0
             if ifname.startswith("loop") or ifname.startswith("tap"):
@@ -235,34 +337,65 @@ class MyAgent(agentx.Agent):
                 self.logger.warning("Could not get link speed for interface %s", ifname)
             else:
                 speed = int(ifaces[ifname].link_speed / 1000)
-            ds.set('1.3.6.1.2.1.31.1.1.1.15.%u' % (idx), 'gauge32', speed)
+            ds.set("1.3.6.1.2.1.31.1.1.1.15.%u" % (idx), "gauge32", speed)
 
-            ds.set('1.3.6.1.2.1.31.1.1.1.16.%u' % (idx), 'int', 2)   # Hardcode to false(2)
-            ds.set('1.3.6.1.2.1.31.1.1.1.17.%u' % (idx), 'int', 1)   # Hardcode to true(1)
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.16.%u" % (idx), "int", 2
+            )  # Hardcode to false(2)
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.17.%u" % (idx), "int", 1
+            )  # Hardcode to true(1)
 
             if self.config and not ifAlias:
                 try:
                     descr = get_description_by_ifname(self.config, ifname)
                     if descr:
-                        self.logger.debug("Setting ifAlias of %s to config description '%s'" % (ifname, descr))
+                        self.logger.debug(
+                            "Setting ifAlias of %s to config description '%s'"
+                            % (ifname, descr)
+                        )
                         ifAlias = descr
                 except:
                     pass
             if not ifAlias:
-                self.logger.debug("Setting ifAlias of %s to ifname %s" % (ifname, ifname))
+                self.logger.debug(
+                    "Setting ifAlias of %s to ifname %s" % (ifname, ifname)
+                )
                 ifAlias = ifname
-            ds.set('1.3.6.1.2.1.31.1.1.1.18.%u' % (idx), 'str', ifAlias)
-            ds.set('1.3.6.1.2.1.31.1.1.1.19.%u' % (idx), 'ticks', 0)  # Hardcode to Timeticks: (0) 0:00:00.00
+            ds.set("1.3.6.1.2.1.31.1.1.1.18.%u" % (idx), "str", ifAlias)
+            ds.set(
+                "1.3.6.1.2.1.31.1.1.1.19.%u" % (idx), "ticks", 0
+            )  # Hardcode to Timeticks: (0) 0:00:00.00
         return ds
 
+
 def main():
     global args
 
     parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
-    parser.add_argument('-a', dest='address', default="localhost:705", type=str, help="""Location of the SNMPd agent (unix-path or host:port), default localhost:705""")
-    parser.add_argument('-p', dest='period', type=int, default=30, help="""Period to poll VPP, default 30 (seconds)""")
-    parser.add_argument('-c', dest='config', type=str, help="""Optional vppcfg YAML configuration file, default empty""")
-    parser.add_argument('-d', dest='debug', action='store_true', help="""Enable debug, default False""")
+    parser.add_argument(
+        "-a",
+        dest="address",
+        default="localhost:705",
+        type=str,
+        help="""Location of the SNMPd agent (unix-path or host:port), default localhost:705""",
+    )
+    parser.add_argument(
+        "-p",
+        dest="period",
+        type=int,
+        default=30,
+        help="""Period to poll VPP, default 30 (seconds)""",
+    )
+    parser.add_argument(
+        "-c",
+        dest="config",
+        type=str,
+        help="""Optional vppcfg YAML configuration file, default empty""",
+    )
+    parser.add_argument(
+        "-d", dest="debug", action="store_true", help="""Enable debug, default False"""
+    )
 
     args = parser.parse_args()
     if args.debug:
@@ -281,5 +414,6 @@ def main():
 
     sys.exit(-1)
 
+
 if __name__ == "__main__":
     main()
diff --git a/vppapi.py b/vppapi.py
index b2a43ee..6b5f17e 100644
--- a/vppapi.py
+++ b/vppapi.py
@@ -1,7 +1,7 @@
-'''
+"""
 The functions in this file interact with the VPP API to retrieve certain
 interface metadata.
-'''
+"""
 
 from vpp_papi import VPPApiClient
 import os
@@ -13,12 +13,14 @@ import socket
 class NullHandler(logging.Handler):
     def emit(self, record):
         pass
-logger = logging.getLogger('agentx.vppapi')
+
+
+logger = logging.getLogger("agentx.vppapi")
 logger.addHandler(NullHandler())
 
 
-class VPPApi():
-    def __init__(self, address='/run/vpp/api.sock', clientname='vppapi-client'):
+class VPPApi:
+    def __init__(self, address="/run/vpp/api.sock", clientname="vppapi-client"):
         self.address = address
         self.connected = False
         self.clientname = clientname
@@ -28,28 +30,27 @@ class VPPApi():
         if self.connected:
             return True
 
-        vpp_json_dir = '/usr/share/vpp/api/'
+        vpp_json_dir = "/usr/share/vpp/api/"
 
         # construct a list of all the json api files
         jsonfiles = []
         for root, dirnames, filenames in os.walk(vpp_json_dir):
-            for filename in fnmatch.filter(filenames, '*.api.json'):
+            for filename in fnmatch.filter(filenames, "*.api.json"):
                 jsonfiles.append(os.path.join(root, filename))
 
         if not jsonfiles:
-            logger.error('no json api files found')
+            logger.error("no json api files found")
             return False
 
-        self.vpp = VPPApiClient(apifiles=jsonfiles,
-                                server_address=self.address)
+        self.vpp = VPPApiClient(apifiles=jsonfiles, server_address=self.address)
         try:
-            logger.info('Connecting to VPP')
+            logger.info("Connecting to VPP")
             self.vpp.connect(self.clientname)
         except:
             return False
 
         v = self.vpp.api.show_version()
-        logger.info('VPP version is %s' % v.version)
+        logger.info("VPP version is %s" % v.version)
 
         self.connected = True
         return True
diff --git a/vppstats.py b/vppstats.py
index 8ed142b..6716607 100644
--- a/vppstats.py
+++ b/vppstats.py
@@ -1,4 +1,4 @@
-'''
+"""
 VPPStats is a shared memory implementation that exposes the VPP statseg as
 an associative array. Counters can be accessed in either dimension.
 stat['/if/rx'] - returns 2D lists
@@ -30,7 +30,7 @@ Usage:
 
     stat.disconnect()
 
-'''
+"""
 
 import os
 import socket
@@ -40,31 +40,36 @@ from struct import Struct
 import time
 import re
 
+
 def recv_fd(sock):
-    '''Get file descriptor for memory map'''
-    fds = array.array("i")   # Array of ints
+    """Get file descriptor for memory map"""
+    fds = array.array("i")  # Array of ints
     _, ancdata, _, _ = sock.recvmsg(0, socket.CMSG_LEN(4))
     for cmsg_level, cmsg_type, cmsg_data in ancdata:
         if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
-            fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
+            fds.frombytes(cmsg_data[: len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
     return list(fds)[0]
 
-VEC_LEN_FMT = Struct('I')
+
+VEC_LEN_FMT = Struct("I")
+
+
 def get_vec_len(stats, vector_offset):
-    '''Equivalent to VPP vec_len()'''
+    """Equivalent to VPP vec_len()"""
     return VEC_LEN_FMT.unpack_from(stats.statseg, vector_offset - 8)[0]
 
+
 def get_string(stats, ptr):
-    '''Get a string from a VPP vector'''
+    """Get a string from a VPP vector"""
     namevector = ptr - stats.base
     namevectorlen = get_vec_len(stats, namevector)
     if namevector + namevectorlen >= stats.size:
-        raise IOError('String overruns stats segment')
-    return stats.statseg[namevector:namevector+namevectorlen-1].decode('ascii')
+        raise IOError("String overruns stats segment")
+    return stats.statseg[namevector : namevector + namevectorlen - 1].decode("ascii")
 
 
 class StatsVector:
-    '''A class representing a VPP vector'''
+    """A class representing a VPP vector"""
 
     def __init__(self, stats, ptr, fmt):
         self.vec_start = ptr - stats.base
@@ -76,28 +81,35 @@ class StatsVector:
         self.stats = stats
 
         if self.vec_start + self.vec_len * self.elementsize >= stats.size:
-            raise IOError('Vector overruns stats segment')
+            raise IOError("Vector overruns stats segment")
 
     def __iter__(self):
         with self.stats.lock:
-            return self.struct.iter_unpack(self.statseg[self.vec_start:self.vec_start +
-                                                        self.elementsize*self.vec_len])
+            return self.struct.iter_unpack(
+                self.statseg[
+                    self.vec_start : self.vec_start + self.elementsize * self.vec_len
+                ]
+            )
 
     def __getitem__(self, index):
         if index > self.vec_len:
-            raise IOError('Index beyond end of vector')
+            raise IOError("Index beyond end of vector")
         with self.stats.lock:
             if self.fmtlen == 1:
-                return self.struct.unpack_from(self.statseg, self.vec_start +
-                                               (index * self.elementsize))[0]
-            return self.struct.unpack_from(self.statseg, self.vec_start +
-                                           (index * self.elementsize))
+                return self.struct.unpack_from(
+                    self.statseg, self.vec_start + (index * self.elementsize)
+                )[0]
+            return self.struct.unpack_from(
+                self.statseg, self.vec_start + (index * self.elementsize)
+            )
+
+
+class VPPStats:
+    """Main class implementing Python access to the VPP statistics segment"""
 
-class VPPStats():
-    '''Main class implementing Python access to the VPP statistics segment'''
     # pylint: disable=too-many-instance-attributes
-    shared_headerfmt = Struct('QPQQPP')
-    default_socketname = '/run/vpp/stats.sock'
+    shared_headerfmt = Struct("QPQQPP")
+    default_socketname = "/run/vpp/stats.sock"
 
     def __init__(self, socketname=default_socketname, timeout=10):
         self.socketname = socketname
@@ -110,7 +122,7 @@ class VPPStats():
         self.statseg = 0
 
     def connect(self):
-        '''Connect to stats segment'''
+        """Connect to stats segment"""
         if self.connected:
             return
         sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
@@ -120,61 +132,64 @@ class VPPStats():
         sock.close()
 
         stat_result = os.fstat(mfd)
-        self.statseg = mmap.mmap(mfd, stat_result.st_size, mmap.PROT_READ, mmap.MAP_SHARED)
+        self.statseg = mmap.mmap(
+            mfd, stat_result.st_size, mmap.PROT_READ, mmap.MAP_SHARED
+        )
         os.close(mfd)
 
         self.size = stat_result.st_size
         if self.version != 2:
-            raise Exception('Incompatbile stat segment version {}'
-                            .format(self.version))
+            raise Exception("Incompatbile stat segment version {}".format(self.version))
 
         self.refresh()
         self.connected = True
 
     def disconnect(self):
-        '''Disconnect from stats segment'''
+        """Disconnect from stats segment"""
         if self.connected:
             self.statseg.close()
             self.connected = False
 
     @property
     def version(self):
-        '''Get version of stats segment'''
+        """Get version of stats segment"""
         return self.shared_headerfmt.unpack_from(self.statseg)[0]
 
     @property
     def base(self):
-        '''Get base pointer of stats segment'''
+        """Get base pointer of stats segment"""
         return self.shared_headerfmt.unpack_from(self.statseg)[1]
 
     @property
     def epoch(self):
-        '''Get current epoch value from stats segment'''
+        """Get current epoch value from stats segment"""
         return self.shared_headerfmt.unpack_from(self.statseg)[2]
 
     @property
     def in_progress(self):
-        '''Get value of in_progress from stats segment'''
+        """Get value of in_progress from stats segment"""
         return self.shared_headerfmt.unpack_from(self.statseg)[3]
 
     @property
     def directory_vector(self):
-        '''Get pointer of directory vector'''
+        """Get pointer of directory vector"""
         return self.shared_headerfmt.unpack_from(self.statseg)[4]
 
-    elementfmt = 'IQ128s'
+    elementfmt = "IQ128s"
 
     def refresh(self, blocking=True):
-        '''Refresh directory vector cache (epoch changed)'''
+        """Refresh directory vector cache (epoch changed)"""
         directory = {}
         directory_by_idx = {}
         while True:
             try:
                 with self.lock:
                     self.last_epoch = self.epoch
-                    for i, direntry in enumerate(StatsVector(self, self.directory_vector, self.elementfmt)):
-                        path_raw = direntry[2].find(b'\x00')
-                        path = direntry[2][:path_raw].decode('ascii')
+                    for i, direntry in enumerate(
+                        StatsVector(self, self.directory_vector, self.elementfmt)
+                    ):
+                        path_raw = direntry[2].find(b"\x00")
+                        path = direntry[2][:path_raw].decode("ascii")
                         directory[path] = StatsEntry(direntry[0], direntry[1])
                         directory_by_idx[i] = path
                     self.directory = directory
@@ -200,14 +215,12 @@ class VPPStats():
     def __iter__(self):
         return iter(self.directory.items())
 
-
     def set_errors(self, blocking=True):
-        '''Return dictionary of error counters > 0'''
+        """Return dictionary of error counters > 0"""
         if not self.connected:
             self.connect()
 
-        errors = {k: v for k, v in self.directory.items()
-                  if k.startswith("/err/")}
+        errors = {k: v for k, v in self.directory.items() if k.startswith("/err/")}
         result = {}
         for k in errors:
             try:
@@ -219,23 +232,23 @@ class VPPStats():
         return result
 
     def set_errors_str(self, blocking=True):
-        '''Return all errors counters > 0 pretty printed'''
-        error_string = ['ERRORS:']
+        """Return all errors counters > 0 pretty printed"""
+        error_string = ["ERRORS:"]
         error_counters = self.set_errors(blocking)
         for k in sorted(error_counters):
-            error_string.append('{:<60}{:>10}'.format(k, error_counters[k]))
-        return '%s\n' % '\n'.join(error_string)
+            error_string.append("{:<60}{:>10}".format(k, error_counters[k]))
+        return "%s\n" % "\n".join(error_string)
 
     def get_counter(self, name, blocking=True):
-        '''Alternative call to __getitem__'''
+        """Alternative call to __getitem__"""
         return self.__getitem__(name, blocking)
 
     def get_err_counter(self, name, blocking=True):
-        '''Alternative call to __getitem__'''
+        """Alternative call to __getitem__"""
         return self.__getitem__(name, blocking).sum()
 
     def ls(self, patterns):
-        '''Returns list of counters matching pattern'''
+        """Returns list of counters matching pattern"""
         # pylint: disable=invalid-name
         if not self.connected:
             self.connect()
@@ -245,20 +258,24 @@ class VPPStats():
         if self.last_epoch != self.epoch:
             self.refresh()
 
-        return [k for k, v in self.directory.items()
-                if any(re.match(pattern, k) for pattern in regex)]
+        return [
+            k
+            for k, v in self.directory.items()
+            if any(re.match(pattern, k) for pattern in regex)
+        ]
 
     def dump(self, counters, blocking=True):
-        '''Given a list of counters return a dictionary of results'''
+        """Given a list of counters return a dictionary of results"""
         if not self.connected:
             self.connect()
         result = {}
         for cnt in counters:
-            result[cnt] = self.__getitem__(cnt,blocking)
+            result[cnt] = self.__getitem__(cnt, blocking)
         return result
 
-class StatsLock():
-    '''Stat segment optimistic locking'''
+
+class StatsLock:
+    """Stat segment optimistic locking"""
 
     def __init__(self, stats):
         self.stats = stats
@@ -273,7 +290,7 @@ class StatsLock():
         self.release()
 
     def acquire(self, blocking=True, timeout=-1):
-        '''Acquire the lock. Await in progress to go false. Record epoch.'''
+        """Acquire the lock. Await in progress to go false. Record epoch."""
         self.epoch = self.stats.epoch
         if timeout > 0:
             start = time.monotonic()
@@ -286,46 +303,49 @@ class StatsLock():
         return True
 
     def release(self):
-        '''Check if data read while locked is valid'''
+        """Check if data read while locked is valid"""
         if self.stats.in_progress or self.stats.epoch != self.epoch:
-            raise IOError('Optimistic lock failed, retry')
+            raise IOError("Optimistic lock failed, retry")
 
     def locked(self):
-        '''Not used'''
+        """Not used"""
 
 
 class StatsCombinedList(list):
-    '''Column slicing for Combined counters list'''
+    """Column slicing for Combined counters list"""
 
     def __getitem__(self, item):
-        '''Supports partial numpy style 2d support. Slice by column [:,1]'''
+        """Supports partial numpy style 2d support. Slice by column [:,1]"""
         if isinstance(item, int):
             return list.__getitem__(self, item)
         return CombinedList([row[item[1]] for row in self])
 
+
 class CombinedList(list):
-    '''Combined Counters 2-dimensional by thread by index of packets/octets'''
+    """Combined Counters 2-dimensional by thread by index of packets/octets"""
 
     def packets(self):
-        '''Return column (2nd dimension). Packets for all threads'''
+        """Return column (2nd dimension). Packets for all threads"""
         return [pair[0] for pair in self]
 
     def octets(self):
-        '''Return column (2nd dimension). Octets for all threads'''
+        """Return column (2nd dimension). Octets for all threads"""
         return [pair[1] for pair in self]
 
     def sum_packets(self):
-        '''Return column (2nd dimension). Sum of all packets for all threads'''
+        """Return column (2nd dimension). Sum of all packets for all threads"""
         return sum(self.packets())
 
     def sum_octets(self):
-        '''Return column (2nd dimension). Sum of all octets for all threads'''
+        """Return column (2nd dimension). Sum of all octets for all threads"""
         return sum(self.octets())
 
+
 class StatsTuple(tuple):
-    '''A Combined vector tuple (packets, octets)'''
+    """A Combined vector tuple (packets, octets)"""
+
     def __init__(self, data):
-        self.dictionary = {'packets': data[0], 'bytes': data[1]}
+        self.dictionary = {"packets": data[0], "bytes": data[1]}
         super().__init__()
 
     def __repr__(self):
@@ -334,28 +354,32 @@ class StatsTuple(tuple):
     def __getitem__(self, item):
         if isinstance(item, int):
             return tuple.__getitem__(self, item)
-        if item == 'packets':
+        if item == "packets":
             return tuple.__getitem__(self, 0)
         return tuple.__getitem__(self, 1)
 
+
 class StatsSimpleList(list):
-    '''Simple Counters 2-dimensional by thread by index of packets'''
+    """Simple Counters 2-dimensional by thread by index of packets"""
 
     def __getitem__(self, item):
-        '''Supports partial numpy style 2d support. Slice by column [:,1]'''
+        """Supports partial numpy style 2d support. Slice by column [:,1]"""
         if isinstance(item, int):
             return list.__getitem__(self, item)
         return SimpleList([row[item[1]] for row in self])
 
+
 class SimpleList(list):
-    '''Simple counter'''
+    """Simple counter"""
 
     def sum(self):
-        '''Sum the vector'''
+        """Sum the vector"""
         return sum(self)
 
-class StatsEntry():
-    '''An individual stats entry'''
+
+class StatsEntry:
+    """An individual stats entry"""
+
     # pylint: disable=unused-argument,no-self-use
 
     def __init__(self, stattype, statvalue):
@@ -376,47 +400,48 @@ class StatsEntry():
             self.function = self.illegal
 
     def illegal(self, stats):
-        '''Invalid or unknown counter type'''
+        """Invalid or unknown counter type"""
         return None
 
     def scalar(self, stats):
-        '''Scalar counter'''
+        """Scalar counter"""
         return self.value
 
     def simple(self, stats):
-        '''Simple counter'''
+        """Simple counter"""
         counter = StatsSimpleList()
-        for threads in StatsVector(stats, self.value, 'P'):
-            clist = [v[0] for v in StatsVector(stats, threads[0], 'Q')]
+        for threads in StatsVector(stats, self.value, "P"):
+            clist = [v[0] for v in StatsVector(stats, threads[0], "Q")]
             counter.append(clist)
         return counter
 
     def combined(self, stats):
-        '''Combined counter'''
+        """Combined counter"""
         counter = StatsCombinedList()
-        for threads in StatsVector(stats, self.value, 'P'):
-            clist = [StatsTuple(cnt) for cnt in StatsVector(stats, threads[0], 'QQ')]
+        for threads in StatsVector(stats, self.value, "P"):
+            clist = [StatsTuple(cnt) for cnt in StatsVector(stats, threads[0], "QQ")]
             counter.append(clist)
         return counter
 
     def name(self, stats):
-        '''Name counter'''
+        """Name counter"""
         counter = []
-        for name in StatsVector(stats, self.value, 'P'):
+        for name in StatsVector(stats, self.value, "P"):
             if name[0]:
                 counter.append(get_string(stats, name[0]))
         return counter
 
-    SYMLINK_FMT1 = Struct('II')
-    SYMLINK_FMT2 = Struct('Q')
+    SYMLINK_FMT1 = Struct("II")
+    SYMLINK_FMT2 = Struct("Q")
+
     def symlink(self, stats):
-        '''Symlink counter'''
+        """Symlink counter"""
         b = self.SYMLINK_FMT2.pack(self.value)
         index1, index2 = self.SYMLINK_FMT1.unpack(b)
         name = stats.directory_by_idx[index1]
-        return stats[name][:,index2]
+        return stats[name][:, index2]
 
     def get_counter(self, stats):
-        '''Return a list of counters'''
+        """Return a list of counters"""
         if stats:
             return self.function(stats)