예제 #1
0
파일: client.py 프로젝트: cfrantz/bubbles
    def __init__(self, faultxml=[], client=None):
        DynamicObject.__init__(self)
        Exception.__init__(self)

        self.code = None
        self.message = None
        self.detail = None

        for node in faultxml:
            tag = node.tag.split('}')[-1]
            if tag == 'faultcode':
                self.code = ns.split(node.text, nsmap=faultxml.nsmap)
            elif tag == 'Code':
                self.code = ns.split(node[0].text, nsmap=faultxml.nsmap)
            elif tag == 'faultstring':
                self.message = node.text
            elif tag == 'Reason':
                self.message = node[0].text
            elif tag == 'detail' or tag == 'Detail':
                faultobj = node[0]
                type = faultobj.get(ET.QName(ns.XSI, 'type'))
                if not type:
                    type = faultobj.tag
                try:
                    faultobj = client.factory(type, faultobj)
                except:
                    pass
                self.detail = faultobj
예제 #2
0
파일: client.py 프로젝트: codefool/bubbles
    def __init__(self, faultxml=[], client=None):
        DynamicObject.__init__(self)
        Exception.__init__(self)

        self.code = None
        self.message = None
        self.detail = None

        for node in faultxml:
            tag = node.tag.split('}')[-1]
            if tag == 'faultcode':
                self.code = ns.split(node.text, nsmap=faultxml.nsmap)
            elif tag == 'Code':
                self.code = ns.split(node[0].text, nsmap=faultxml.nsmap)
            elif tag == 'faultstring':
                self.message = node.text
            elif tag == 'Reason':
                self.message = node[0].text
            elif tag == 'detail' or tag == 'Detail':
                faultobj = node[0]
                type = faultobj.get(ET.QName(ns.XSI, 'type'))
                if not type:
                    type = faultobj.tag
                try:
                    faultobj = client.factory(type, faultobj)
                except:
                    pass
                self.detail = faultobj
예제 #3
0
파일: client.py 프로젝트: cfrantz/bubbles
    def __init__(self, client, btype, op, tns=None):
        self.name = op.get('name')
        portop = client.wsdl.find('wsdl:portType[@name="%s"]/wsdl:operation[@name="%s"]' % (btype, self.name))
        self.imsg = None
        self.ihdr = None
        self.omsg = None
        self.client = client
        self.faults = []
        self.action = '""'
        soapop = op.find(ns.expand('soap:operation', client.nsmap))
        if soapop is not None:
            self.action = '"%s"' % soapop.get('soapAction', '')

        hdr = op.find(ns.expand('soap:header', client.nsmap))
        if hdr is not None:
            msg = client.wsdl.messages[ns.expand(hdr.get('message'), el.nsmap)]
            self.ihdr = msg

        for el in portop:
            (namespace, tag) = ns.split(el.tag)
            if tag not in ('input', 'output', 'fault'):
                continue
            msg = client.wsdl.messages[ns.expand(el.get('message'), el.nsmap)]

            if tag == 'input':
                self.imsg = msg
            if tag == 'output':
                self.omsg = msg
            if tag == 'fault':
                self.faults.append(msg)
예제 #4
0
파일: schema.py 프로젝트: cfrantz/bubbles
    def _make_type(self, value, type):
        '''
        Parse value and convert it to type
        '''
        iselem = False
        if ET.iselement(value):
            iselem = True
            xtype = value.get(xsi_type)
            if xtype:
                xtype = ns.expand(xtype, value.nsmap)
                (prefix, t) = ns.split(xtype)
                if prefix == ns.XS:
                    type = 'xs:'+t
                else:
                    type = xtype
            if value.get(xsi_nil) == 'true':
                return None

        if type.startswith('xs:'):
            if iselem:
                value = value.text
            c = converter(type)
            if value is not None and not c.check(value):
                value = c.fromstr(value)
        else:
            if value == "":
                value = None
            value = self.__builder__.factory(type)(value, __relax__=self.__relax__)
        return value
