Getting Started…

This three-part blog series describes the details of how to use netapp-ontap Python client libraries for REST API provided with NetApp® ONTAP® 9.6 and later for ease of automation. It discusses how to install and configure the netapp-ontap libraries, the different resources and objects available for programmers to use, how to handle the responses, and available debugging and exception-handling methodologies. A few sample scripts based on netapp-ontap Python client library are available on GitHub for reference as well.

In this first blog, we investigate how to install and use the netapp-ontap Python client library.

What is the ONTAP REST API Python client library?

The Python client library is a package you can use when writing scripts to access the ONTAP REST API. It provides support for several underlying services, including connection management, asynchronous request processing, and exception handling. By using the Python client library, you can quickly develop robust code to support the automation of your ONTAP deployments.

Installing Python client libraries for ONTAP REST API

Software requirements

Before installing the Python client library, you must make sure that the following packages are installed on your system:

  • Python 3.5 or later
  • Requests 2.21.0 or later
  • Marshmallow 3.2.1 or later

Prerequisites

Before you run the Python scripts, you must make sure that your environment is configured properly:

  • You can use pip or another Python management tool as appropriate for your environment.
  • The client workstation where the scripts run must have network access to the ONTAP cluster.

Also, you must have the following information ready:

  • IP address or hostname of the ONTAP cluster management LIF
  • Username and password of an ONTAP administrator account

Download PCL

The Python client library is available for download as the package netapp_ at the (PyPi) web site.

Installing and importing the package

  • You can install the package by using the pip utility. It’s also possible to install locally by downloading the .whl wheel file:

     pip install netapp-ontap

  • After installing the package, you can import the objects you need into your application:

    from netapp_ontap.resources import Volume, Snapshot  

Example

This example examines a script step by step to show how the Python client library can be used to do an operation on ONTAP objects.

##--------------------------------------------------------------------
# Description: Python script to create a volume.
# (C) Copyright 2020 NetApp, Inc
##--------------------------------------------------------------------

# Step 1:-
from netapp_ontap, import HostConnection, NetAppRestError, config, utils
import logging

# Step 2:-
logging.basicConfig(level=logging.DEBUG)
utils.DEBUG = 1

# Step 3:-
from netapp_ontap.resources import Volume

# Step 4:-
conn = HostConnection("1.1.1.1", username="admin",
password="mypassword", verify=False)

# Step 5:- Set connection as the default for all API calls
config.CONNECTION = conn

try:
# Step 6:- Create new volume object
   volume = Volume(name='vol1', svm={'name': 'vs1'}, aggregates=[{'name': 'aggr1'}])

# Step 7:- Do a post operation on the volume object.
response = volume.post(poll=True)

# Step 8:- Catch exceptions
except NetAppRestError:
    print("Error:- " % error.http_err_response.http_response.text)
    print("Exception caught :" + str(error))

Step 1

# Step 1:-
from netapp_ontap import HostConnection, NetAppRestError, config, utils 

This step imports the necessary modules to access the Python client library methods like HostConnection (to initiate connection to the storage); NetAppRestError (for handling REST errors); config (the global configuration options and related functions for the library); and utils (to access common utility functions used in the library).

Step 2

# Step 2:-
logging.basicConfig(level=logging.DEBUG)
utils.DEBUG = 1

Complete this step if you want to enable debugging while running the script. You can also set this by setting DEBUG=1 in the environment before executing your application. This causes the library to log the request and response for any failed API call. You can also set the LOG_ALL_API_CALLS flag.

Step 3 

# Step 3:-
from netapp_ontap.resources import Volume

Import the required ONTAP objects by importing the appropriate resources modules.

Step 4

# Step 4:-
conn = HostConnection("1.1.1.1", username="admin",
password="mypassword", verify=False)

The netapp_ontap.host_connection.HostConnection object allows a client application to store credentials once and reuse them for each subsequent operation. You can use the set_connection() function on a specific resource so that the connection is used for all actions on the resource. Also, use the get_connection() function to get the connection used by an object and use it for subsequent operations.

