Pull Operations Description Notebook

<--- Back

Pull Operation Concepts

The DMTF CIM/XML Pull operations allow a WBEM client to break the monolithic instance operations for requests that deliver multiple objects (ex. EnumerateInstances) into multiple requests/responses executed as a sequence of requests to limit the size of individual responses.

The purpose and function and usage of these WBEM operations is defined on the pull operations concepts page in the pywbem documentation

Pull Enumerate Instances Enumeration Sequence

The Pull Enumerate Instances request operation sequence differs from the EnumerateInstances() request in that it consists of multiple of operations, an OpenEnumerateInstances() operation and corresponding PullInstancesWithPath() operations. The OpenEnumerateInstances() opens an enumeration sequence and optionally acquires instances from the server determined by the MaxObjectCount parameter. It returns a named tuple that defines the sequence, marks, the end of the sequence, and includes instances retrieved by the OpenEnumerateInstances() operation.

Subsequent PullEnumerateInstancesWithPath() operations retrieve more instances as defined by the MaxObjectCount parameter of the call until the end-of-sequence flag (result.eos) is received.

The OpenEnumerateInstances() method returns a Python named tuple with the components as defined in the concepts documentation:

  • eos - End-Of-Sequence Boolean flag indicating whether the server has more to instances/paths to deliver.
  • context - Opaque string that provides context between open, pull and close operations within a single enumeration sequence.
  • instances - A list of pywbem.CIMInstance objects for each CIM instance of a particular CIM class (and its subclasses). The CIM instance path is part of the returned instance objects and can be accessed via their path attribute returned for this request operation. The instances may be a partial or complete response depending on the result.eos flag.

The PullEnumerateInstancesWithPath() method returns a named tuple containing the same named elements as the OpenEnumerateInstances() above (eos, context, instances). Note that while the MaxObjectCount parameter is an option with the open request (the default is zero) it is a required parameter with the pull request.

The following code enumerates the instances of the specified CIM class with an open and subsequent pull requests and prints their instance paths in WBEM URI format (see pywbem.CIMInstanceName.__str__()), and the instance itself in MOF format (see pywbem.CIMInstance.tomof()) when all have been retrieved.

The example sets the maximum number of instances that will be retrieved for each request including the open (MaxObjectCount) at 100. Each response may return 100 or fewer instances.

In this code, the received results are accumulated into the insts list. They could also be processed directly after each response is received. The only caution is that if they are processed immediatly, the client must understand that the response sequence could end early and incomplete if an exception is received and the client must account for this incomplete response in its processing.

In [ ]:
import pywbem

# Global variables used by all examples:
server = 'http://localhost'
username = 'user'
password = 'password'
namespace = 'root/cimv2'

classname = 'PyWBEM_Person'
max_obj_cnt = 100

conn = pywbem.WBEMConnection(server, (username, password),
                             default_namespace=namespace,
                             no_verification=True)

try:
    result = conn.OpenEnumerateInstances(classname,
                                         MaxObjectCount=max_obj_cnt)
    insts = result.instances
    while not result.eos:
        result = conn.PullInstancesWithPath(result.context, max_obj_cnt)
        insts.extend(result.instances)
except pywbem.Error as exc:
    print('Operation failed: %s' % exc)
else:
    print('Retrieved %s instances' % (len(insts)))
    for inst in insts:
        print('path=%s' % inst.path)
        print(inst.tomof())

In this example, the connection has a default namespace set. This allows us to omit the namespace from the subsequent OpenEnumerateInstances() method.

This example also shows exception handling with pywbem: Pywbem wraps any exceptions that are considered runtime errors, and raises them as subclasses of pywbem.Error. Any other exceptions are considered programming errors. Therefore, the code above only needs to catch pywbem.Error.

Note that the creation of the pywbem.WBEMConnection object in the code above does not need to be protected by exception handling; its initialization code does not raise any pywbem runtime errors.

Pull Enumerate Paths Enumeration Sequence

The Pull Enumerate Paths operation parallels the Pull Enumerate Instances sequence except that it returns instance paths instead of instances.

The Pull Enumerate Paths request operation sequence differs from the EnumerateInstanceNames() request in that its consists of multiple of operations, an OpenEnumerateInstancePaths() operation and corresponding PullEnumerateInstancesPaths() operations. The OpenEnumerateInstances() opens an enumeration sequence and optionally acquires instance paths from the server determined by the MaxObjectCount parameter. It returns a named tuple that defines the sequence, marks, the end of the sequence, and includes instance paths retrieved by the OpenEnumerateInstancePaths() operation.

In [ ]:
# Global variables from first example are used

max_obj_cnt = 100