예제 #5
0
    def _make_type(self, value, type):
        '''
        Parse value and convert it to type
        '''
        iselem = False
        if ET.iselement(value):
            iselem = True
            xtype = value.get(xsi_type)
            if xtype:
                xtype = ns.expand(xtype, value.nsmap)
                (prefix, t) = ns.split(xtype)
                if prefix == ns.XS:
                    type = 'xs:' + t
                else:
                    type = xtype
            if value.get(xsi_nil) == 'true':
                return None

        if type.startswith('xs:'):
            if iselem:
                value = value.text
            c = converter(type)
            if value is not None and not c.check(value):
                value = c.fromstr(value)
        else:
            if value == "":
                value = None
            value = self.__builder__.factory(type)(value,
                                                   __relax__=self.__relax__)
        return value
예제 #6
0
파일: client.py 프로젝트: codefool/bubbles
    def __init__(self, client, btype, op, tns=None):
        self.name = op.get('name')
        portop = client.wsdl.find('wsdl:portType[@name="%s"]/wsdl:operation[@name="%s"]' % (btype, self.name))
        self.imsg = None
        self.ihdr = None
        self.omsg = None
        self.client = client
        self.faults = []
        self.action = '""'
        soapop = op.find(ns.expand('soap:operation', client.nsmap))
        if soapop is not None:
            self.action = '"%s"' % soapop.get('soapAction', '')

        hdr = op.find(ns.expand('soap:header', client.nsmap))
        if hdr is not None:
            msg = client.wsdl.messages[ns.expand(hdr.get('message'), el.nsmap)]
            self.ihdr = msg

        for el in portop:
            (namespace, tag) = ns.split(el.tag)
            if tag not in ('input', 'output', 'fault'):
                continue
            msg = client.wsdl.messages[ns.expand(el.get('message'), el.nsmap)]

            if tag == 'input':
                self.imsg = msg
            if tag == 'output':
                self.omsg = msg
            if tag == 'fault':
                self.faults.append(msg)
예제 #7
0
 def guess(self, filename):
     text = file(filename).read()
     text = re.sub(r'xmlns="[^"]*"', '', text)
     xml = ET.fromstring(text)
     obj = DynamicObject(xml)
     tns, tag = ns.split(xml.tag)
     root = self.complexType(tag, obj)
     el = Element(name=tag, type=root.name)
     self._addElement(self.schema, el)
예제 #8
0
 def guess(self, filename):
     text = file(filename).read()
     text = re.sub(r'xmlns="[^"]*"', '', text)
     xml = ET.fromstring(text)
     obj = DynamicObject(xml)
     tns, tag = ns.split(xml.tag)
     root = self.complexType(tag, obj)
     el = Element(name=tag, type=root.name)
     self._addElement(self.schema, el)
예제 #9
0
파일: client.py 프로젝트: codefool/bubbles
 def _mk_binding(self, bname, service):
     '''
     Build operation objects bound to the service
     '''
     #bname = ns.expand(bname, self.nsmap)
     #print "making binding for",bname
     binding = self.wsdl.find('wsdl:binding[@name="%s"]' % bname)
     (_, btype) = ns.split(binding.get('type'), binding.nsmap)
     for op in binding.findall(ns.expand('wsdl:operation', self.nsmap)):
         operation = Operation(self, btype, op)
         setattr(service, op.get('name'), operation)
예제 #10
0
파일: client.py 프로젝트: cfrantz/bubbles
 def _mk_binding(self, bname, service):
     '''
     Build operation objects bound to the service
     '''
     #bname = ns.expand(bname, self.nsmap)
     #print "making binding for",bname
     binding = self.wsdl.find('wsdl:binding[@name="%s"]' % bname)
     (_, btype) = ns.split(binding.get('type'), binding.nsmap)
     for op in binding.findall(ns.expand('wsdl:operation', self.nsmap)):
         operation = Operation(self, btype, op)
         setattr(service, op.get('name'), operation)
예제 #11
0
파일: client.py 프로젝트: cfrantz/bubbles
 def _mk_service(self):
     '''
     Build a Service object for each wsdl:service
     '''
     for s in self.wsdl.findall('wsdl:service'):
         name = s.get('name')
         service = Service(name)
         setattr(self, name, service)
         port = s.find(ns.expand('wsdl:port', self.nsmap))
         (_, binding) = ns.split(port.get('binding'), port.nsmap)
         self._mk_binding(binding, service)
예제 #12
0
파일: client.py 프로젝트: codefool/bubbles
 def _mk_service(self):
     '''
     Build a Service object for each wsdl:service
     '''
     for s in self.wsdl.findall('wsdl:service'):
         name = s.get('name')
         service = Service(name)
         setattr(self, name, service)
         port = s.find(ns.expand('wsdl:port', self.nsmap))
         (_, binding) = ns.split(port.get('binding'), port.nsmap)
         self._mk_binding(binding, service)
예제 #13
0
    def prefix(self, namespace, joinchar=':'):
        '''
        Get the ns prefix schema corresponding to namespace

        If given a full typename like {http://aaa}foobar, this function
        will return nsprefix:typename
        '''
        if '}' in namespace:
            nsname = list(ns.split(namespace))
        else:
            nsname = [namespace]

        nsname[0] = self.revns[nsname[0]]
        return joinchar.join(nsname)
예제 #14
0
파일: schema.py 프로젝트: cfrantz/bubbles
    def prefix(self, namespace, joinchar=':'):
        '''
        Get the ns prefix schema corresponding to namespace

        If given a full typename like {http://aaa}foobar, this function
        will return nsprefix:typename
        '''
        if '}' in namespace:
            nsname = list(ns.split(namespace))
        else:
            nsname = [namespace]

        nsname[0] = self.revns[nsname[0]]
        return joinchar.join(nsname)
예제 #15
0
파일: schema.py 프로젝트: cfrantz/bubbles
    def validate(self, element, onerror='raise'):
        (namespace, name) = ns.split(element.tag)
        validator = self.schemas[namespace]['validator']
        if validator is None:
            validator = ET.XMLSchema(self.schemas[namespace]['root'])
            self.schemas[namespace]['validator'] = validator

        errlog = None
        if validator(element) == False:
            errlog = validator.error_log
            if onerror == 'log':
                log.error('Schema Validation Error: %s', str(errlog))
            elif onerror == 'pass':
                pass
            else:
                raise SchemaValidationError(errlog)
        return errlog
예제 #16
0
    def validate(self, element, onerror='raise'):
        (namespace, name) = ns.split(element.tag)
        validator = self.schemas[namespace]['validator']
        if validator is None:
            validator = ET.XMLSchema(self.schemas[namespace]['root'])
            self.schemas[namespace]['validator'] = validator

        errlog = None
        if validator(element) == False:
            errlog = validator.error_log
            if onerror == 'log':
                log.error('Schema Validation Error: %s', str(errlog))
            elif onerror == 'pass':
                pass
            else:
                raise SchemaValidationError(errlog)
        return errlog
예제 #17
0
파일: schema.py 프로젝트: cfrantz/bubbles
 def basecls(self, name):
     '''Get the base class corresponding to name'''
     (namespace, name) = ns.split(name)
     cls = self.schemas[namespace]['basecls']
     return cls
예제 #18
0
파일: schema.py 프로젝트: cfrantz/bubbles
 def group(self, name):
     '''Get the group corresponding to name'''
     (namespace, name) = ns.split(name)
     groups = self.schemas[namespace]['groups']
     return groups[name]
예제 #19
0
파일: schema.py 프로젝트: cfrantz/bubbles
 def element(self, name):
     '''Get the element corresponding to name'''
     (namespace, name) = ns.split(name)
     elements = self.schemas[namespace]['elements']
     return elements.get(name)
예제 #20
0
파일: schema.py 프로젝트: cfrantz/bubbles
 def type(self, name):
     '''Get the type corresponding to name'''
     (namespace, name) = ns.split(name)
     types = self.schemas[namespace]['types']
     return types.get(name)