If it is required to send custom headers with the REST request, this can be done at the connection level by creating the header dictionary and passing the header while initializing the connection.

  • The following example code creates a custom header for SVM tunneling.

#Initialize a connection object with custom headers
 from netapp_ontap import config, HostConnection
 headers = {'X-Dot-SVM-Name': svm.name, 'X-Dot-SVM-UUID': svm.uuid}

 config.CONNECTION = HostConnection('myhost.mycompany.com', 'username', 'password', headers=headers)

Step 5

# Step 5:- Set connection as the default for all API calls
config.CONNECTION = conn

Set connection as the default for all API calls.

Step 6

# Step 6:- Create new volume object
volume = Volume(name='vol1', svm={'name': 'vs1'}, aggregates=[{'name': 'aggr1'}])

This step creates an instance of the resource you want to perform operations on.

A resource represents a snapshot of an object that exists on the host. Any variable number of arguments or a keyworded, variable-length argument list passed into the constructor will be set as properties of that instance. In this example, we have set the volume name, the SVM, and the aggregate it should belong to. Now we create a new Volume object to create a new volume with the minimum default space of 20MB. There are several ways this can be done, which we will discuss in the next blog.

Step 7

# Step 7:- Do a post operation on the volume object.
response = volume.post(poll=True)

Now we create the volume by doing a POST action. All POST, PATCH, and DELETE requests that take more than 2 seconds to complete are designed to run asynchronously. By default, an asynchronous request automatically polls the job. Control is returned to your script when a terminal state is reached (success or failure) or the configured timeout value expires. This behavior can be changed by setting the poll value to false.

I want to focus on the response we get from the POST action. A request always returns a netapp_ontap.response.NetAppResponse object that contains the details of the HTTP response. It contains information such as whether the response is an error or a job.

  • NetAppResponse object offers a method called poll, which waits for the job associated with the response to complete. For example:
  • NetAppResponse object also offers 2 instance variables: is_job and is_err.

is_job: This instance variable determines whether the response is a job. It returns True if the HTTP status code returned was 202, else it returns False. For example:

while response.is_job:
   try:
      response = response.poll(timeout=2500)

is_err: This instance variable examines to determine whether the response is an error. It returns True if the HTTP status code was 400 or greater, else it returns False.

resp = volume.get()
assert not resp.is_err

Step 8

# Step 8:- Catch exceptions
except NetAppRestError:
    print("Error:- " % error.http_err_response.http_response.text)
    print("Exception caught :" + str(error))

Exception is returned if a request returns an HTTP status code of 400 or greater. The netapp_ontap.error.NetAppRestError exception object type holds the HTTP response object so that the exception can be handled in the client code.

If you do not want to raise exceptions, you can set netapp_ontap.config.RAISE_API_ERRORS to false. It is possible to check the HTTP response from the netapp_ontap.response.NetAppResponse object and handle any errors within the code.

To be continued…

In this blog post, we have seen how to install and use the Python client library for ONTAP REST API. The  coming posts in the series will explain the different Python client library methods that are available to make the scripting super simple. And it will use these methods for executing CRUD operations (GET, POST, PATCH, and DELETE) to get a fuller picture of Python client library usage. More Python client library sample scripts are available for reference in GitHub. You can bring up a Lab on Demand instance to try out these scripts. Be sure to read the setup instructions (in the lod folder under the ontap-rest-python repository in GitHub) to start executing the scripts on the instance.

In this blog post, we haven’t covered every possible scenario, and we know that you’ll have questions and concerns, so please contact us at ng-ontap-restapi-queries@netapp.com, or connect with us through Slack. To report any issues, file them on the GitHub Issues page.

Part 1 > Part 2 > Part 3

Jacob Andathethu on EmailJacob Andathethu on Linkedin
Jacob Andathethu
Technical Marketing Engineer at NetApp
A dynamic professional with over 13 years of experience working in Data Storage Industry [NetApp and Dell-EMC]
Currently working as a Technical Marketing Engineer for Open Ecosystem Products in NetApp (Docker,Docker Swarm,Kubernetes, OpenShift).

Pin It on Pinterest