REST API - Getting Started Using Python

To get started with REST API, a sample script written in Python is discussed: rest_api_python_sample.zip. The script demonstrates how to interact with the following APIs:

  • POST Login
  • GET Client Properties
  • POST Client Properties

Supported Python Versions

The Commvault software supports the following Python versions:

  • Python 2.7
  • Python 3


The script uses the following libraries:

  • requests to make API calls.
  • sys to make system calls.
  • ElementTree to parse XML responses.
  • base64 to encode the password.

Running the Script

This script takes the following parameters:

  • server: Host name of the computer where the web server is installed.
  • username: Name of the CommCell user.
  • password: Plain text password for the user.

Use the following command to run the script:

python rest_api_python_sample.py server domain\username plain_text_password

Logging On

This part of the script logs on and obtains an authentication token. All API requests must contain an authentication token.


POST: http://<web server host name>:81/SearchSvc/CVWebService.svc/Login
Parameters: None
Body: XML request with the user and a base64 encoded password
Response: XML with an attribute "token"

The libraries are imported and the variables are set:

import requests
import sys
import xml.etree.ElementTree as ET
import base64

user = None
pwd = None
service = 'http://server:81/SearchSvc/CVWebService.svc/'

The username and password attributes in the <DM2ContentIndexing_CheckCredentialReq> element are used to pass in the user credentials:

#1. Login
if len(sys.argv) < 3:
   print ("Server name and username are required arguments")
server = sys.argv[1]
service = service.replace("server", server)
user = sys.argv[2]

loginReq = '<DM2ContentIndexing_CheckCredentialReq username="<<username>>" password="<<password>>" />'

if user is None:
   print ("Username is required")
   loginReq = loginReq.replace("<<username>>", user)

if len(sys.argv) > 3:
   pwd = sys.argv[3];

if pwd is None:
   loginReq = loginReq.replace("<<password>>", "")

The password is encoded in base64:

  • Python 1 and 2 example

    #encode password in base64
       loginReq = loginReq.replace("<<password>>", base64.b64encode(pwd))

  • Python 3 example

    #encode password in base64
       pwd = bytes(pwd, encoding='utf8')
       pwd = str(base64.b64encode(pwd), encoding='utf-8')
       loginReq = loginReq.replace("<<password>>", pwd)

The token is requested:

#Login request built. Send the request now:
r = requests.post(service + 'Login', data=loginReq)
token = None

The response is checked. If the request is successful, a token is returned.

#Check response code and check if the response has an attribute "token" set
if r.status_code == 200:
   root = ET.fromstring(r.text)
   if 'token' in root.attrib:
      token = root.attrib['token']
      print ("Login Successful")
      print ("Login Failed")
   print ('there was an error logging in')

#Login successful.

Getting the Client Properties

This part of the script returns the client properties for a client with a client ID equal to "2."

Note: If the client ID is not known, the GET Client API can be used to retrieve the clientId attribute.


GET: http://<web server host name>:81/SearchSvc/CVWebService.svc/client/{clientId}
Parameters: None
Body: None
Headers: Authtoken (the token received from the login request)

The client ID is set to "2":

#2. Get client props. Client Id is hard coded to 2.
clientId = "2"
clientPropsReq = service + "client/" + clientId

The token is sent with the request for the client properties:

#build headers with the received token
headers = {'Authtoken': token}
r = requests.get(clientPropsReq, headers=headers)
clientResp = r.text

The client name and host name are retrieved from the response. The client description and job priority are not mandatory, so if they exist in the response, they are retrieved:

#Parse response to get client name, host name and client description
client = ET.fromstring(clientResp)

activePhysicalNode = client.findall(".//ActivePhysicalNode")
print ("Client Name: " + activePhysicalNode[0].attrib["clientName"])
print ("Host Name: " + activePhysicalNode[0].attrib["hostName"])

cd = client.findall(".//clientProperties/client")
if 'clientDescription' in cd[0].attrib:
   print ("Client Desc: " + cd[0].attrib["clientDescription"])

clientProps = client.findall(".//clientProps")
if 'JobPriority' in clientProps[0].attrib:
   print ("Job Priority: " + clientProps[0].attrib["JobPriority"])

Posting the Client Properties

This part of the script updates the job priority.

Note: The XML request is hard coded in the sample script, but it can be read from a file to set the appropriate properties.


POST: http://<web server host name>:81/SearchSvc/CVWebService.svc/client/{clientId}
Parameters: None
Body: XML request to set the properties including the client properties to change
Headers: Authtoken (the token received from the login request)

The new job priority is set:

#3. Set client props
updateClientProps = '<App_SetClientPropertiesRequest><clientProperties><clientProps JobPriority="<<jobPriority>>"></clientProps></clientProperties></App_SetClientPropertiesRequest>'
updateClientProps = updateClientProps.replace("<<jobPriority>>", "7")

The request to update the job priority is sent:

#Fire the request and print output
r = requests.post(clientPropsReq,data=updateClientProps, headers=headers)
resp = r.text
print (resp)
respRoot = ET.fromstring(resp)
respEle = respRoot.findall(".//response")
errorCode = respEle[0].attrib["errorCode"]

if errorCode == "0":
   print ("Client properties set successfully")
   print ("Client properties could not be set. Error Code: " + errorCode)

Last modified: 4/8/2020 8:39:41 PM