conn = pywbem.WBEMConnection(server, (username, password),
                             default_namespace=namespace,
                             no_verification=True)

try:
    result = conn.OpenEnumerateInstancePaths(classname,
                                             MaxObjectCount=max_obj_cnt)
    paths = result.paths
    while not result.eos:
        result = conn.PullInstancesPaths(result.context, max_obj_cnt)
        insts.extend(result.paths)
except pywbem.Error as exc:
    print('Operation failed: %s' % exc)
else:
    print('Retrieved %s instances' % (len(paths)))
    for path in paths:
        print('path=%s' % path)

Pull Associator Instances Enumeration Sequence

The Pull Associator Instances sequence is opened with an OpenAssociatorInstances() operation and corresponding PullInstancesWithPath()

The example below first gets instance names from a class that is part of an association and then uses one of those instances to execute the OpenAssociatorInstances operation. Normally the code should always include the full pattern of the Open followed by the Pull loop because the client cannot be certain how many objects will be returned in the response to the open request (the specification only requires that no more than MaxObjectCount be returned). In fact, some WBEM server implementations recommend that the client delay slightly between a response and subsequent pull to insure the server has more objects prepared to send.

The extra print statements in the example below record the the responses received.

In [ ]:
# Global variables from first example are used

max_obj_cnt = 100

conn = pywbem.WBEMConnection(server, (username, password),
                             default_namespace=namespace,
                             no_verification=True)

try:
    # Find an instance path for the source end of an association.
    source_paths = conn.EnumerateInstanceNames(classname)
    if source_paths:
        result = conn.OpenAssociatorInstances(source_paths[0],
                                              MaxObjectCount=max_obj_cnt)
        insts = result.instances
        while not result.eos:
            result = conn.PullInstancesWithPath(result.context, max_obj_cnt)
            insts.extend(result.instances)
    else:
        print('%s class has no instances and therefore no associations' %
              classname)
except pywbem.Error as exc:
    print('Operation failed: %s' % exc)
else:
    print('Retrieved %s instance(s)' % (len(insts)))
    for inst in insts:
        print('path=%s' % inst.path)
        print(inst.tomof())

Pull Associator Paths Enumeration Sequence

The Pull Associator Paths sequence is opened with an OpenAssociatorInstancePaths() operation and corresponding PullInstancesPaths()

The example below first gets instance names from a class that is part of an association and then uses one of those instances to execute the OpenReferenceInstances operation. Normally the code should always include the full pattern of the Open followed by the Pull loop because the client cannot be certain how many objects will be returned in the response to the open request (the specification only requires that no more than MaxObjectCount be returned). In fact, some WBEM server implementations recommend that the client delay slightly between a response and subsequent pull to insure the server has more objects prepared to send.

The extra print statements in the example below record the the responses received.

In [ ]:
# Global variables from first example are used

max_obj_cnt = 100

conn = pywbem.WBEMConnection(server, (username, password),
                             default_namespace=namespace,
                             no_verification=True)

try:
    # Find an instance path for the source end of an association.
    source_paths = conn.EnumerateInstanceNames(classname)
    if source_paths:
        result = conn.OpenAssociatorInstancePaths(source_paths[0],
                                                  MaxObjectCount=max_obj_cnt)
        paths = result.paths
        while not result.eos:
            result = conn.PullInstancePaths(result.context, max_obj_cnt)
            insts.extend(result.paths)
    else:
        print('%s class has no paths and therefore no associations' %
              classname)
except pywbem.Error as exc:
    print('Operation failed: %s' % exc)
else:
    print('Retrieved %s paths' % (len(paths)))
    for path in paths:
        print('path=%s' % path)

Pull Reference Instances Enumeration Sequence

The Pull ReferenceInstances sequence is opened with an OpenReferenceInstances() operation and corresponding PullInstancesWithPath()

The example below first gets instance names from a class that is part of an association and then uses one of those instances to execute the OpenReferenceInstances operation. Normally the code should always include the full pattern of the Open followed by the Pull loop because the client cannot be certain how many objects will be returned in the response to the open request (the specification only requires that no more than MaxObjectCount be returned). In fact, some WBEM server implementations recommend that the client delay slightly between a response and subsequent pull to insure the server has more objects prepared to send.

The extra print statements in the example below record the the responses received.

In [ ]:
# Global variables from first example are used

max_obj_cnt = 100

conn = pywbem.WBEMConnection(server, (username, password),
                             default_namespace=namespace,
                             no_verification=True)