예제 #21
0
    def __xml__(self, tag=None, node=None, nsmap=None):
        lat = len(self.__attrchar__)
        done = []
        extra = False
        if tag is None:
            tag = self.__class__.__name__
        tag = self.__nsx__(tag)
        if node is None:
            node = ET.Element(tag, nsmap=nsmap)

        # Construct reverse namespace map for doing xsi:type
        rmap = dict((v, k) for k, v in node.nsmap.items() if k is not None)

        # Iterate over the template to construct the XML representation.
        for (name, type, default, minmax, flags) in self.__template__:
            # If this field is an "xs:any" node, note it for later and skip
            if (flags & ANY):
                extra = True
                continue
            # If the field is choice/optional and doesn't exist, skip it
            if ((flags & CHOICE) or minmax[0] == 0) and name not in self:
                continue
            # Get the value
            value = self[name]
            done.append(name)

            if value is None and minmax[0] == 0 and not (flags & XSINIL):
                # Skip fields that are none and don't have to exist, as long
                # as they aren't nillable
                continue
            elif (flags & ATTRIBUTE):
                # Handle attributes.  Skip attributes that are optional
                value = converter(type).tostr(value)
                if value is None:
                    value = ''
                if value is not None or minmax[0]:
                    node.set(self.__nsx__(name[lat:], flags & QUALIFIED),
                             value)
                continue
            elif (flags & PROPERTY):
                # Property
                node.text = converter(type).tostr(value)
                continue

            qname = self.__nsx__(name)
            if not isinstance(value, (list, tuple)):
                value = [value]
            for v in value:
                if v is None and (flags & XSINIL):
                    # Nil node
                    n = ET.Element(qname, xsi_nil_true)
                    node.append(n)
                elif ET.iselement(v):
                    # User supplied XML Elements, so just add them
                    node.append(v)
                elif type.startswith('xs:'):
                    # Primitive type
                    n = ET.Element(qname)
                    n.text = converter(type).tostr(v)
                    node.append(n)
                elif flags & SIMPLE:
                    # Primitive type
                    type = self.__builder__.factory(type).__simple__
                    n = ET.Element(qname)
                    n.text = converter(type).tostr(v)
                    node.append(n)
                elif isinstance(v, DynamicObject):
                    # Dynamic object or subclass, so marshall and append
                    n = v.__xml__(name)
                    if type != v.__class__.__name__:
                        (namespace, datatype) = ns.split(v.__class__.__name__)
                        n.set(xsi_type, '%s:%s' % (rmap[namespace], datatype))
                    node.append(n)
                elif v == '':
                    # Carry-over for dealing with SUDS bug
                    pass
                else:
                    if not self.__relax__:
                        raise TypeError('Unknown type', name, type)

        # If there was an xs:any node, fall back to the schemaless marshaller
        # in the base class
        if extra:
            DynamicObject.__xml__(self, tag, node, ignore=done)
        return node
예제 #22
0
파일: schema.py 프로젝트: cfrantz/bubbles
 def nssplit(self, s, target=True):
     tns = {}
     if target:
         tns['targetNamespace'] = self.root.get('targetNamespace')
     return ns.split(s, self.root.nsmap, **tns)
예제 #23
0
 def group(self, name):
     '''Get the group corresponding to name'''
     (namespace, name) = ns.split(name)
     groups = self.schemas[namespace]['groups']
     return groups[name]
예제 #24
0
 def type(self, name):
     '''Get the type corresponding to name'''
     (namespace, name) = ns.split(name)
     types = self.schemas[namespace]['types']
     return types.get(name)
예제 #25
0
 def basecls(self, name):
     '''Get the base class corresponding to name'''
     (namespace, name) = ns.split(name)
     cls = self.schemas[namespace]['basecls']
     return cls
