Package pywbem :: Module twisted_client
[frames] | no frames]

Source Code for Module pywbem.twisted_client

  1  # 
  2  # (C) Copyright 2005,2007 Hewlett-Packard Development Company, L.P. 
  3  # 
  4  # This library is free software; you can redistribute it and/or 
  5  # modify it under the terms of the GNU Lesser General Public 
  6  # License as published by the Free Software Foundation; either 
  7  # version 2.1 of the License, or (at your option) any later version. 
  8  # 
  9  # This program is distributed in the hope that it will be useful, but 
 10  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 12  # Lesser General Public License for more details. 
 13  # 
 14  # You should have received a copy of the GNU Lesser General Public 
 15  # License along with this program; if not, write to the Free Software 
 16  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 17  # 
 18  # Author: Tim Potter <tpot@hp.com> 
 19  # 
 20   
 21  """pywbem.twisted - WBEM client bindings for Twisted Python. 
 22   
 23  This module contains factory classes that produce WBEMClient instances 
 24  that perform WBEM requests over HTTP using the 
 25  twisted.protocols.http.HTTPClient base class. 
 26  """ 
 27   
 28  import string 
 29  import base64 
 30  from types import StringTypes 
 31  from datetime import datetime, timedelta 
 32  import urllib 
 33  try: 
 34      from elementtree.ElementTree import fromstring, tostring 
 35  except ImportError, arg: 
 36      from xml.etree.ElementTree import fromstring, tostring 
 37   
 38  from twisted.internet import reactor, protocol, defer 
 39  from twisted.web import http #, client, error 
 40   
 41  # TODO: Eww - we should get rid of the tupletree, tupleparse modules 
 42  # and replace with elementtree based code. 
 43  from pywbem import cim_types, cim_xml, cim_obj, tupleparse, tupletree 
 44  from pywbem.cim_obj import CIMClass, CIMClassName, CIMInstance, CIMInstanceName 
 45  from pywbem.cim_operations import CIMError 
 46  from pywbem.cim_types import CIMDateTime 
 47   
 48  __all__ = ['WBEMClient', 'WBEMClientFactory', 'EnumerateInstances', 
 49             'EnumerateInstanceNames', 'GetInstance', 'DeleteInstance', 
 50             'CreateInstance', 'ModifyInstance', 'EnumerateClassNames', 
 51             'EnumerateClasses', 'GetClass', 'Associators', 'AssociatorNames',    
 52             'References', 'ReferenceNames', 'InvokeMethod', 'ExecQuery'] 
 53   
