def __call__(self, data, raw=False): e = data.to_xml(data, data.__class__.__name__) envelope = make_soap_envelope(e) body = et.tostring(envelope) methodName = '\"%s\"' % self.method httpHeaders = { "Content-Length": len(body), "Content-type": 'text/xml; charset="UTF-8"', "Accept": "application/soap+xml, application/dime, multipart/related, text/*", 'User-Agent': 'Soaplib/1.0', 'SOAPAction': methodName } scheme, host, path = split_url(self.host) if scheme == "http": conn = httplib.HTTPConnection(host) elif scheme == "https": conn = httplib.HTTPSConnection(host) else: raise RuntimeError("Unsupported URI connection scheme: %s" % scheme) conn.request("POST", path, body=body, headers=httpHeaders) response = conn.getresponse() raw_data = response.read() retval = et.fromstring(raw_data) d = retval.find( '{http://schemas.xmlsoap.org/soap/envelope/}Body').getchildren()[0] if raw: return d return objectify(d)
def importtypes(self, document): """ Processes any imported xmlschema in a wsdl:types element within document, returns a soaplib.parsers.typeparse.TypeParser containing the parsed schema. """ location = None for t in document.findall(wsdlqname + "types"): url = None for s in t.findall(schqname + "schema"): for i in s.findall(schqname + "import"): url = i.get('schemaLocation') if url is not None: #work out if relative or absolute url if '://' not in url: #relative url = path.join(path.dirname(self.url), url) f = ulib.urlopen(url) d = f.read() f.close() element = ElementTree.fromstring(d) else: #inline schema for element in t.findall(schqname + "schema"): self._add_tp( TypeParser(element, global_ctypes=self.ctypes, global_elements=self.elements)) return self._add_tp( TypeParser(element, global_ctypes=self.ctypes, global_elements=self.elements)) return
def __call__(self, data, raw=False): e = data.to_xml(data, data.__class__.__name__) envelope = make_soap_envelope(e) body = et.tostring(envelope) methodName = '\"%s\"' % self.method httpHeaders = { 'Content-Length': len(body), 'Content-type': 'text/xml; charset="UTF-8"', 'Accept': ('application/soap+xml, application/dime, ' 'multipart/related, text/*'), 'User-Agent': 'Soaplib/1.0', 'SOAPAction': methodName, } scheme, host, path = split_url(self.host) if scheme == "http": conn = httplib.HTTPConnection(host) elif scheme == "https": conn = httplib.HTTPSConnection(host) else: raise RuntimeError("Unsupported URI connection scheme: %s" % scheme) conn.request("POST", path, body=body, headers=httpHeaders) response = conn.getresponse() raw_data = response.read() retval = et.fromstring(raw_data) pattern = '{http://schemas.xmlsoap.org/soap/envelope/}Body' node = retval.find(pattern).getchildren()[0] if raw: return node return objectify(node)
def importwsdl(self, document): """ Processes any wsdl documents imported by document (messages are sometimes held in a seperate document, for example). Recusively calls WsdlParser to descend through imports """ reimport = 0 for imp in document.findall('%simport' % wsdlqname): url = str(imp.get('location')) #work out if relative or absolute url if '://' not in url: #relative url = path.join(path.dirname(self.url), url) f = ulib.urlopen(url) d = f.read() f.close() root = ElementTree.fromstring(d) wp = WSDLParser(root, url) for cats in ['ctypes', 'elements', 'messagecat', 'portcat', 'bindingcat']: getattr(self, cats).update(getattr(wp, cats)) document.remove(imp) if self.tp is None: self.tp = wp.tp elif wp.tp is not None: self.tp.ctypes.update(wp.tp.ctypes) self.tp.elements.update(wp.tp.elements)
def importtypes(self, document): """ Processes any imported xmlschema in a wsdl:types element within document, returns a soaplib.parsers.typeparse.TypeParser containing the parsed schema. """ for t in document.findall(wsdlqname+"types"): url = None for s in t.findall(schqname+"schema"): for i in s.findall(schqname+"import"): url = i.get('schemaLocation') if url is not None: #work out if relative or absolute url if '://' not in url: #relative url = path.join(path.dirname(self.url), url) f = ulib.urlopen(url) d = f.read() f.close() element = ElementTree.fromstring(d) else: #inline schema for element in t.findall(schqname+"schema"): self._add_tp(TypeParser(element, global_ctypes=self.ctypes, global_elements=self.elements)) return self._add_tp(TypeParser(element, global_ctypes=self.ctypes, global_elements=self.elements)) return
def to_xml(cls, value, name="retval"): if type(value) == str: value = ElementTree.fromstring(value) e = ElementTree.Element(name) e.set("xmlns", "") e.append(value) return e
def to_xml(cls, value, name='retval'): if type(value) == str: value = ElementTree.fromstring(value) e = ElementTree.Element(name) e.set('xmlns', '') e.append(value) return e
def importwsdl(self, document): """ Processes any wsdl documents imported by document (messages are sometimes held in a seperate document, for example). Recusively calls WsdlParser to descend through imports """ reimport = 0 for imp in document.findall('%simport' % wsdlqname): url = str(imp.get('location')) #work out if relative or absolute url if '://' not in url: #relative url = path.join(path.dirname(self.url), url) f = ulib.urlopen(url) d = f.read() f.close() root = ElementTree.fromstring(d) wp = WSDLParser(root, url) for cats in [ 'ctypes', 'elements', 'messagecat', 'portcat', 'bindingcat' ]: getattr(self, cats).update(getattr(wp, cats)) document.remove(imp) for tp in wp.tps: self._add_tp(tp)
def to_xml(cls,value,name='retval'): if type(value) == str: value = ElementTree.fromstring(value) e = ElementTree.Element(name) e.set('xmlns','') e.append(value) return e
def from_string(cls, xml, url): """ return a new WSDLParser with WSDL parsed from the supplied xml, the url is required incase of additional wsdl or schema files need to be fetched. """ element = ElementTree.fromstring(xml) return WSDLParser(element, url)
def element2dict(element): deprecate('element2dict') if type(element) == str: element = ElementTree.fromstring(element) children = element.getchildren() tag = element.tag.split('}')[-1] return {tag: _element2dict(children)}
def test_soap_fault(self): fault = make_soap_fault('something happened') fault = et.fromstring(et.tostring(fault)) self.assertTrue(fault.getchildren()[0].tag.endswith,'Body') self.assertTrue(fault.getchildren()[0].getchildren()[0].tag.endswith('Fault')) f = fault.getchildren()[0].getchildren()[0] self.assertEquals(f.find('faultstring').text,'something happened') self.assertEquals(f.find('faultcode').text,'Server') self.assertEquals(f.find('detail').text,None) fault = make_soap_fault('something happened','DatabaseError','error on line 12') fault = et.fromstring(et.tostring(fault)) f = fault.getchildren()[0].getchildren()[0] self.assertEquals(f.find('faultstring').text,'something happened') self.assertEquals(f.find('faultcode').text,'DatabaseError') self.assertEquals(f.find('detail').text,'error on line 12')
def test_soap_fault(self): fault = make_soap_fault('something happened') fault = et.fromstring(et.tostring(fault)) self.assertTrue(fault.getchildren()[0].tag.endswith, 'Body') self.assertTrue( fault.getchildren()[0].getchildren()[0].tag.endswith('Fault')) f = fault.getchildren()[0].getchildren()[0] self.assertEquals(f.find('faultstring').text, 'something happened') self.assertEquals(f.find('faultcode').text, 'Server') self.assertEquals(f.find('detail').text, None) fault = make_soap_fault('something happened', 'DatabaseError', 'error on line 12') fault = et.fromstring(et.tostring(fault)) f = fault.getchildren()[0].getchildren()[0] self.assertEquals(f.find('faultstring').text, 'something happened') self.assertEquals(f.find('faultcode').text, 'DatabaseError') self.assertEquals(f.find('detail').text, 'error on line 12')
def test_soap_envelope(self): m = Message('myMessage',[('p',Person)]) env = make_soap_envelope(m.to_xml(Person())) self.assertTrue(env.tag.endswith('Envelope')) self.assertTrue(env.getchildren()[0].tag.endswith('Body')) m = Message('myMessage',[('p',Person)]) env = make_soap_envelope(m.to_xml(Person()), header_elements=[et.Element('header1'),et.Element('header2')]) env = et.fromstring(et.tostring(env)) self.assertTrue(env.getchildren()[0].tag.endswith('Header')) self.assertEquals(len(env.getchildren()[0].getchildren()),2) self.assertTrue(env.getchildren()[1].tag.endswith('Body'))
def test_soap_envelope(self): m = Message('myMessage', [('p', Person)]) env = make_soap_envelope(m.to_xml(Person())) self.assertTrue(env.tag.endswith('Envelope')) self.assertTrue(env.getchildren()[0].tag.endswith('Body')) m = Message('myMessage', [('p', Person)]) env = make_soap_envelope( m.to_xml(Person()), header_elements=[et.Element('header1'), et.Element('header2')]) env = et.fromstring(et.tostring(env)) self.assertTrue(env.getchildren()[0].tag.endswith('Header')) self.assertEquals(len(env.getchildren()[0].getchildren()), 2) self.assertTrue(env.getchildren()[1].tag.endswith('Body'))
def importwsdl(self, document): """ Processes any wsdl documents imported by document (messages are sometimes held in a seperate document, for example). Recusively calls WsdlParser to descend through imports """ reimport = 0 for imp in document.findall("%simport" % wsdlqname): url = str(imp.get("location")) # work out if relative or absolute url if "://" not in url: # relative url = path.join(path.dirname(self.url), url) f = ulib.urlopen(url) d = f.read() f.close() root = ElementTree.fromstring(d) wp = WSDLParser(root, url) for cats in ["ctypes", "elements", "messagecat", "portcat", "bindingcat"]: getattr(self, cats).update(getattr(wp, cats)) document.remove(imp) for tp in wp.tps: self._add_tp(tp)
def __call__(self, *args, **kwargs): ''' This method executes the http request to the remote web service. With the exception of 'headers', 'msgid', and 'mtom'; all keyword arguments to this method are put in the http header. The 'headers' keyword is to denote a list of elements to be included in the soap header, 'msgid' is a convenience keyword used in async web services which creates a WS-Addressing messageid header to be included in the soap headers, and 'mtom' enables the Message Transmission Optimization Mechanism. @param the arguments to the remote method @param the keyword arguments ''' if len(args) != len(self.descriptor.inMessage.params): argstring = '\r\n'.join([' ' + str(arg) for arg in args]) paramstring = '\r\n'.join( [' ' + str(p[0]) for p in self.descriptor.inMessage.params]) err_msg = _err_format % (argstring, paramstring) raise Exception(err_msg) msg = self.descriptor.inMessage.to_xml(*args) # grab the soap headers passed into this call headers = kwargs.get('headers', []) mtom = kwargs.get('mtom', False) msgid = kwargs.get('msgid') if msgid: # special case for the msgid field as a convenience # when dealing with async callback methods headers.append(create_relates_to_header(msgid)) tns = self.descriptor.inMessage.ns envelope = make_soap_envelope(msg, tns, header_elements=headers) body = ElementTree.tostring(envelope, pretty_print=_debug) methodName = '\"%s\"' % self.descriptor.soapAction httpHeaders = { 'Content-Length': len(body), 'Content-type': 'text/xml; charset="UTF-8"', 'Accept': ('application/soap+xml, application/dime, ' 'multipart/related, text/*'), 'User-Agent': 'Soaplib/0.10', 'SOAPAction': methodName, } for k, v in kwargs.items(): # add all the other keywords to the http headers if k not in ('headers', 'msgid', 'mtom'): httpHeaders[k] = v if mtom: httpHeaders, body = apply_mtom(httpHeaders, body, self.descriptor.inMessage.params, args) dump(self.host, self.path, httpHeaders, body) if self.scheme == "http": conn = httplib.HTTPConnection(self.host) elif self.scheme == "https": conn = httplib.HTTPSConnection(self.host) else: raise RuntimeError("Unsupported URI connection scheme: %s" % self.scheme) conn.request("POST", self.path, body=body, headers=httpHeaders) response = conn.getresponse() data = response.read() if _debug: data = ElementTree.fromstring(data) data = ElementTree.tostring(data, pretty_print=True) dump(self.host, self.path, dict(response.getheaders()), data) contenttype = response.getheader('Content-Type') data = collapse_swa(contenttype, data) conn.close() if not (str(response.status) in ('200', '202')): # consider everything NOT 200 or 202 as an error response if str(response.status) == '500': fault = None try: payload, headers = from_soap(data) fault = Fault.from_xml(payload) except: trace = StringIO() import traceback traceback.print_exc(file=trace) fault = Exception("Unable to read response \n" "%s %s \n %s \n %s" % (response.status, response.reason, trace.getvalue(), data)) raise fault else: raise Exception("%s %s" % (response.status, response.reason)) if not self.descriptor.outMessage.params: return payload, headers = from_soap(data) results = self.descriptor.outMessage.from_xml(payload) #TODO: consider supporting multiple return types in a better manner if len(results) > 1: return results return results[0]
def setUp(self): self.service = TestService() self._wsdl = self.service.wsdl('') self.wsdl = ElementTree.fromstring(self._wsdl)
def test_override_default_names(self): wsdl = ElementTree.fromstring(OverrideNamespaceService().wsdl('')) self.assertEquals(wsdl.get('targetNamespace'), "http://someservice.com/override")
def run(url): content = urllib2.urlopen(url).read() wsdl = et.fromstring(content) handle_wsdl(wsdl) return make_clients()
def to_xml(cls,value,name='retval',nsmap=ns): if type(value) == str: value = ElementTree.fromstring(value) e = create_xml_element(name, nsmap) e.append(value) return e
def from_string(cls, xml): """ return a new TypeParser with XSD parsed from the supplied xml """ element = ElementTree.fromstring(xml) return TypeParser(element)
def to_xml(cls, value, name='retval', nsmap=ns): if type(value) == str: value = ElementTree.fromstring(value) e = create_xml_element(name, nsmap) e.append(value) return e
def __call__(self, *args, **kwargs): ''' This method executes the http request to the remote web service. With the exception of 'headers', 'msgid', and 'mtom'; all keyword arguments to this method are put in the http header. The 'headers' keyword is to denote a list of elements to be included in the soap header, 'msgid' is a convenience keyword used in async web services which creates a WS-Addressing messageid header to be included in the soap headers, and 'mtom' enables the Message Transmission Optimization Mechanism. @param the arguments to the remote method @param the keyword arguments ''' if len(args) != len(self.descriptor.inMessage.params): argstring = '\r\n'.join([' ' + str(arg) for arg in args]) paramstring = '\r\n'.join([' ' + str(p[0]) for p in self.descriptor.inMessage.params]) err_msg = _err_format % (argstring, paramstring) raise Exception(err_msg) msg = self.descriptor.inMessage.to_xml(*args) # grab the soap headers passed into this call headers = kwargs.get('headers', []) mtom = kwargs.get('mtom', False) msgid = kwargs.get('msgid') if msgid: # special case for the msgid field as a convenience # when dealing with async callback methods headers.append(create_relates_to_header(msgid)) tns = self.descriptor.inMessage.ns envelope = make_soap_envelope(msg, tns, header_elements=headers) body = ElementTree.tostring(envelope,pretty_print=_debug) methodName = '\"%s\"' % self.descriptor.soapAction httpHeaders = { 'Content-Length': len(body), 'Content-type': 'text/xml; charset="UTF-8"', 'Accept': ('application/soap+xml, application/dime, ' 'multipart/related, text/*'), 'User-Agent': 'Soaplib/0.10', 'SOAPAction': methodName, } for k, v in kwargs.items(): # add all the other keywords to the http headers if k not in ('headers', 'msgid', 'mtom'): httpHeaders[k] = v if mtom: httpHeaders, body = apply_mtom(httpHeaders, body, self.descriptor.inMessage.params, args) dump(self.host, self.path, httpHeaders, body) if self.scheme == "http": conn = httplib.HTTPConnection(self.host) elif self.scheme == "https": conn = httplib.HTTPSConnection(self.host) else: raise RuntimeError("Unsupported URI connection scheme: %s" % self.scheme) conn.request("POST", self.path, body=body, headers=httpHeaders) response = conn.getresponse() data = response.read() if _debug: data = ElementTree.fromstring(data) data = ElementTree.tostring(data,pretty_print=True) dump(self.host, self.path, dict(response.getheaders()), data) contenttype = response.getheader('Content-Type') data = collapse_swa(contenttype, data) conn.close() if not (str(response.status) in ('200', '202')): # consider everything NOT 200 or 202 as an error response if str(response.status) == '500': fault = None try: payload, headers = from_soap(data) fault = Fault.from_xml(payload) except: trace = StringIO() import traceback traceback.print_exc(file=trace) fault = Exception("Unable to read response \n" "%s %s \n %s \n %s" % (response.status, response.reason, trace.getvalue(), data)) raise fault else: raise Exception("%s %s" % (response.status, response.reason)) if not self.descriptor.outMessage.params: return payload, headers = from_soap(data) results = self.descriptor.outMessage.from_xml(payload) #TODO: consider supporting multiple return types in a better manner if len(results) > 1: return results return results[0]