예제 #26
0
파일: client.py 프로젝트: cfrantz/bubbles
    def invoke(self, operation, *args, **kwargs):
        '''
        Invoke a SOAP operation.
        '''
        self._reqno += 1
        retxml = kwargs.pop('__retxml__', self.retxml)
        timeout = kwargs.pop('__timeout__', self.timeout)
        transport_options = kwargs.pop('__transport__', {})
        # Create an instance of the request message and initialize
        # the object from the arguments
        param = self.factory(operation.imsg)
        tmpl = param.__template__
        for k,v in zip((t[0] for t in tmpl), args):
            param[k] = v
        for k,v in kwargs.items():
            param[k] = v

        # Build the soap envelope and set the http headers
        payload = self.envelope(self.headers, param, operation.imsg)
        httphdr = { 'Content-Type': 'text/xml', 'SOAPAction': operation.action }
        httphdr.update(self.httphdr)

        # Construct and issue the request, read the response
        payload = ET.tostring(payload, pretty_print=True)
        log.debug('=== SOAP REQUEST ===\n%s', payload)
        req = urllib2.Request(self.url, payload, httphdr)
        try:
            if self._inject:
                xml = ET.fromstring(self._inject.next())
            else:
                if hasattr(self.transport, 'open'):
                    rsp = self.transport.open(req, timeout=timeout, **transport_options)
                else:
                    rsp = self.transport.urlopen(req, timeout=timeout, **transport_options)
                xml = ET.parse(rsp)
        except urllib2.HTTPError as ex:
            xml = ET.parse(ex)

        log.debug('=== SOAP RESPONSE ===\n%s', xmlstr(xml))
        # Get the soap body
        retval = xml.find(ns.expand('soapenv:Body', self.nsmap))
        if not retxml:
            # Does the body contain any nodes?
            if len(retval):
                # Get the first child and examine it
                retval = retval[0]
                namespace, tag = ns.split(retval.tag)
                # If it's a fault, convert it to an exception
                if tag == 'Fault':
                    raise SoapFault(retval, self)
                # Otherwise, deserialize
                obj = self.factory(operation.omsg, retval)
                # If the deserialized
                # object has only one item, return that item, otherwise the
                # whole object
                #
                # This is so if the return value is a single primitive type
                # (like a string), you don't have to dig into an object just
                # to get at the single primitive return value
                if len(obj) == 1:
                    obj = obj[0]
                retval = obj
            else:
                retval = None

        return retval
예제 #27
0
 def nssplit(self, s, target=True):
     tns = {}
     if target:
         tns['targetNamespace'] = self.root.get('targetNamespace')
     return ns.split(s, self.root.nsmap, **tns)
예제 #28
0
 def element(self, name):
     '''Get the element corresponding to name'''
     (namespace, name) = ns.split(name)
     elements = self.schemas[namespace]['elements']
     return elements.get(name)
예제 #29
0
파일: schema.py 프로젝트: cfrantz/bubbles
    def __xml__(self, tag=None, node=None, nsmap=None):
        lat = len(self.__attrchar__)
        done = []
        extra = False
        if tag is None:
            tag = self.__class__.__name__
        tag = self.__nsx__(tag)
        if node is None:
            node = ET.Element(tag, nsmap=nsmap)

        # Construct reverse namespace map for doing xsi:type
        rmap = dict((v,k) for k, v in node.nsmap.items() if k is not None)

        # Iterate over the template to construct the XML representation.
        for (name, type, default, minmax, flags) in self.__template__:
            # If this field is an "xs:any" node, note it for later and skip
            if (flags & ANY):
                extra = True
                continue
            # If the field is choice/optional and doesn't exist, skip it
            if ((flags & CHOICE) or minmax[0] == 0) and name not in self:
                continue
            # Get the value
            value = self[name]
            done.append(name)
            
            if value is None and minmax[0] == 0 and not (flags & XSINIL):
                # Skip fields that are none and don't have to exist, as long
                # as they aren't nillable
                continue
            elif (flags & ATTRIBUTE):
                # Handle attributes.  Skip attributes that are optional
                value = converter(type).tostr(value)
                if value is None:
                    value = ''
                if value is not None or minmax[0]:
                    node.set(self.__nsx__(name[lat:], flags & QUALIFIED), value)
                continue
            elif (flags & PROPERTY):
                # Property
                node.text = converter(type).tostr(value)
                continue

            qname = self.__nsx__(name)
            if not isinstance(value, (list, tuple)):
                value = [value]
            for v in value:
                if v is None and (flags & XSINIL):
                    # Nil node
                    n = ET.Element(qname, xsi_nil_true)
                    node.append(n)
                elif ET.iselement(v):
                    # User supplied XML Elements, so just add them
                    node.append(v)
                elif type.startswith('xs:'):
                    # Primitive type
                    n = ET.Element(qname)
                    n.text = converter(type).tostr(v)
                    node.append(n)
                elif flags & SIMPLE:
                    # Primitive type
                    type = self.__builder__.factory(type).__simple__
                    n = ET.Element(qname)
                    n.text = converter(type).tostr(v)
                    node.append(n)
                elif isinstance(v, DynamicObject):
                    # Dynamic object or subclass, so marshall and append
                    n = v.__xml__(name)
                    if type != v.__class__.__name__:
                        (namespace, datatype) = ns.split(v.__class__.__name__)
                        n.set(xsi_type, '%s:%s' % (rmap[namespace], datatype))
                    node.append(n)
                elif v == '':
                    # Carry-over for dealing with SUDS bug
                    pass
                else:
                    if not self.__relax__:
                        raise TypeError('Unknown type', name, type)

        # If there was an xs:any node, fall back to the schemaless marshaller
        # in the base class
        if extra:
            DynamicObject.__xml__(self, tag, node, ignore=done)
        return node