54 -class WBEMClient(http.HTTPClient):
55 """A HTTPClient subclass that handles WBEM requests.""" 56 57 status = None 58
59 - def connectionMade(self):
60 """Send a HTTP POST command with the appropriate CIM over HTTP 61 headers and payload.""" 62 63 self.factory.request_xml = str(self.factory.payload) 64 65 self.sendCommand('POST', '/cimom') 66 67 self.sendHeader('Host', '%s:%d' % 68 (self.transport.addr[0], self.transport.addr[1])) 69 self.sendHeader('User-Agent', 'pywbem/twisted') 70 self.sendHeader('Content-length', len(self.factory.payload)) 71 self.sendHeader('Content-type', 'application/xml') 72 73 if self.factory.creds: 74 auth = base64.b64encode('%s:%s' % (self.factory.creds[0], 75 self.factory.creds[1])) 76 77 self.sendHeader('Authorization', 'Basic %s' % auth) 78 79 self.sendHeader('CIMOperation', str(self.factory.operation)) 80 self.sendHeader('CIMMethod', str(self.factory.method)) 81 self.sendHeader('CIMObject', str(self.factory.object)) 82 83 self.endHeaders() 84 85 # TODO: Figure out why twisted doesn't support unicode. An 86 # exception should be thrown by the str() call if the payload 87 # can't be converted to the current codepage. 88 89 self.transport.write(str(self.factory.payload))
90
91 - def handleResponse(self, data):
92 """Called when all response data has been received.""" 93 94 self.factory.response_xml = data 95 96 if self.status == '200': 97 self.factory.parseErrorAndResponse(data) 98 99 self.factory.deferred = None 100 self.transport.loseConnection()
101
102 - def handleStatus(self, version, status, message):
103 """Save the status code for processing when we get to the end 104 of the headers.""" 105 106 self.status = status 107 self.message = message
108
109 - def handleHeader(self, key, value):
110 """Handle header values.""" 111 112 if key == 'CIMError': 113 self.CIMError = urllib.unquote(value) 114 if key == 'PGErrorDetail': 115 self.PGErrorDetail = urllib.unquote(value)
116
117 - def handleEndHeaders(self):
118 """Check whether the status was OK and raise an error if not 119 using previously saved header information.""" 120 121 if self.status != '200': 122 123 if not hasattr(self, 'cimerror') or \ 124 not hasattr(self, 'errordetail'): 125 126 self.factory.deferred.errback( 127 CIMError(0, 'HTTP error %s: %s' % 128 (self.status, self.message))) 129 130 else: 131 132 self.factory.deferred.errback( 133 CIMError(0, '%s: %s' % (cimerror, errordetail)))
134
135 -class WBEMClientFactory(protocol.ClientFactory):
136 """Create instances of the WBEMClient class.""" 137 138 request_xml = None 139 response_xml = None 140 xml_header = '<?xml version="1.0" encoding="utf-8" ?>' 141
142 - def __init__(self, creds, operation, method, object, payload):
143 self.creds = creds 144 self.operation = operation 145 self.method = method 146 self.object = object 147 self.payload = payload 148 self.protocol = lambda: WBEMClient() 149 self.deferred = defer.Deferred()
150
151 - def clientConnectionFailed(self, connector, reason):
152 if self.deferred is not None: 153 reactor.callLater(0, self.deferred.errback, reason)
154
155 - def clientConnectionLost(self, connector, reason):
156 if self.deferred is not None: 157 reactor.callLater(0, self.deferred.errback, reason)
158
159 - def imethodcallPayload(self, methodname, localnsp, **kwargs):
160 """Generate the XML payload for an intrinsic methodcall.""" 161 162 param_list = [pywbem.IPARAMVALUE(x[0], pywbem.tocimxml(x[1])) 163 for x in kwargs.items()] 164 165 payload = cim_xml.CIM( 166 cim_xml.MESSAGE( 167 cim_xml.SIMPLEREQ( 168 cim_xml.IMETHODCALL( 169 methodname, 170 cim_xml.LOCALNAMESPACEPATH( 171 [cim_xml.NAMESPACE(ns) 172 for ns in string.split(localnsp, '/')]), 173 param_list)), 174 '1001', '1.0'), 175 '2.0', '2.0') 176 177 return self.xml_header + payload.toxml()
178
179 - def methodcallPayload(self, methodname, obj, namespace, **kwargs):
180 """Generate the XML payload for an extrinsic methodcall.""" 181 182 if isinstance(obj, CIMInstanceName): 183 184 path = obj.copy() 185 186 path.host = None 187 path.namespace = None 188 189 localpath = cim_xml.LOCALINSTANCEPATH( 190 cim_xml.LOCALNAMESPACEPATH( 191 [cim_xml.NAMESPACE(ns) 192 for ns in string.split(namespace, '/')]), 193 path.tocimxml()) 194 else: 195 localpath = cim_xml.LOCALCLASSPATH( 196 cim_xml.LOCALNAMESPACEPATH( 197 [cim_xml.NAMESPACE(ns) 198 for ns in string.split(namespace, '/')]), 199 obj) 200 201 def paramtype(obj): 202 """Return a string to be used as the CIMTYPE for a parameter.""" 203 if isinstance(obj, cim_types.CIMType): 204 return obj.cimtype 205 elif type(obj) == bool: 206 return 'boolean' 207 elif isinstance(obj, StringTypes): 208 return 'string' 209 elif isinstance(obj, (datetime, timedelta)): 210 return 'datetime' 211 elif isinstance(obj, (CIMClassName, CIMInstanceName)): 212 return 'reference' 213 elif isinstance(obj, (CIMClass, CIMInstance)): 214 return 'string' 215 elif isinstance(obj, list): 216 return paramtype(obj[0]) 217 raise TypeError('Unsupported parameter type "%s"' % type(obj))
218 219 def paramvalue(obj): 220 """Return a cim_xml node to be used as the value for a 221 parameter.""" 222 if isinstance(obj, (datetime, timedelta)): 223 obj = CIMDateTime(obj) 224 if isinstance(obj, (cim_types.CIMType, bool, StringTypes)): 225 return cim_xml.VALUE(cim_types.atomic_to_cim_xml(obj)) 226 if isinstance(obj, (CIMClassName, CIMInstanceName)): 227 return cim_xml.VALUE_REFERENCE(obj.tocimxml()) 228 if isinstance(obj, (CIMClass, CIMInstance)): 229 return cim_xml.VALUE(obj.tocimxml().toxml()) 230 if isinstance(obj, list): 231 if isinstance(obj[0], (CIMClassName, CIMInstanceName)): 232 return cim_xml.VALUE_REFARRAY([paramvalue(x) for x in obj]) 233 return cim_xml.VALUE_ARRAY([paramvalue(x) for x in obj]) 234 raise TypeError('Unsupported parameter type "%s"' % type(obj))
235 236 param_list = [cim_xml.PARAMVALUE(x[0], 237 paramvalue(x[1]), 238 paramtype(x[1])) 239 for x in kwargs.items()] 240 241 payload = cim_xml.CIM( 242 cim_xml.MESSAGE( 243 cim_xml.SIMPLEREQ( 244 cim_xml.METHODCALL(methodname, 245 localpath, 246 param_list)), 247 '1001', '1.0'), 248 '2.0', '2.0') 249 250 return self.xml_header + payload.toxml() 251
252 - def parseErrorAndResponse(self, data):
253 """Parse returned XML for errors, then convert into 254 appropriate Python objects.""" 255 256 xml = fromstring(data) 257 error = xml.find('.//ERROR') 258 259 if error is None: 260 self.deferred.callback(self.parseResponse(xml)) 261 return 262 263 try: 264 code = int(error.attrib['CODE']) 265 except ValueError: 266 code = 0 267 268 self.deferred.errback(CIMError(code, error.attrib['DESCRIPTION']))
269
270 - def parseResponse(self, xml):
271 """Parse returned XML and convert into appropriate Python 272 objects. Override in subclass""" 273 274 pass
275
276 -class EnumerateInstances(WBEMClientFactory):
277 """Factory to produce EnumerateInstances WBEM clients.""" 278
279 - def __init__(self, creds, classname, namespace='root/cimv2', **kwargs):
280 281 self.classname = classname 282 self.namespace = namespace 283 284 payload = self.imethodcallPayload( 285 'EnumerateInstances', 286 namespace, 287 ClassName=CIMClassName(classname), 288 **kwargs) 289 290 WBEMClientFactory.__init__( 291 self, 292 creds, 293 operation='MethodCall', 294 method='EnumerateInstances', 295 object=namespace, 296 payload=payload)
297
298 - def __repr__(self):
299 return '<%s(/%s:%s) at 0x%x>' % \ 300 (self.__class__, self.namespace, self.classname, id(self))
301
302 - def parseResponse(self, xml):
303 304 tt = [tupletree.xml_to_tupletree(tostring(x)) 305 for x in xml.findall('.//VALUE.NAMEDINSTANCE')] 306 307 return [tupleparse.parse_value_namedinstance(x) for x in tt]
308
309 -class EnumerateInstanceNames(WBEMClientFactory):
310 """Factory to produce EnumerateInstanceNames WBEM clients.""" 311
312 - def __init__(self, creds, classname, namespace='root/cimv2', **kwargs):
313 314 self.classname = classname 315 self.namespace = namespace 316 317 payload = self.imethodcallPayload( 318 'EnumerateInstanceNames', 319 namespace, 320 ClassName=CIMClassName(classname), 321 **kwargs) 322 323 WBEMClientFactory.__init__( 324 self, 325 creds, 326 operation='MethodCall', 327 method='EnumerateInstanceNames', 328 object=namespace, 329 payload=payload)
330
331 - def __repr__(self):
332 return '<%s(/%s:%s) at 0x%x>' % \ 333 (self.__class__, self.namespace, self.classname, id(self))
334
335 - def parseResponse(self, xml):
336 337 tt = [tupletree.xml_to_tupletree(tostring(x)) 338 for x in xml.findall('.//INSTANCENAME')] 339 340 names = [tupleparse.parse_instancename(x) for x in tt] 341 342 [setattr(n, 'namespace', self.namespace) for n in names] 343 344 return names
345
346 -class GetInstance(WBEMClientFactory):
347 """Factory to produce GetInstance WBEM clients.""" 348
349 - def __init__(self, creds, instancename, namespace='root/cimv2', **kwargs):
350 351 self.instancename = instancename 352 self.namespace = namespace 353 354 payload = self.imethodcallPayload( 355 'GetInstance', 356 namespace, 357 InstanceName=instancename, 358 **kwargs) 359 360 WBEMClientFactory.__init__( 361 self, 362 creds, 363 operation='MethodCall', 364 method='GetInstance', 365 object=namespace, 366 payload=payload)
367
368 - def __repr__(self):
369 return '<%s(/%s:%s) at 0x%x>' % \ 370 (self.__class__, self.namespace, self.instancename, id(self))
371
372 - def parseResponse(self, xml):
373 374 tt = tupletree.xml_to_tupletree( 375 tostring(xml.find('.//INSTANCE'))) 376 377 return tupleparse.parse_instance(tt)
378
379 -class DeleteInstance(WBEMClientFactory):
380 """Factory to produce DeleteInstance WBEM clients.""" 381
382 - def __init__(self, creds, instancename, namespace='root/cimv2', **kwargs):
383 384 self.instancename = instancename 385 self.namespace = namespace 386 387 payload = self.imethodcallPayload( 388 'DeleteInstance', 389 namespace, 390 InstanceName=instancename, 391 **kwargs) 392 393 WBEMClientFactory.__init__( 394 self, 395 creds, 396 operation='MethodCall', 397 method='DeleteInstance', 398 object=namespace, 399 payload=payload)
400
401 - def __repr__(self):
402 return '<%s(/%s:%s) at 0x%x>' % \ 403 (self.__class__, self.namespace, self.instancename, id(self))
404
405 -class CreateInstance(WBEMClientFactory):
406 """Factory to produce CreateInstance WBEM clients.""" 407 408 # TODO: Implement __repr__ method 409
410 - def __init__(self, creds, instance, namespace='root/cimv2', **kwargs):
411 412 payload = self.imethodcallPayload( 413 'CreateInstance', 414 namespace, 415 NewInstance=instance, 416 **kwargs) 417 418 WBEMClientFactory.__init__( 419 self, 420 creds, 421 operation='MethodCall', 422 method='CreateInstance', 423 object=namespace, 424 payload=payload)
425
426 - def parseResponse(self, xml):
427 428 tt = tupletree.xml_to_tupletree( 429 tostring(xml.find('.//INSTANCENAME'))) 430 431 return tupleparse.parse_instancename(tt)
432
433 -class ModifyInstance(WBEMClientFactory):
434 """Factory to produce ModifyInstance WBEM clients.""" 435 436 # TODO: Implement __repr__ method 437
438 - def __init__(self, creds, instancename, instance, namespace='root/cimv2', 439 **kwargs):
440 441 wrapped_instance = CIMNamedInstance(instancename, instance) 442 443 payload = self.imethodcallPayload( 444 'ModifyInstance', 445 namespace, 446 ModifiedInstance=wrapped_instance, 447 **kwargs) 448 449 WBEMClientFactory.__init__( 450 self, 451 creds, 452 operation='MethodCall', 453 method='ModifyInstance', 454 object=namespace, 455 payload=payload)
456
457 -class EnumerateClassNames(WBEMClientFactory):
458 """Factory to produce EnumerateClassNames WBEM clients.""" 459
460 - def __init__(self, creds, namespace='root/cimv2', **kwargs):
461 462 self.localnsp = namespace 463 464 payload = self.imethodcallPayload( 465 'EnumerateClassNames', 466 namespace, 467 **kwargs) 468 469 WBEMClientFactory.__init__( 470 self, 471 creds, 472 operation='MethodCall', 473 method='EnumerateClassNames', 474 object=namespace, 475 payload=payload)
476
477 - def __repr__(self):
478 return '<%s(/%s) at 0x%x>' % \ 479 (self.__class__, self.namespace, id(self))
480
481 - def parseResponse(self, xml):
482 483 tt = [tupletree.xml_to_tupletree(tostring(x)) 484 for x in xml.findall('.//CLASSNAME')] 485 486 return [tupleparse.parse_classname(x) for x in tt]
487
488 -class EnumerateClasses(WBEMClientFactory):
489 """Factory to produce EnumerateClasses WBEM clients.""" 490
491 - def __init__(self, creds, namespace='root/cimv2', **kwargs):
492 493 self.localnsp = namespace 494 self.namespace = namespace 495 496 payload = self.imethodcallPayload( 497 'EnumerateClasses', 498 namespace, 499 **kwargs) 500 501 WBEMClientFactory.__init__( 502 self, 503 creds, 504 operation='MethodCall', 505 method='EnumerateClasses', 506 object=namespace, 507 payload=payload)
508
509 - def __repr__(self):
510 return '<%s(/%s) at 0x%x>' % \ 511 (self.__class__, self.namespace, id(self))
512
513 - def parseResponse(self, xml):
514 515 tt = [tupletree.xml_to_tupletree(tostring(x)) 516 for x in xml.findall('.//CLASS')] 517 518 return [tupleparse.parse_class(x) for x in tt]
519
520 -class GetClass(WBEMClientFactory):
521 """Factory to produce GetClass WBEM clients.""" 522
523 - def __init__(self, creds, classname, namespace='root/cimv2', **kwargs):
524 525 self.classname = classname 526 self.namespace = namespace 527 528 payload = self.imethodcallPayload( 529 'GetClass', 530 namespace, 531 ClassName=CIMClassName(classname), 532 **kwargs) 533 534 WBEMClientFactory.__init__( 535 self, 536 creds, 537 operation='MethodCall', 538 method='GetClass', 539 object=namespace, 540 payload=payload)
541
542 - def __repr__(self):
543 return '<%s(/%s:%s) at 0x%x>' % \ 544 (self.__class__, self.namespace, self.classname, id(self))
545
546 - def parseResponse(self, xml):
547 548 tt = tupletree.xml_to_tupletree( 549 tostring(xml.find('.//CLASS'))) 550 551 return tupleparse.parse_class(tt)
552
553 -class Associators(WBEMClientFactory):
554 """Factory to produce Associators WBEM clients.""" 555 556 # TODO: Implement __repr__ method 557
558 - def __init__(self, creds, obj, namespace='root/cimv2', **kwargs):
559 560 if isinstance(obj, CIMInstanceName): 561 kwargs['ObjectName'] = obj 562 else: 563 kwargs['ObjectName'] = CIMClassName(obj) 564 565 payload = self.imethodcallPayload( 566 'Associators', 567 namespace, 568 **kwargs) 569 570 WBEMClientFactory.__init__( 571 self, 572 creds, 573 operation='MethodCall', 574 method='Associators', 575 object=namespace, 576 payload=payload)
577
578 -class AssociatorNames(WBEMClientFactory):
579 """Factory to produce AssociatorNames WBEM clients.""" 580 581 # TODO: Implement __repr__ method 582
583 - def __init__(self, creds, obj, namespace='root/cimv2', **kwargs):
584 585 if isinstance(obj, CIMInstanceName): 586 kwargs['ObjectName'] = obj 587 else: 588 kwargs['ObjectName'] = CIMClassName(obj) 589 590 payload = self.imethodcallPayload( 591 'AssociatorNames', 592 namespace, 593 **kwargs) 594 595 WBEMClientFactory.__init__( 596 self, 597 creds, 598 operation='MethodCall', 599 method='AssociatorNames', 600 object=namespace, 601 payload=payload)
602
603 - def parseResponse(self, xml):
604 605 if len(xml.findall('.//INSTANCENAME')) > 0: 606 607 tt = [tupletree.xml_to_tupletree(tostring(x)) 608 for x in xml.findall('.//INSTANCENAME')] 609 610 return [tupleparse.parse_instancename(x) for x in tt] 611 612 else: 613 614 tt = [tupletree.xml_to_tupletree(tostring(x)) 615 for x in xml.findall('.//OBJECTPATH')] 616 617 return [tupleparse.parse_objectpath(x)[2] for x in tt]
618
619 -class References(WBEMClientFactory):
620 """Factory to produce References WBEM clients.""" 621
622 - def __init__(self, creds, obj, namespace='root/cimv2', **kwargs):
623 624 if isinstance(obj, CIMInstanceName): 625 kwargs['ObjectName'] = obj 626 else: 627 kwargs['ObjectName'] = CIMClassName(obj) 628 629 payload = self.imethodcallPayload( 630 'References', 631 namespace, 632 **kwargs) 633 634 WBEMClientFactory.__init__( 635 self, 636 creds, 637 operation='MethodCall', 638 method='References', 639 object=namespace, 640 payload=payload)
641
642 -class ReferenceNames(WBEMClientFactory):
643 """Factory to produce ReferenceNames WBEM clients.""" 644 645 # TODO: Implement __repr__ method 646
647 - def __init__(self, creds, obj, namespace='root/cimv2', **kwargs):
648 649 if isinstance(obj, CIMInstanceName): 650 kwargs['ObjectName'] = obj 651 else: 652 kwargs['ObjectName'] = CIMClassName(obj) 653 654 payload = self.imethodcallPayload( 655 'ReferenceNames', 656 namespace, 657 **kwargs) 658 659 WBEMClientFactory.__init__( 660 self, 661 creds, 662 operation='MethodCall', 663 method='ReferenceNames', 664 object=namespace, 665 payload=payload)
666
667 - def parseResponse(self, xml):
668 669 if len(xml.findall('.//INSTANCENAME')) > 0: 670 671 tt = [tupletree.xml_to_tupletree(tostring(x)) 672 for x in xml.findall('.//INSTANCENAME')] 673 674 return [tupleparse.parse_instancename(x) for x in tt] 675 676 else: 677 678 tt = [tupletree.xml_to_tupletree(tostring(x)) 679 for x in xml.findall('.//OBJECTPATH')] 680 681 return [tupleparse.parse_objectpath(x)[2] for x in tt]
682
683 -class InvokeMethod(WBEMClientFactory):
684 """Factory to produce InvokeMethod WBEM clients.""" 685
686 - def __init__(self, creds, MethodName, ObjectName, namespace='root/cimv2', 687 **kwargs):
688 689 # Convert string to CIMClassName 690 691 obj = ObjectName 692 693 if isinstance(obj, StringTypes): 694 obj = CIMClassName(obj, namespace=namespace) 695 696 if isinstance(obj, CIMInstanceName) and obj.namespace is None: 697 obj = ObjectName.copy() 698 obj.namespace = namespace 699 700 # Make the method call 701 702 payload = self.methodcallPayload( 703 MethodName, 704 obj, 705 namespace, 706 **kwargs) 707 708 WBEMClientFactory.__init__( 709 self, 710 creds, 711 operation='MethodCall', 712 method=MethodName, 713 object=obj, 714 payload=payload)
715
716 - def parseResponse(self, xml):
717 718 # Return value of method 719 720 result_xml = tupletree.xml_to_tupletree( 721 tostring(xml.find('.//RETURNVALUE'))) 722 723 result_tt = tupleparse.parse_any(result_xml) 724 725 result = cim_obj.tocimobj(result_tt[1]['PARAMTYPE'], 726 result_tt[2]) 727 728 # Output parameters 729 730 params_xml = [tupletree.xml_to_tupletree(tostring(x)) 731 for x in xml.findall('.//PARAMVALUE')] 732 733 params_tt = [tupleparse.parse_any(x) for x in params_xml] 734 735 params = {} 736 737 for p in params_tt: 738 if p[1] == 'reference': 739 params[p[0]] = p[2] 740 else: 741 params[p[0]] = cim_obj.tocimobj(p[1], p[2]) 742 743 return (result, params)
744
745 -class ExecQuery(WBEMClientFactory):
746
747 - def __init__(self, creds, QueryLanguage, Query, namespace='root/cimv2'):
748 749 self.QueryLanguage = QueryLanguage 750 self.Query = Query 751 self.namespace = namespace 752 753 payload = self.imethodcallPayload( 754 'ExecQuery', 755 namespace, 756 QueryLanguage = QueryLanguage, 757 Query = Query) 758 759 WBEMClientFactory.__init__( 760 self, 761 creds, 762 operation='MethodCall', 763 method='ExecQuery', 764 object=namespace, 765 payload=payload)
766
767 - def __repr__(self):
768 return '<%s(/%s:%s) at 0x%x>' % \ 769 (self.__class__, self.namespace, self.Query, id(self))
770
771 - def parseResponse(self, xml):
772 tt = [pywbem.tupletree.xml_to_tupletree(tostring(x)) 773 for x in xml.findall('.//INSTANCE')] 774 return [pywbem.tupleparse.parse_instance(x) for x in tt]
775