Step 1: Login and authenticate with Python code
Postman is great to start interacting with and discovering APIs, but to automate and program the infrastructure, you need to build code that can be reused and applications that extend the fabric.
You've seen how Postman can generate code in Python and other programming languages. Now you'll build dedicated functions and classes based on the Postman generated code, and in the next Learning Lab you'll use those functions and classes to build Python applications. These functions and classes will authenticate and interact with the vManage REST API with GET
and POST
calls.
You can find complete code for the functions and the classes in the code for the learning lab Getting Started with Cisco SD-WAN GitHub repository.
Building the authentication function
In the Postman lab, you saw that the first step was to authenticate to the DevNet SD-WAN sandbox vManage instance. You will now use the Postman code generator for the authentication API call to build your first Python function.
First you need to specify the endpoint,
https://{{vmanage}}:{{port}}
and then the login resource,/j_security_check
. You will store each one of them in individual variables:- The
base_url_str
variable contains the vManage endpoint in string format. - The
login_action
variable contains the login resource.
- The
Next you need to specify the username and password and store it in another variable that we'll call
login_data
. This will be the payload data organized as key value pairs in JSON format that you send to the login resource.So far you have the three variables defined:
base_url_str = 'https://%s:8443/'%vmanage_ip login_action = '/j_security_check' login_data = {'j_username' : username, 'j_password' : password}
The endpoint and resource are split into two different variables. If either of them change, you only need to change them in one place.
Next you will combine these two variables to build the complete login URL. Name the variable
login_url
and define it as a combination ofbase_url_str
andlogin_action
. This defines the login URL as a combination of endpoint and resource and the payload as a JSON file containing thej_username
andj_password
values.Next you will use the
session
method of therequests
library to open a new session. Use the POST method of the session object to send the request to thelogin_url
, with a payload oflogin_data
. You don't want to check the authenticity of the self-signed certificate so theverify
option is set toFalse
.login_url = base_url_str + login_action sess = requests.session() login_response = sess.post(url=login_url, data=login_data, verify=False)
The function needs to determine if the login attempt was successful. A successful authentication returns a status of
200 OK
but does not return any data. However, the presence of an<html>
tag will indicate a failed attempt. If the authentication fails, Python will return a message notifying the user that theLogin Failed
and exit the function.if b'<html>' in login_response.content: print ("Login Failed") sys.exit(0)
Reviewing the complete authentication function
By combining all these components, you have built a Python function to login and authenticate to a Cisco SD-WAN vManage REST API. This function takes the following value as input: the vManage IP address, the username and password.
The following code shows an example of a complete authentication function:
def login(vmanage_ip, username, password):
"""Login to vmanage"""
base_url_str = 'https://%s:8443/'%vmanage_ip
login_action = '/j_security_check'
#Format data for loginForm
login_data = {'j_username' : username, 'j_password' : password}
#Url for posting login data
login_url = base_url_str + login_action
sess = requests.session()
#If the vmanage has a certificate signed by a trusted authority change verify to True
login_response = sess.post(url=login_url, data=login_data, verify=False)
if b'<html>' in login_response.content:
print ("Login Failed")
sys.exit(0)
In the next section you will build ßadditional Python functions for getting data from the API (get_request
) and posting and creating new data (post_request
).
Note: After you have completed this Learning Lab, you are welcome to experiment with adding more functions for
PUT
,DELETE
,PATCH
, and others. For the purposes of your application that we'll develop in the next Learning Lab, being able to GET and POST new data is enough.
Step 2: GET requests in Python
In this step you will create a new function that will GET data from the vManage REST API.
For the purposes of this Lab, the function name will be get_request()
. This function will receive two parameters as input: the vManage IP address and the resource from which you are trying to obtain the data. This resource will be called a mount_point
.
You need to define the URL to which you will issue your GET request. All the REST API resources can be found after
https://{{vmanage_ip}}:{{port}}/dataservice/
. With this information, build the url as follows:url = "https://%s:8443/dataservice/%s"%(vmanage_ip, mount_point)
The input two variables for the
get_request()
function,vmanage_ip
andmount_point
, are passed as string values in the process of building the URL.Use the
request
method to perform a GET on theurl
. The results of the request will be restored in a variable namedresponse
and returned to the user:response = requests.request("GET", url, verify=False) data = response.content return data
Note: In this Learning Lab example, you do not verify the authenticity of the SSL certificate. In a production environment you should always verify if the SSL certificate returned by the vManage instance is valid.
You can now combine these components to create the
get_request()
function:def get_request(vmanage_ip, mount_point): """GET request""" url = "https://%s:8443/dataservice/%s"%(vmanage_ip, mount_point) response = requests.request("GET", url, verify=False) data = response.content return data
You will use this function whenever you want to perform a GET request from the vManage REST API. Next, you will build a POST function that creates new data in the API.
Step 3: POST requests in Python
You've built two functions for the vManage REST API: login(vmanage_ip, username, password)
and get_request(vmanage_ip, mount_point)
. Next, you'll build the function to perform POST calls and create new data in the API. This function will be called post_request()
.
For the purposes of this Lab, the function name will be post_request()
. This function receives the following parameters as input:
- The vManage IP address
- The resource to which the POST call will be sent.
- The payload that will be sent to the endpoint.
- The
Content-Type
header that will be enforced asapplication/json
.
Build the URL to which the request will be sent. This variable is exactly the same as the one you used for the GET function. The resources that you can send the POST request to, are all to be found after
https://{{vmanage_ip}}:{{port}}/dataservice/
.The payload data that will be sent with the request is taken from the input of the function, and is JSON encoded and stored in the
payload
variable:def post_request(vmanage_ip, mount_point, payload, headers={'Content-Type': 'application/json'}): url = "https://%s:8443/dataservice/%s"%(vmanage_ip, mount_point) payload = json.dumps(payload)
Create the POST operation. Use the
request
and specify that this is a POST operation. You will also include the endpoint and resource represented by the URL you defined above. The actual data that will be sent with this call is stored in the payload variable, and theContent-Type
headers and the SSL verification is disabled. The result of the request is stored in theresponse
variable. Thejson()
method is called on the response object and the JSON format of the response is returned to the user.response = requests.request("POST", url, data=payload, headers=headers, verify=False) data = response.json() return data
You can now combine these components to create the
post_request()
function:def post_request(vmanage_ip, mount_point, payload, headers={'Content-Type': 'application/json'}): """POST request""" url = "https://%s:8443/dataservice/%s"%(vmanage_ip, mount_point) payload = json.dumps(payload) response = requests.request("POST", url, data=payload, headers=headers, verify=False) data = response.json() return data
Step 4: rest_api_lib Python class
You have now built three functions that you will re-use extensively in your interactions with the vManage REST API:
login()
get_request()
post_request()
In this step you will create your first Python class.
About Python classes
Classes in Python provide a method for bundling data and functionality. Creating a new class creates a new type of object that can then be instantiated. Each class instance can have attributes attached to it for state maintenance and methods for modifying its state.
The __init__
method is a reserved method in Python classes and is called a constructor. With it you can initialize the attributes of the class. self
represents the instance of a class and with it you can access the attributes and the methods of the class.
Constructing the rest_api_lib class.
You will initialize the constructor __init__
method with the attributes for the vManage IP address, an empty dictionary for the REST API session and you will also initialize the login
function.
Next, you will define the methods that the rest_api_lib
class will expose when an instance of it is created. To define the methods, use the functions that you defined for login
, get_request()
and post_request
.
You will need to make some adjustments to these functions to adapt to the Python class. Each method in a Python class needs to have the self
parameter passed as input. You will also preserve the session
that gets established after you login into the API and use this session in the other methods of the class.
When you combine these functions and parameters, the rest_api_lib
class code should be similar to the following:
Note: The following code sample may be missing some underscore characters. Refer to the code in the Getting Started with Cisco SD-WAN GitHub repository.
class rest_api_lib:
def __init__(self, vmanage_ip, username, password):
self.vmanage_ip = vmanage_ip
self.session = {}
self.login(self.vmanage_ip, username, password)
def login(self, vmanage_ip, username, password):
"""Login to vmanage"""
base_url_str = 'https://%s:8443/'%vmanage_ip
login_action = '/j_security_check'
#Format data for loginForm
login_data = {'j_username' : username, 'j_password' : password}
#Url for posting login data
login_url = base_url_str + login_action
url = base_url_str + login_url
sess = requests.session()
#If the vmanage has a certificate signed by a trusted authority change verify to True
login_response = sess.post(url=login_url, data=login_data, verify=False)
if b'<html>' in login_response.content:
print ("Login Failed")
sys.exit(0)
self.session[vmanage_ip] = sess
def get_request(self, mount_point):
"""GET request"""
url = "https://%s:8443/dataservice/%s"%(self.vmanage_ip, mount_point)
#print url
response = self.session[self.vmanage_ip].get(url, verify=False)
data = response.content
return data
def post_request(self, mount_point, payload, headers={'Content-Type': 'application/json'}):
"""POST request"""
url = "https://%s:8443/dataservice/%s"%(self.vmanage_ip, mount_point)
payload = json.dumps(payload)
print (payload)
response = self.session[self.vmanage_ip].post(url=url, data=payload, headers=headers, verify=False)
data = response.json()
return data
Summary
If you are overwhelmed by the amount of information in this Learning Lab, you may want to spend some time with the functions and the class you created so far on your own. Copy and paste the code into Python (.py
) files, run them in a Python interpreter and see the error messages you get. Try to solve the error messages and become comfortable with all the concepts you discussed in this Learning Lab.
Note: You can also find all the functions and the class created in this Learning Lab in the
functions
folder in the Getting Started with Cisco SD-WAN GitHub repository.
In the next Learning Lab in this module you will use this Python class as a foundation to build a CLI application that interacts with the vManage REST API, extracts data using GET requests, creates new data using POST requests and displays it to the user in an interactive manner.
No comments:
Post a Comment