예제 #30
0
파일: schema.py 프로젝트: cfrantz/bubbles
 def schema(self, namespace):
     '''Get the schema corresponding to namespace'''
     if '}' in namespace:
         (namespace, name) = ns.split(namespace)
     return self.schemas[namespace]['root']
예제 #31
0
파일: client.py 프로젝트: codefool/bubbles
    def invoke(self, operation, *args, **kwargs):
        '''
        Invoke a SOAP operation.
        '''
        self._reqno += 1
        retxml = kwargs.pop('__retxml__', self.retxml)
        timeout = kwargs.pop('__timeout__', self.timeout)
        transport_options = kwargs.pop('__transport__', {})
        # Create an instance of the request message and initialize
        # the object from the arguments
        param = self.factory(operation.imsg)
        tmpl = param.__template__
        for k,v in zip((t[0] for t in tmpl), args):
            param[k] = v
        for k,v in kwargs.items():
            param[k] = v

        # Build the soap envelope and set the http headers
        payload = self.envelope(self.headers, param, operation.imsg)
        httphdr = { 'Content-Type': 'text/xml', 'SOAPAction': operation.action }
        httphdr.update(self.httphdr)

        # Construct and issue the request, read the response
        payload = ET.tostring(payload, pretty_print=True)
        log.debug('=== SOAP REQUEST ===\n%s', re.sub(r'password>.*?<', r'password>*****<', payload ))
        req = urllib2.Request(self.url, payload, httphdr)
        try:
            if self._inject:
                xml = ET.fromstring(self._inject.next())
            else:
                if hasattr(self.transport, 'open'):
                    rsp = self.transport.open(req, timeout=timeout, **transport_options)
                else:
                    rsp = self.transport.urlopen(req, timeout=timeout, **transport_options)
                xml = ET.parse(rsp)
        except urllib2.HTTPError as ex:
            xml = ET.parse(ex)

        log.debug('=== SOAP RESPONSE ===\n%s', xmlstr(xml))
        # Get the soap body
        retval = xml.find(ns.expand('soapenv:Body', self.nsmap))
        if not retxml:
            # Does the body contain any nodes?
            if len(retval):
                # Get the first child and examine it
                retval = retval[0]
                namespace, tag = ns.split(retval.tag)
                # If it's a fault, convert it to an exception
                if tag == 'Fault':
                    raise SoapFault(retval, self)
                # Otherwise, deserialize
                obj = self.factory(operation.omsg, retval)
                # If the deserialized
                # object has only one item, return that item, otherwise the
                # whole object
                #
                # This is so if the return value is a single primitive type
                # (like a string), you don't have to dig into an object just
                # to get at the single primitive return value
                if len(obj) == 1:
                    obj = obj[0]
                retval = obj
            else:
                retval = None

        return retval
예제 #32
0
 def schema(self, namespace):
     '''Get the schema corresponding to namespace'''
     if '}' in namespace:
         (namespace, name) = ns.split(namespace)
     return self.schemas[namespace]['root']