PyWBEM Client - Tutorial
This is a short tutorial about using the PyWBEM client library. It is intended to be enough to get people who know a bit about WBEM and CIM up and going.
Python code in this tutorial is shown using the interactive Python interpreter. The examples are meant to be run in order. The interpreter is started up like this:
$ python Python 2.6.6 (r266:84292, May 22 2015, 08:34:51) [GCC 4.4.7 20120313 (Red Hat 4.4.7-15)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>
The output of running the various examples has been reformatted for readability.
If you want to actually type the examples in, you need a WBEM server that implements the "CIM_Process" class. But you can also just read the tutorial instead, and get something out of it.
Once PyWBEM has been installed, the next stage is to learn how to make connections to WBEM servers. A client's connection to a WBEM server is represented by an instance of the Python class.
Creating a connection is quite simple. All that is required is a URL for the WBEM server, and a set of credentials. The following code creates an SSL-encrypted connection to wbem.example.com using a dummy user and dummy password:
>>> import pywbem >>> conn = pywbem.WBEMConnection('https://wbem.example.com', ('user', 'password'))
After creating a connection, various methods may be called on the WBEMConnection object, which causes remote calls to the WBEM server.
As usual in HTTP, there is no persistent TCP connection; the connectedness provided by this class is only conceptual. That is, the creation of the connection object does not cause any interaction with the WBEM server, and each subsequent operation performs an independent, state-less HTTP/HTTPS request, setting up and tearing down a new TCP connection.
Python Object and Data Model
One of the goals of PyWBEM is to have an understandable, well-integrated, and easy to use interface to CIM objects and operations. This is achieved by the thoughtful mapping of CIM objects such as instances, instance names, properties, classes, etc. to Python objects. There is no need to worry about the representation of CIM objects in XML, or anything related to HTTP/HTTPS.
PyWBEM represents CIM objects in a generic way. For example, CIM instances are represented as objects of the Python class CIMInstance, and CIM classes as objects of the Python class CIMClass. Thus, a CIM instance of class "CIM_Person" is represented as a Python object of type CIMInstance whose classname attribute is set to "CIM_Person".
This approach is simple and straight forward. However, first-class object aficionados might prefer Python objects of type CIM_Person for CIM instances of class "CIM_Person", instead. Such a first-class object representation has its own complexities, however, and is not currently supported by PyWBEM.
CIM Instances and Instance Names
The two fundamental Python classes in PyWBEM are and . A CIMInstance object is a representation of a CIM instance in a WBEM server, which in turn represents a physical or logical resource that is under management, or an aspect thereof. Examples for such managed resources are disk drives, temperature sensors, or network cards. The most interesting part of a CIM instance is the properties and values those properties take. The properties of a CIMInstance object can be accessed by treating the object as a Python dictionary:
>>> inst = pywbem.CIMInstance('CIM_Person') >>> inst['Firstname'] = 'Tim' >>> inst['Lastname'] = 'Potter' >>> print inst.items() [('Lastname', 'Potter'), ('Firstname', 'Tim')]
A CIMInstanceName object is a reference to a CIM instance in a WBEM server. It may specify the location of the WBEM server, the CIM namespace within the server, the CIM class within the namespace, and identifies the CIM instance within the class by means of its key property values. These key property values are called key bindings in CIM.
Similar to CIMInstance, the key bindings of a CIMInstanceName object can also be accessed by treating the object as a Python dictionary.
CIM Data Types
CIM has a number of data types that are mostly mapped to specific Python classes, and in some cases to built-in Python types such as bool, str/unicode or list.
See for details about the mapping.
CIM Instance Operations
PyWBEM supports all CIM operations to query, access and manipulate CIM instances. These CIM operations are all methods of the WBEMConnection class, and take Python CIM objects as parameters and return Python CIM objects as results.
The method returns a list of objects for each CIM instance of a particular CIM class (and its subclasses). The CIM instance name is part of the returned objects and can be accessed via their path attribute.
The following script fetches the CIM instances for every process running on the managed node and displays all the details for the first process returned:
>>> processes = conn.EnumerateInstances('CIM_Process') >>> print processes.items() [(u'Parameters', [u'init']), (u'CSName', u'nautilus3.asiapacific.cpqcorp.net'), (u'RealUserID', 0L), (u'OSName', u'Red Hat Enterprise Linux AS'), (u'Priority', 15L), (u'OtherExecutionDescription', None), (u'ProcessNiceValue', 0L), (u'Handle', u'1'), (u'Description', u'init'), (u'OSCreationClassName', u'CIM_OperatingSystem'), (u'WorkingSetSize', 0L), (u'Name', u'init'), (u'ProcessGroupID', 0L), (u'ProcessTTY', u'?'), (u'Caption', u'init'), (u'ProcessSessionID', 0L), (u'KernelModeTime', 7651000L), (u'ParentProcessID', u'0'), (u'ExecutionState', 6L), (u'CSCreationClassName', u'CIM_UnitaryComputerSystem'), (u'UserModeTime', 1000L), (u'CreationClassName', u'PG_UnixProcess')]
The method returns a list of objects which reference each instance of a particular CIM class (and its subclasses):
>>> process_names = conn.EnumerateInstanceNames('CIM_Process') >>> print process_names.items() [(u'CSName', u'nautilus3.asiapacific.cpqcorp.net'), (u'Handle', u'1'), (u'OSCreationClassName', u'CIM_OperatingSystem'), (u'CreationClassName', u'PG_UnixProcess'), (u'CSCreationClassName', u'CIM_UnitaryComputerSystem'), (u'OSName', u'Red Hat Enterprise Linux AS')]
Note that you cannot necessarily assume that the ordering of the returned results for the "CIM_Process" provider is the same for enumerating instance names as it is for enumerating instances. We just happen to be lucky in this case (which can be seen by the fact that all key bindings in the returned instance name have the same values as the same-named properties of the instance returned in the previous example).
Also note that the list of key bindings displayed for the instance name is a subset of the list of properties displayed for the instance.
CIMInstanceName objects are required as parameters for most PyWBEM calls as they uniquely identify a CIM instance on the managed node.
Calling returns a object, given a object that references the desired CIM instance:
>>> process0 = conn.GetInstance(process_names) >>> process0 == processes True
Again, for the comparison, we are relying on the fact that the first instance in the result set of EnumerateInstances() is for the same process as the first instance name in the result set of EnumerateInstanceNames().
For some CIM classes, it makes no sense to support deletion of their CIM instances. For some others, deletion of its CIM instances and consequently deletion of the represented managed resources is defined. Such a deletion semantics is typically not defined in the class definitions in the CIM Schema, but in their usage definitions in WBEM Management Profiles (see DMTF standard DSP1001). Often, management profiles that define a semantics for the deletion of managed resources, leave that optional for an implementation to support. The implementation for a CIM class in the WBEM server (aka CIM provider) thus may or may not support deletion of its instances and the represented managed resources.
The method takes a object and deletes the referenced CIM instance and the represented managed resource, or rejects the operation if deletion is not supported.
>>> conn.DeleteInstance(process_names) Traceback (most recent call last): File "
", line 1, in ? File ".../pywbem/cim_operations.py", line 1142, in DeleteInstance self.imethodcall( File ".../pywbem/cim_operations.py", line 673, in imethodcall raise CIMError(code, tt['DESCRIPTION']) pywbem.cim_operations.CIMError: (7, u'CIM_ERR_NOT_SUPPORTED: The requested operation is not supported')
As it turns out, the CIM provider for class "CIM_Process" in our WBEM server does not support the deletion of processes, so the WBEM server returns a failure with CIM status CIM_ERR_NOT_SUPPORTED.
PyWBEM maps CIM operation failures to the Python exception , and raises that in this case. The CIM status code is available as a numeric value in the error_code attribute of the exception object. See for a definition of the CIM status code values.
The creation of a CIM instance and in turn the creation of the underlying managed resource is achieved by calling the method. It takes a object as input, which specifies the class and the initial properties for the CIM instance to be created, and returns a object that references the new CIM instance.
Like for DeleteInstance(), the CIM provider on the WBEM server may or may not support the creation of new CIM instances.
Note that the CIMInstance object provided as input does not specfify an instance name. The determination of an instance name for the new CIM instance is completely left to the CIM provider in the WBEM server. For CIM classes with natural keys (key properties other than "InstanceID"), some CIM providers do honor initial values for some or all of the key properties provided in the input instance.
Existing CIM instances can be modified by having the values of properties changed. This is achieved using the method. It takes a object as input, which references the CIM instance to be modified with its path attribute, and specifies new values for the properties.
The PropertyList input parameter of the method specifies the names of the properties that are to be modified. If this parameter is not provided, all properties are modified. Those properties that are to be modified but have no new values specified in the input instance get their default values.
The values of key properties cannot be modified.
>>> process0['Priority'] = Uint32(10) >>> conn.ModifyInstance(process0, PropertyList=['Priority']) >>> process0m = conn.GetInstance(process0.path) >>> print process0m.items() [... (u'Priority', 10L), ...]
The method is used to execute a query in a particular query language in a namespace of the WBEM server.
There is a standard query language, the CIM Query Language (CQL, DMTF standard DSP0202), which is identified using the value "DMTF:CQL" for the QueryLanguage parameter. Another query language is the WBEM Query Language (WQL), identified using the value "WQL" for the QueryLanguage parameter. WQL has never been standardized, but is frequently implemented.
The query string in the chosen query language is then specified via the Query parameter of ExecQuery().
ExecQuery() returns a list of objects that form the query result.
CIM Method Invocation
CIM method invocations are quite easily done. The method is used to invoke a CIM method on a CIM instance, or on a CIM class (only for static CIM methods).
For invoking a CIM method on a CIM instance, InvokeMethod() takes a object referencing the CIM instance, as input. The input parameters for the CIM method are specified as keyword parameters to InvokeMethod().
InvokeMethod() returns a tuple consisting of the return value of the CIM method, and a dictionary with the output parameters of the CIM method.
CIM Association Operations
PyWBEM supports all CIM operations related to association classes:
CIM Class and Qualifier Operations
PyWBEM supports all CIM operations to query, access and manipulate CIM classes and qualifiers:
To help get developers, testers and hackers started with the PyWBEM client library, there is some more complete example code available to see how the basic functions operate: