Friday, 29 April 2016

Python for Network Engineers - Part 2 - Making REST calls

In this blog article we’re going to look at using the Python requests module to interface with REST APIs.  We’ll start off looking at a very simple example that’s available over the Internet.

Blog Series

Python for Network Engineers - Part 1 - Introduction
Python for Network Engineers - Part 2 - Making REST calls
Python for Network Engineers - Part 3 - Using Cisco Nexus NX-API
Python for Network Engineers - Part 4 - Using Arista EOS eAPI
Python for Network Engineers - Part 5 - Using Junos NETCONF interface
Python for Network Engineers - Part 6 - Using Cisco Nexus NETCONF interface
Python for Network Engineers - Part 7 - Using Palo Alto Networks XML API


Requests Module

The reason we’ll use requests is that it’s very easy to use.  For example it will read and use cookies without having to do anything and is very easy to use SSL, set authentication parameters, additional headers and parameters.  Also it’s very easy to handle the response data.

The disadvantage is that it’s not a built in library or commonly available in most default Python installs.  For that reason some people prefer to use urllib2, so there are no dependencies.  But if you decide to go down that route you’ll need to build your authentication header manually and read in and set cookies manually too.

However requests is easily installed using pip, yum or apt-get.  I recommend you use pip to ensure you’re using a recent version.

To setup requests on Ubuntu 16.04 then all you should need to do is:
apt-get install python-pip
pip install requests

RIPE who is

To start off then we’ll use the RIPE whois REST API as its freely available on the Internet, so all you’ll require is access to the internet, a copy of python and the requests module.

Example 1
The RIPE API is unauthenticated so to get started all we do is the following from the interactive prompt:
import requests
r = requests.get('http://rest.db.ripe.net/ripe/mntner/RIPE-DBM-MNT')
Our response object is now stored as ‘r’, so we can examine the response data with the following:
r.status_code
r.headers
r.text
You can also take a look at what other attributes are available with the following
dir(r)

Example 2
You’ll notice that in the above example the response data (ie r.text) was in XML format.  In the next example we’ll do the same query but ask the API to give use JSON data back by using the ‘Accept’ header.  Also, to make full use of the requests module, we’re now going to create a session object called ‘s’:
import requests, json
s = requests.session()
s.headers.update({'Accept': 'application/json'})
r = s.get('http://rest.db.ripe.net/ripe/mntner/RIPE-DBM-MNT')
You can now use some of the commands you learnt in Example 1 to look at the response object.  In particular you’ll notice that the response data is now in JSON format.
r.text
The request module will also convert the output into JSON and I can also pull out a single value from this easily.
r.json()
r.json()['objects']['object'][0]['attributes']['attribute'][0]['value']
Also we can print this is a more readable format like this:
print json.dumps(r.json(), indent=2)

Example 3
For the above examples we’ve just used a test URL.  So for the last example we’ll do a query against a specific IP range.  In this example we’ll:
  • Create a session object ‘s’
  • Insert a HTTP ‘Accept’ header
  • Set some HTTP parameters
  • Execute a HTTP GET and capture the response with ‘r’
  • print out the response data
import requests, json
s = requests.session()
s.headers.update({'Accept': 'application/json'})
params = {'query-string': '212.58.244.0'}
r = s.get('http://rest.db.ripe.net/search', params = params)
r.status_code
j = r.json()
print json.dumps(j,indent=2)
print json.dumps(j['objects']['object'][3],indent=2)
You can also take a look at how the params attribute affected our REST call by using the following:
r.url

In the next post we’ll look at the Cisco NX-API REST interface.

Resources



No comments:

Post a Comment