try:
    # Find an instance path for the source end of an association.
    source_paths = conn.EnumerateInstanceNames(classname)
    if source_paths:
        result = conn.OpenReferenceInstances(source_paths[0],
                                             MaxObjectCount=max_obj_cnt)
        insts = result.instances
        while not result.eos:
            result = conn.PullInstancesWithPath(result.context, max_obj_cnt)
            insts.extend(result.instances)
    else:
        print('%s class has no instances and therefore no associations' %
              classname)
except pywbem.Error as exc:
    print('Operation failed: %s' % exc)
else:
    print('Retrieved %s instances\n' % (len(insts)))
    for inst in insts:
        print('path=%s\n' % inst.path)
        print(inst.tomof())

Pull Reference Paths Enumeration Sequence

The Pull Reference Paths sequence is opened with an OpenReferenceInstancePaths() operation and corresponding PullInstancesPaths()

The example below first gets instance names from a class that is part of an association and then uses one of those instances to execute the OpenReferenceInstances operation. Normally the code should always include the full pattern of the Open followed by the Pull loop because the client cannot be certain how many objects will be returned in the response to the open request (the specification only requires that no more than MaxObjectCount be returned). In fact, some WBEM server implementations recommend that the client delay slightly between a response and subsequent pull to insure the server has more objects prepared to send.

The extra print statements in the example below record the the responses received.

In [ ]:
# Global variables from first example are used

max_open_cnt = 0    # no instance paths returned on open
max_pull_cnt = 1    # zero or one instance path returned for each pull

conn = pywbem.WBEMConnection(server, (username, password),
                             default_namespace=namespace,
                             no_verification=True)

try:
    # Find an instance path for the source end of an association.
    source_paths = conn.EnumerateInstanceNames(classname)
    if source_paths:
        result = conn.OpenReferenceInstancePaths(source_paths[0],
                                                 MaxObjectCount=max_open_cnt)
        paths = result.paths
        print('Open eos=%s, context=%s, path count %s' %
              (result.eos, result.context, len(result.paths)))
        while not result.eos:
            result = conn.PullInstancePaths(result.context, max_pull_cnt)
            print('Pull eos=%s, context=%s, path count %s' %
                  (result.eos, result.context, len(result.paths)))
            paths.extend(result.paths)
    else:
        print('%s class has no paths and therefore no associations', classname)
except pywbem.Error as exc:
    print('Operation failed: %s' % exc)
else:
    print('Retrieved %s paths' % (len(paths)))
    for path in paths:
        print('path=%s' % path)

Pull Query Instances Enumeration Sequence

In [ ]:
The Pull Query Instances sequence is a parallel to the traditional ExecQuery operation. It requests that the
server execute a query defined by the query parameter and the query language parameters. These are NOT the same query
and query language as the other pull operations. The query language is normally WQL or the DMTF CQL.

The [`OpenQueryInstances()`](https://pywbem.readthedocs.io/en/latest/client.html#pywbem.WBEMConnection.OpenQueryInstances)
defines the query language and query required parameters.

This enumeration sequence uses the [`PullInstances()`](https://pywbem.readthedocs.io/en/latest/client.html#pywbem.WBEMConnection.PullInstances)
operation because the query function returns instances without paths.

The following example execute a query on the class Pywbem_Person with no where clause. This should return all 
instances of this class and its subclasses.
                                                       
The maximum instances that can be returned from each request is 10 (see max_object_cnt) although this is
lower that normally recommended for MaxObjectCnt.
                                                       
In [ ]:
# Global variables from first example are used

classname = 'Pywbem_Person'
max_object_cnt = 10

query_language = "DMTF:CQL"
query = 'Select  * from Pywbem_Person'

conn = pywbem.WBEMConnection(server, (username, password),
                             default_namespace=namespace,
                             no_verification=True)

try:
    result = conn.OpenQueryInstances(query_language, query,
                                     MaxObjectCount=max_object_cnt)
    insts = result.instances
    while not result.eos:
        result = conn.PullInstances(result.context, max_object_cnt)
        insts.extend(result.instances)
except pywbem.Error as exc:
    print('Operation failed: %s' % exc)

CloseEnumeration Request

The following is an example of using the CloseEnumeration request to terminate an enumeration sequence before it has completed. It requests zero responses from the open and terminates before the first pull. In this example, since the MaxObjectCount for the open is zero, no instances should be processed before the close is issued.

In [ ]:
# Global variables from first example are used

classname = 'CIM_ComputerSystem'

conn = pywbem.WBEMConnection(server, (username, password),
                             default_namespace=namespace,
                             no_verification=True)

try:
    result = conn.OpenEnumerateInstances(classname, MaxObjectCount=0)
    if result.eos:
        result = conn.CloseEnumeration(result.context)
    print('instance count = %s' % len(result.instances))
except pywbem.Error as exc:
    print('Operation failed: %s' % exc)