Understanding create and retrieve operations using Python client library

In the previous blog post, we discussed how to quickly set up and start using the NetApp® ONTAP® REST API Python client library (PCL) to start automating your storage. This post, Part 2, describes how to use the different Python client library methods to create, retrieve, update, and delete ONTAP objects (POST, GET, PATCH, and DELETE actions). You’ll see how easy it is to create ONTAP REST API automation using the Python client library. Also, a few Python client library sample scripts are available on GitHub for reference.

This blog post focuses on how to do a Create (POST) action and a Retrieve (GET) action using PCL.

Create an ONTAP object using the Python client library

The following code snippet was written using Python client library to create a volume.

# STEP 1:-
volume = Volume.from_dict({
'name': 'vol1',
'svm': {'name': 'vs1'},
'aggregates': [{'name': 'aggr1'}],
})

# STEP 2
try:
    volume.post(poll=True):
    print("Volume %s created Successfully" % volume.name)

# STEP 3
except NetAppRestError as error:
    print("Exception caught :" + str(error))

However, the code snippet won’t work as is. There are two things that you need to do before you start using the it.

First, you need to import the resources of the ONTAP object that you want to work with.

Second, you need to initialize the host connection using the netapp_ontap.host_connection.HostConnection object, which allows a client application to store credentials once and reuse them for each subsequent operation. Also, be sure to call the config.CONNECTION to set as the default connection for all API calls.

Now let’s examine the code step by step.

Step 1

# STEP 1:-
volume = Volume.from_dict({
'name': 'vol1',
'svm': {'name': 'vs1'},
'aggregates': [{'name': 'aggr1'}],
})

This step constructs a resource object using the  from_dict() method. This method deserializes a dictionary to a Resource type required for constructing a specific object.

The from_dict() method also does field validation of the object. It validates the enums, strings, and integers, and also verifies the parent keys on the object. If any invalid arguments are encountered, .

The arguments can be passed as a dictionary that contains a set of key/value pairs (input dict) or as a dictionary from a returned instance.

The volume object can also be instantiated in other ways:

  • By passing the argument as a list of parameters in the key-value format:

     from netapp_ontap.resources
     import Volume # Key Value arguments
     volume = Volume(name='vol1', svm={'name': 'vs1'}, aggregates=[{'name': 'aggr1'}])

  • by creating a dictionary and passing it to the volume object as a **kwargs:

     data = { 'name': 'vol1', 'svm': {'name': 'vs1'}, 'aggregates': [{'name': 'aggr1'}],}
     volume = Volume(**data)

Note

The Python client library provides a method called to_dict() to serialize or return dictionaries representing the objects and its subobjects. The following example shows how the to_dict() method can be used to return a dictionary:

  • Using the to_dict() method to retrieve object details in dictionary format

     volume = Volume.to_dict() 

  • Using the to_dict() method to retrieve specific object detail

     volume_name= volume.to_dict(only=['name'])

Step 2

# STEP 2
try:
volume.post(poll=True):
print("Volume %s created Successfully" % volume.name)

Returning to the example, in Step 2 we use the POST method to send this object to the host as a creation request.

There are quite a few arguments that can be used with the POST method. If the hydrate argument is set to True, after the response is received from the call, a GET call is made to refresh all fields of the object. If the poll argument is set to True, the call does not return until the asynchronous job on the host has completed. The poll_interval and poll_timeout arguments can be specified to set the frequency to query the jobs and how long the job status should be monitored. The **kwargs argument can be specified to send the query parameters to the host. Here are a few examples.

  • This example shows how to do a POST operation by sending poll as True and hydrate as True: 

      aggr.post(poll=True, hydrate=True)        

  • This example shows how to do a POST operation by sending along a query as well: 

     response = cluster.post(**params)

Step 3

# STEP 3
except NetAppRestError as error:
print("Exception caught :" + str(error))

Returning to the example, now we can create a “try ” “except” block to run the PCL  POST() method so that in case of a REST exception, the netapp_ontap.error.NetAppRestError exception object type that holds the HTTP response object can be handled within the client code.

Retrieve an ONTAP object using the Python client library

 The following code snippet retrieves a Volume object.

svm_name = input("Enter the SVM from which the Volumes need to be listed:-")
print("Getting Volume Details")
print("======================")

# STEP 1
try:
for volume in Volume.get_collection(**{"svm.name": svm_name},max_records=5):

# STEP 2
print("Volume Name = %s;  Volume UUID = %s" %
(volume.name, volume.uuid))

# STEP 3
except NetAppRestError as error:
print("Exception caught :" + str(error))

This example asks the user to give the SVM name from which to list the volumes.

Now let us turn our attention to Step 1.

# STEP 1
try:
for volume in Volume.get_collection(**{"svm.name": svm_name},max_records=5):

The get_collection() fetches a list of UUIDs of objects of Volume type that belong to the mentioned SVM from the host. This is a lazy fetch, making API calls only as necessary when the result of this call is iterated over. Here max_records is set to 5, so that the iteration over the collection causes an API call to be sent to the server once for every 5 records.

The get_collection() takes the following as argument: *args, which represents a parent key that is used to build the  /api/foos/{foo.name}/bars; connection (storage connection); max_records (maximum records to be returned); and **kwargs, any key/value pairs that can be sent as query parameters.

  • The following example shows how to query using the get_collection method based on specific fields:

     print(Volume.get_collection(fields='state', name=volume_names))

  • The following example shows how to query using the get_collection method to return all the fields:

     aggregates = list(Aggregate.get_collection(fields="*"))

  • The following example shows how to query using the get_collection method with the object passed as a dictionary:

     volume in Volume.get_collection(**{"svm.name": svm_name}):

  • The following example shows how to query using the get_collection method with the max_record and order_by parameters set:

     for event in EmsEvent.get_collection(max_records=10, order_by='time desc'):

The PCL allows the get method to fetch the details of the object from the host. It requires the keys (if any)) to be set. After returning, new or changed properties from the host are set on the instance.

volume1.get(fields='state,svm')
print("volume {} is {}".format(volume1.name, volume1.state))

Step 2

# STEP 2
print("Volume Name = %s;  Volume UUID = %s" %
(volume.name, volume.uuid))

Now that the collection is returned, we print the required object properties. In this case, we are retrieving the volume name and volume uuid.

Step 3

# STEP 3
except NetAppRestError as error:
print("Exception caught :" + str(error))

This step uses a try-except block to catch any REST API Errors.

More to come…

I hope that now you have an idea of how to create and retrieve ONTAP objects by using the ONTAP REST API Python client library. We have also seen how to use PCL methods like get_collection(), from_dict(), to_dict(), post(), and get(). In the next blog post, we will see how to do update and delete operations on ONTAP objects using Python client library. More PCL  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