A few months ago I spent some time to make a tool for checking the status of various services on a network infrastructure. I tried to make the tool modular so it could support any vendor that has an API but I started with Arista since most of the infrastructure that I work on is Arista.

I used the Rich package to format everything into a nice table with colours, line etc. If you’re not already familiar with Rich, I highly recommend checking it out – it’s a fantastic tool for formatting command line text and making it easier to read.

Anyway, I made the tool, everything was going great, and I was receiving nice reports whenever I needed them. People also started using it and they liked it. Everything seemed to be going well until one day, I was asked to add a new device to the tool. I thought OK, that’s not a problem. All I need to do is add the new device to the inventory, and everything should be fine. Or so I thought.

I ran the script after adding the device but the output for some services for the new device was:

unable to render int; a string or other renderable object is required

instead of an output like: rich-table

hmmm 🤔, interesting. Why? Logically, it should work because the new box is Arista and it’s running EOS. To understand what’s causing the issue, I started with comparing the raw output of the same command just to make sure at least both device produce similar output:

JSON output snippet of device X:

    '169.254.96.29': {
    'description': 'site-b-rt03',
    'msgSent': 21111451,
    'inMsgQueue': 0,
    'prefixReceived': 12,
    'upDownTime': 1676722090.889669,
    'version': 4,
    'prefixAccepted': 12,
    'msgReceived': 17919108,
    'peerState': 'Established',
    'outMsgQueue': 0,
    'underMaintenance': False,
    'asn': '64512'
}

JSON output snippet of device Y:

'169.254.96.9': {
    'prefixReceived': 335,
    'description': 'TOR-A',
    'msgSent': 513051,
    'inMsgQueue': 0,
    'underMaintenance': False,
    'prefixInBest': 57,
    'upDownTime': 1677277045.425945,
    'version': 4,
    'msgReceived': 572874,
    'prefixAccepted': 58,
    'peerState': 'Established',
    'outMsgQueue': 0,
    'prefixInBestEcmp': 3,
    'asn': 64512
}

Both outputs seem fine but comparing line by line, you can see 'asn' value type for device Y is an integer but for device X it’s a string and going back to the error message, that seems to be the culprit: the Rich module is expecting a string for the input to render and complains when it’s given an integer (asn value is something that it renders for the output).

To make sure that this has nothing to do with the script or the Rich table module, I also compared the EOS version of both devices and sure enough the device Y was running on an older version of EOS, so this appears to be a change in API which has been fixed in newer EOS versions.

To validate the data, one could use Pydantic to create an schema and data types for variables, but for now all I did was to put a one line list comprehension like item = [str(i) for i in item] at the beginning of my Rich table function to get what I wanted.