Python, JSON and API’s – Part 1

So I understand what API’s do, but I never really understood how they can save me time or effort. Well, I think I just found a way. I’m just starting to roll out some out of band devices. These devices have serial ports which console in to our network equipment. Normally I would configure the devices, label the port, then create SecureCRT sessions for all the hosts and share them everyone. The SecureCRT portion is tedious and when people move things around out in the field, they never update the rest of the team. So the tool that saves our hide is out of date pretty much by the time I’m finished with documentation. Well, I think I found a way to 1) keep it all up to date 2) use an API. The out of band devices I’ll be using are Vertiv ACS 8000 series. They have a native API and the next few posts are all about writing some Python code to interact with an API and present some useful data (I hope). Here’s the plan…I’m going to build a web application (leaning towards Django, but we’ll see). That web app will have a list of all the serial ports. For example let’s say I have ACS device and on port7 is the device named WAN-RTR-1. The ACS device can automagically read the connected hostname so I know that will always be correct. So in the web app will be a list of all the serial ports. Using search I can look for the device I want. Listed is the device and all the info I need; IP address of the ACS box, hostname of the connected device, the status, the speed, etc. I want to have two buttons as well. One will download a SecureCRT session file and the second button will open the URL to the device.

The first challenge I came across was authenticating to the API. The ACS device supports base64 encoding or the JSON Web Token (JWT). I went with the JWT only because it seems easier to use. In the documentation there were examples of sending a username and password and receiving a token back. The example however was using Curl. I tested with Curl and it worked like a champ. How in the world do I do this with Python?? It took lots of trial and error, but here’s what I ended up with:

Figuring out how to send a POST via requests was the most difficult. I had tried other modules with varying success. The requests module ended up being the easiest way. The API was expecting the credentials to be sent in JSON format and we can do that with the headers. Finally we put it all together and give it a variable name of ‘response’.

Since I’m still learning I like to put lots of error checking in. Not necessarily in the code, that will come later. Checking that things are working like I expect them too. For example, add this to the end of the file above.

It will give you a code number and the associated reason. You should see 200 OK. Great, but I don’t see the token code like when I did a Curl. OK, time to work on that.

Let’s dissect this line a bit. json_data is just a variable name, nothing too hard there. JSON has a couple of options; load(s) and dump(s). Since we want to load the response to our POST, we’ll use that. The ‘response.text’ is the data stream of the response to the POST. The name must be response.text!!

Now we can simply print(json_data)

Excellent, we got the authentication token. According to the documentation each time we send an API request we need to send the token in the header. Specifically it needs to look exactly like this (and in JSON format):

OK, but how do we get a header to look like that?? Remember that JSON is in key-value pairs. If you specify the key, Python will return the value. So we assign a variable when Python sends the value back to use.

The first token above is the name of our variable. The second token in the brackets and single quotes is the key token in the JSON string.

So if we print ‘token’

Now all we have to do is add the new key value and pre-pend the token. We will assign that a variable of course since we will be calling it on every request to the API.