Introducing the Python Client for eAPI (pyeapi)

The Arista EOS command API (eAPI) has been available in versions of EOS since the release of version 4.12.  It has proven to be an invaluable tool for building management plane applications, making it easy to develop solutions that interface with the device configuration and state information.  Building on the capabilities of eAPI, this article introduces the initial release of the Python Client for eAPI (pyeapi).

The Python Client for eAPI (pyeapi) is a language specific client to make working eAPI even easier.  It is designed to assist network engineers, operators and devops teams to build eAPI applications faster without having to deal with the specifics of the eAPI implementation.

The Python Client for eAPI is designed to run either locally on the EOS node or remotely using the HTTP/S transport capabilities of eAPI.  It provides an easy to use Python library for building robust management plane applications.

This article will provide an overview of how to install and get started using the Python Client for eAPI.

Installation

Installing the Python Client for eAPI is a straightforward process.  The most recent stable version of pyeapi is available at PyPi (https://pypi.python.org/pypi/pyeapi).  The most recent development versions are hosted on Github (http://github.com/arista-eosplus/pyeapi)

To install the client on your local machine simply use pip:

$ pip install pyeapi

Feeling a little more adventurous, the development version can be installed from Github:

$ git clone http://github.com/arista-eosplus/pyeapi
$ cd pyeapi
$ python setup.py install

Once installed, the next step is to create the eapi.conf file.

Configuring pyeapi

The Python Client for eAPI uses a configuration file to load the destination nodes settings.  The configuration file is an INI style file that can contain multiple nodes.  By default the Python Client for eAPI looks for the configuration file at ~/.eapi.conf.

Start by creating a new configuration file using the text editor of your choice.  Below is an example.

$ vi ~/.eapi.conf
[connection:veos01]
host: 192.168.1.16
username: eapi
password: password
transport: https

[connection:veos02]
host: 192.168.1.17
username: eapi
password: password
transport: https

The configuration example above defines two connections (veos01 and veos02) in the configuration file.  The connection name will be used to connect to the client.

Note: The connection syntax is important.  The connection name must be prepended with connection: otherwise it will not work.

The configuration file supports the following settings:

  • host – The IP address or FQDN of the remote device. If the host parameter is omitted then the connection name is used
  • username – The eAPI username to use for authentication (only required for http or https connections)
  • password – The eAPI password to use for authentication (only required for http or https connections)
  • enablepwd – The enable mode password if required by the destination node
  • transport – Configures the type of transport connection to use. The default value is http. Valid values are:
    • socket
    • http_local
    • http
    • https
  • port – Configures the port to use for the eAPI connection. A default port is used if this parameter is absent, based on the transport setting using the following values:
    • transport: http, default port: 80
    • transport: https, default port: 443
    • transport: https_local, default port: 8080
    • transport: socket, default port: n/a

Using pyeapi

The Python Client for eAPI is simple to use.  After the configuration is done, test using pyeapi in a Python interpreter or use in an application.  The example below demonstrates using pyeapi.

>>> import pyeapi
>>> node = pyeapi.connect_to('veos01')

In the above example, simply import pyeapi and connect to the node.  Notice the connect_to function specifies the name to connect to based on the configuration file.  The connection name is the string to the right of the colon in the section header.

Once the connection to the node is established, use the enable method to send show commands to the device and return the output. Below is an example of sending the ‘show version’ command.

>>> from pprint import pprint as pp
>>> pp(node.enable('show version'))
[{'command': 'show version',
'encoding': 'json',
'result': {u'architecture': u'i386',
u'bootupTimestamp': 1421765066.11,
u'hardwareRevision': u'',
u'internalBuildId': u'f590eed4-1e66-43c6-8943-cee0390fbafe',
u'internalVersion': u'4.14.5F-2209869.4145F',
u'memFree': 115496,
u'memTotal': 2028008,
u'modelName': u'vEOS',
u'serialNumber': u'',
u'systemMacAddress': u'00:0c:29:f5:d2:7d',
u'version': u'4.14.5F'}}]

In the example, the return from the enable method is a list of dictionary objects with each dictionary representing a response from the command.  Notice the dictionary has three keys: command, encoding and result.  Command is the command that was executed on the node, result is the output from the command and encoding is the type of encoding of the result (this will make more sense in the next example).

Since eAPI’s inception, not all commands have been fully converted to structured JSON output.  In the past this has meant that in order to return the output from the command, the calling function had to understand the encoding necessary otherwise the command would fail.   The Python Client for eAPI solves this problem as shown in the below example.

>>> pp(node.enable(['show version', 'show ip route']))
[{'command': 'show version',
'encoding': 'json',
'result': {u'architecture': u'i386',
u'bootupTimestamp': 1421765066.11,
u'hardwareRevision': u'',
u'internalBuildId': u'f590eed4-1e66-43c6-8943-cee0390fbafe',
u'internalVersion': u'4.14.5F-2209869.4145F',
u'memFree': 115628,
u'memTotal': 2028008,
u'modelName': u'vEOS',
u'serialNumber': u'',
u'systemMacAddress': u'00:0c:29:f5:d2:7d',
u'version': u'4.14.5F'}},
{'command': 'show ip route',
'encoding': 'text',
'result': {u'output': u'Codes: C - connected, S - static, K - kernel, \n       O - OSPF, IA - OSPF inter area, E1 - OSPF external type 1,\n       E2 - OSPF external type 2, N1 - OSPF NSSA external type 1,\n       N2 - OSPF NSSA external type2, B I - iBGP, B E - eBGP,\n       R - RIP, I - ISIS, A B - BGP Aggregate, A O - OSPF Summary,\n       NG - Nexthop Group Static Route \n\n C      192.168.1.0/24 is directly connected, Management1\n\n'}}]

In this example, we send to commands to the node (show version and show ip route).  The Python Client for eAPI is able to return both commands one in JSON encoding and one in text encoding.

We can also disable this behavior by specifying the strict keyword argument and the enable method will return an exception if one of the commands doesn’t supported the desired encoding.

>>> pp(node.enable(['show version', 'show ip route'], strict=True))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pyeapi/client.py", line 492, in enable
responses = self.run_commands(commands, encoding)
File "pyeapi/client.py", line 538, in run_commands
response = self._connection.execute(commands, encoding)
File "pyeapi/eapilib.py", line 350, in execute
response = self.send(request)
File "pyeapi/eapilib.py", line 305, in send
raise CommandError(_code, _message)
pyeapi.eapilib.CommandError: CLI command 3 of 3 'show ip route' failed: unconverted command

The Python Client for eAPI can also be use to send configuration commands to the device.  For this purpose use the config method on the node instance.

>>> node.config('hostname veos01')
[{}]

Notice with the call to config, the commands enable and configure do not need to be specified as the commands are automatically handled in the method call.  As with the enable method, the config method also supports sending multiple commands.

>>> node.config(['interface Ethernet4', 'description foo'])
[{}, {}]

In both cases, we get the output from the command which, if successful, is a blank dictionary.

Summary

Hopefully this introduction to the Python Client for eAPI provides enough information to help get starting writing awesome applications for EOS.  This article has touch on how to install the client library, configure nodes for use with the client library and send commands to the node.  The Python Client for eAPI provides substantially more features however we will save those for future articles.

About Arista EOS+ CS

Arista EOS+ CS is an organization that has been created to embrace, alongside our customers, the devops community. EOS+ CS remains focused on delivering technical solutions freely to the open source community for the purposes of advancing innovation around traditional network operational environments. The Arista EOS+ CS team contributes to a variety of open source projects and continues to actively engage in devops communities in support of building more advanced operational and development models that operate next generation massively scalable data center environments.