def runTransaction(self, **kwargs): # pylint: disable=unused-argument cc_reply_items = { 'reasonCode': 100, 'amount': unicode(amount), 'requestDateTime': '2015-01-01T:00:00:00Z', 'reconciliationID': 'efg456' } items = { 'requestID': transaction_id, 'decision': decision, 'merchantReferenceCode': unicode(basket_id), 'reasonCode': 100, 'requestToken': 'abc123', 'purchaseTotals': Factory.object('PurchaseTotals', {'currency': currency}), 'ccCreditReply': Factory.object('CCCreditReply', cc_reply_items) } return Factory.object('reply', items)
def __init__(self, root, definitions): """ @param root: An XML root element. @type root: L{Element} @param definitions: A definitions object. @type definitions: L{Definitions} """ NamedObject.__init__(self, root, definitions) self.operations = {} for c in root.getChildren('operation'): op = SFactory.object('Operation') op.name = c.get('name') op.tns = definitions.tns input = c.getChild('input') op.input = input.get('message') output = c.getChild('output', default=input) if output is None: op.output = None else: op.output = output.get('message') faults = [] for fault in c.getChildren('fault'): f = SFactory.object('Operation') f.name = fault.get('name') f.message = fault.get('message') faults.append(f) op.faults = faults self.operations[op.name] = op
def add_methods(self): """ Build method view for service """ bindings = { 'document/literal': Document(self), 'rpc/literal': RPC(self), 'rpc/encoded': Encoded(self) } for p in self.service.ports: binding = p.binding ptype = p.binding.type operations = p.binding.type.operations.values() for name in [op.name for op in operations]: m = SFactory.object('Method') m.name = name m.location = p.location m.binding = SFactory.object('binding') op = binding.operation(name) m.soap = op.soap key = '/'.join((op.soap.style, op.soap.input.body.use)) m.binding.input = bindings.get(key) key = '/'.join((op.soap.style, op.soap.output.body.use)) m.binding.output = bindings.get(key) op = ptype.operation(name) m.message = SFactory.object('message') m.message.input = op.input m.message.output = op.output m.qname = ':'.join((p.name, name)) self.service.methods[m.name] = m self.service.methods[m.qname] = m
def process(self, data, type, history): """ process the specified type then process its children """ if type in history: return if type.enum(): return history.append(type) resolved = type.resolve() value = None if type.multi_occurrence(): value = [] else: if len(resolved) > 0: if resolved.mixed(): value = Factory.property(resolved.name) md = value.__metadata__ md.sxtype = resolved else: value = Factory.object(resolved.name) md = value.__metadata__ md.sxtype = resolved md.ordering = self.ordering(resolved) setattr(data, type.name, value) if value is not None: data = value if not isinstance(data, list): self.add_attributes(data, resolved) for child, ancestry in resolved.children(): if self.skip_child(child, ancestry): continue self.process(data, child, history[:])
def build(self, name): """ build a an object for the specified typename as defined in the schema """ if isinstance(name, basestring): type = self.resolver.find(name) if type is None: raise TypeNotFound(name) else: type = name cls = type.name if type.mixed(): data = Factory.property(cls) else: data = Factory.object(cls) resolved = type.resolve() md = data.__metadata__ md.sxtype = resolved md.ordering = self.ordering(resolved) history = [] self.add_attributes(data, resolved) for child, ancestry in type.children(): if self.skip_child(child, ancestry): continue self.process(data, child, history[:]) return data
def process(self, data, type, history): """ process the specified type then process its children """ if type in history: return if type.enum(): return history.append(type) resolved = type.resolve() value = None if type.unbounded(): value = [] else: if len(resolved) > 0: if resolved.mixed(): value = Factory.property(resolved.name) md = value.__metadata__ md.sxtype = resolved else: value = Factory.object(resolved.name) md = value.__metadata__ md.sxtype = resolved md.ordering = self.ordering(resolved) setattr(data, type.name, value) if value is not None: data = value if not isinstance(data, list): self.add_attributes(data, resolved) for child, ancestry in resolved.children(): if self.skip_child(child, ancestry): continue self.process(data, child, history[:])
def translate(self, content): """ Translate using the XSD type information. Python I{dict} is translated to a suds object. Most importantly, primitive values are translated from python to XML types using the XSD type. @param content: Content to translate. @type content: L{Object} @return: self @rtype: L{Typed} """ v = content.value if v is None: return if isinstance(v, dict): cls = content.real.name content.value = Factory.object(cls, v) md = content.value.__metadata__ md.sxtype = content.type return v = content.real.translate(v, False) content.value = v return self
def postprocess(self, content): """ Perform final processing of the resulting data structure as follows: - Mixed values (children and text) will have a result of the I{content.node}. - Simi-simple values (attributes, no-children and text) will have a result of a property object. - Simple values (no-attributes, no-children with text nodes) will have a string result equal to the value of the content.node.getText(). @param content: The current content being unmarshalled. @type content: L{Content} @return: The post-processed result. @rtype: I{any} """ node = content.node if len(node.children) and node.hasText(): return node attributes = AttrList(node.attributes) if attributes.rlen() and not len(node.children) and node.hasText(): p = Factory.property(node.name, node.getText()) return merge(content.data, p) if len(content.data): return content.data lang = attributes.lang() if content.node.isnil(): return None if not len(node.children) and content.text is None: if self.nillable(content): return None else: return Text("", lang=lang) if isinstance(content.text, str): return Text(content.text, lang=lang) else: return content.text
def create(self, name): """ create a WSDL type by name @param name: The name of a type defined in the WSDL. @type name: str @return: The requested object. @rtype: L{Object} """ timer = metrics.Timer() timer.start() type = self.resolver.find(name) if type is None: raise TypeNotFound(name) if type.enum(): result = InstFactory.object(name) for e, a in type.children(): setattr(result, e.name, e.name) else: try: result = self.builder.build(type) except Exception as e: log.error("create '%s' failed", name, exc_info=True) raise BuildError(name, e) timer.stop() metrics.log.debug('%s created: %s', name, timer) return result
def replycomposite(self, rtypes, nodes): """ Construct a I{composite} reply. This method is called when it has been detected that the reply has multiple root nodes. @param rtypes: A list of known return I{types}. @type rtypes: [L{suds.xsd.sxbase.SchemaObject},...] @param nodes: A collection of XML nodes. @type nodes: [L{Element},...] @return: The I{unmarshalled} composite object. @rtype: L{Object},... """ dictionary = {} for rt in rtypes: dictionary[rt.name] = rt unmarshaller = self.unmarshaller() composite = Factory.object('reply') for node in nodes: tag = node.name rt = dictionary.get(tag, None) if rt is None: if node.get('id') is None: raise Exception('<%s/> not mapped to message part' % tag) else: continue resolved = rt.resolve(nobuiltin=True) sobject = unmarshaller.process(node, resolved) if rt.unbounded(): value = getattr(composite, tag, None) if value is None: value = [] setattr(composite, tag, value) value.append(sobject) else: setattr(composite, tag, sobject) return composite
def start(self, content): """ Processing on I{node} has started. Build and return the proper object. @param content: The current content being unmarshalled. @type content: L{Content} @return: A subclass of Object. @rtype: L{Object} """ content.data = Factory.object(content.node.name)
def add_operations(self, root, definitions): """ Add <operation/> children """ dsop = Element('operation', ns=soapns) for c in root.getChildren('operation'): op = SFactory.object('Operation') op.name = c.get('name') sop = c.getChild('operation', default=dsop) soap = SFactory.object('soap') soap.action = '"%s"' % sop.get('soapAction', default='') soap.style = sop.get('style', default=self.soap.style) soap.input = SFactory.object('Input') soap.input.body = SFactory.object('Body') soap.input.headers = [] soap.output = SFactory.object('Output') soap.output.body = SFactory.object('Body') soap.output.headers = [] op.soap = soap input = c.getChild('input') if input is None: input = Element('input', ns=wsdlns) body = input.getChild('body') self.body(definitions, soap.input.body, body) for header in input.getChildren('header'): self.header(definitions, soap.input, header) output = c.getChild('output') if output is None: output = Element('output', ns=wsdlns) body = output.getChild('body') self.body(definitions, soap.output.body, output) for header in output.getChildren('header'): self.header(definitions, soap.output, header) self.operations[op.name] = op
def cast(self, content): """ Cast the I{untyped} list items found in content I{value}. Each items contained in the list is checked for XSD type information. Items (values) that are I{untyped}, are replaced with suds objects and type I{metadata} is added. @param content: The content holding the collection. @type content: L{Content} @return: self @rtype: L{Encoded} """ aty = content.aty[1] resolved = content.type.resolve() array = Factory.object(resolved.name) array.item = [] query = TypeQuery(aty) ref = query.execute(self.schema) if ref is None: raise TypeNotFound(qref) for x in content.value: if isinstance(x, (list, tuple)): array.item.append(x) continue if isinstance(x, Object): md = x.__metadata__ md.sxtype = ref array.item.append(x) continue if isinstance(x, dict): x = Factory.object(ref.name, x) md = x.__metadata__ md.sxtype = ref array.item.append(x) continue x = Factory.property(ref.name, x) md = x.__metadata__ md.sxtype = ref array.item.append(x) content.value = array return self
def __init__(self, root, definitions=None): """ @param root: An XML root element. @type root: L{Element} @param definitions: A definitions object. @type definitions: L{Definitions} """ Object.__init__(self) self.root = root pmd = SFactory.metadata() pmd.excludes = ['root'] pmd.wrappers = dict(qname=lambda x: repr(x)) self.__metadata__.__print__ = pmd
def __init__(self, root, definitions): """ @param root: An XML root element. @type root: L{Element} @param definitions: A definitions object. @type definitions: L{Definitions} """ NamedObject.__init__(self, root, definitions) pmd = SFactory.metadata() pmd.wrappers = \ dict(element=lambda x: repr(x), type=lambda x: repr(x)) self.__metadata__.__print__ = pmd tns = definitions.tns self.element = self.__getref('element', tns) self.type = self.__getref('type', tns)
def add_methods(self, service): """ Build method view for service """ bindings = { 'document/literal' : Document(self), 'rpc/literal' : RPC(self), 'rpc/encoded' : Encoded(self) } for p in service.ports: binding = p.binding ptype = p.binding.type operations = p.binding.type.operations.values() for name in [op.name for op in operations]: m = SFactory.object('Method') m.name = name m.location = p.location m.binding = SFactory.object('binding') op = binding.operation(name) m.soap = op.soap key = '/'.join((op.soap.style, op.soap.input.body.use)) m.binding.input = bindings.get(key) key = '/'.join((op.soap.style, op.soap.output.body.use)) m.binding.output = bindings.get(key) op = ptype.operation(name) p.methods[name] = m
def replycomposite(self, rtypes, nodes): """ Construct a I{composite} reply. Called for replies with multiple output nodes. @param rtypes: A list of known return I{types}. @type rtypes: [L{suds.xsd.sxbase.SchemaObject},...] @param nodes: A collection of XML nodes. @type nodes: [L{Element},...] @return: The I{unmarshalled} composite object. @rtype: L{Object},... """ dictionary = {} for rt in rtypes: dictionary[rt.name] = rt unmarshaller = self.unmarshaller() composite = Factory.object("reply") for node in nodes: tag = node.name rt = dictionary.get(tag) if rt is None: if node.get("id") is None: message = "<%s/> not mapped to message part" % (tag, ) raise Exception(message) continue resolved = rt.resolve(nobuiltin=True) sobject = unmarshaller.process(node, resolved) value = getattr(composite, tag, None) if value is None: if rt.multi_occurrence(): value = [] setattr(composite, tag, value) value.append(sobject) else: setattr(composite, tag, sobject) else: if not isinstance(value, list): value = [ value, ] setattr(composite, tag, value) value.append(sobject) return composite
def dict2suds(d): """ Suds object deserializer """ out = {} for k, v in d.items(): if isinstance(v, dict): out[k] = dict2suds(v) elif isinstance(v, list): out[k] = [] for item in list(v): if isinstance(item, dict): out[k].append(dict2suds(item)) else: out[k].append(item) else: out[k] = v return SudsFactory.object(out.pop('__class__'), out)
def __init__(self, root, definitions): """ @param root: An XML root element. @type root: L{Element} @param definitions: A definitions object. @type definitions: L{Definitions} """ NamedObject.__init__(self, root, definitions) self.operations = {} self.type = root.get('type') sr = self.soaproot() if sr is None: self.soap = None log.debug('binding: "%s" not a soap binding', self.name) return soap = SFactory.object('soap') self.soap = soap self.soap.style = sr.get('style', default='document') self.add_operations(self.root, definitions)
def header(self, definitions, parent, root): """ add the input/output header properties """ if root is None: return header = SFactory.object('Header') parent.headers.append(header) header.use = root.get('use', default='literal') ns = root.get('namespace') if ns is None: header.namespace = definitions.tns else: prefix = root.findPrefix(ns, 'h0') header.namespace = (prefix, ns) msg = root.get('message') if msg is not None: header.message = msg part = root.get('part') if part is not None: header.part = part
def replycomposite(self, rtypes, nodes): """ Construct a I{composite} reply. Called for replies with multiple output nodes. @param rtypes: A list of known return I{types}. @type rtypes: [L{suds.xsd.sxbase.SchemaObject},...] @param nodes: A collection of XML nodes. @type nodes: [L{Element},...] @return: The I{unmarshalled} composite object. @rtype: L{Object},... """ dictionary = {} for rt in rtypes: dictionary[rt.name] = rt unmarshaller = self.unmarshaller() composite = Factory.object("reply") for node in nodes: tag = node.name rt = dictionary.get(tag) if rt is None: if node.get("id") is None: message = "<%s/> not mapped to message part" % (tag,) raise Exception(message) continue resolved = rt.resolve(nobuiltin=True) sobject = unmarshaller.process(node, resolved) value = getattr(composite, tag, None) if value is None: if rt.multi_occurrence(): value = [] setattr(composite, tag, value) value.append(sobject) else: setattr(composite, tag, sobject) else: if not isinstance(value, list): value = [value,] setattr(composite, tag, value) value.append(sobject) return composite
def start(self, content): # # Resolve to the schema type; build an object and setup metadata. # if content.type is None: found = self.resolver.find(content.node) if found is None: log.error(self.resolver.schema) raise TypeNotFound(content.node.qname()) content.type = found else: known = self.resolver.known(content.node) frame = Frame(content.type, resolved=known) self.resolver.push(frame) resolved = self.resolver.top().resolved cls_name = resolved.name if cls_name is None: cls_name = content.node.name content.data = Factory.object(cls_name) md = content.data.__metadata__ md.sxtype = content.type
def __init__(self, root, definitions): """ @param root: An XML root element. @type root: L{Element} @param definitions: A definitions object. @type definitions: L{Definitions} """ NamedObject.__init__(self, root, definitions) self.operations = {} for c in root.getChildren('operation'): op = SFactory.object('Operation') op.name = c.get('name') op.tns = definitions.tns input = c.getChild('input') op.input = input.get('message') output = c.getChild('output', default=input) if output is None: op.output = None else: op.output = output.get('message') self.operations[op.name] = op
def postprocess(self, content): """ Perform final processing of the resulting data structure as follows: - Mixed values (children and text) will have a result of the I{content.node}. - Semi-simple values (attributes, no-children and text) will have a result of a property object. - Simple values (no-attributes, no-children with text nodes) will have a string result equal to the value of the content.node.getText(). @param content: The current content being unmarshalled. @type content: L{Content} @return: The post-processed result. @rtype: I{any} """ node = content.node if len(node.children) and node.hasText(): return node attributes = AttrList(node.attributes) if ( attributes.rlen() and not len(node.children) and node.hasText() ): p = Factory.property(node.name, node.getText()) return merge(content.data, p) if len(content.data): return content.data lang = attributes.lang() if content.node.isnil(): return None if not len(node.children) and content.text is None: if self.nillable(content): return None else: return Text('', lang=lang) if isinstance(content.text, basestring): return Text(content.text, lang=lang) else: return content.text
def add_operations(self, root, definitions): """ Add <operation/> children """ dsop = Element('operation', ns=soapns) for c in root.getChildren('operation'): op = SFactory.object('Operation') op.name = c.get('name') sop = c.getChild('operation', default=dsop) soap = SFactory.object('soap') soap.action = '"%s"' % sop.get('soapAction', default='') soap.style = sop.get('style', default=self.soap.style) soap.input = SFactory.object('Input') soap.input.body = SFactory.object('Body') soap.input.headers = [] soap.output = SFactory.object('Output') soap.output.body = SFactory.object('Body') soap.output.headers = [] op.soap = soap input = c.getChild('input') if input is None: input = Element('input', ns=wsdlns) body = input.getChild('body') self.body(definitions, soap.input.body, body) for header in input.getChildren('header'): self.header(definitions, soap.input, header) output = c.getChild('output') if output is None: output = Element('output', ns=wsdlns) body = output.getChild('body') self.body(definitions, soap.output.body, output) for header in output.getChildren('header'): self.header(definitions, soap.output, header) faults = [] for fault in c.getChildren('fault'): fault = fault.getChild('fault') if fault is None: continue f = SFactory.object('Fault') f.name = fault.get('name') f.use = fault.get('use', default='literal') faults.append(f) soap.faults = faults self.operations[op.name] = op
def start(self, content): # # Resolve to the schema type; build an object and setup metadata. # if content.type is None: found = self.resolver.find(content.node) if found is None: log.error(self.resolver.schema) raise TypeNotFound(content.node.qname()) content.type = found else: known = self.resolver.known(content.node) frame = Frame(content.type, resolved=known) self.resolver.push(frame) real = self.resolver.top().resolved content.real = real cls_name = real.name if cls_name is None: cls_name = content.node.name content.data = Factory.object(cls_name) md = content.data.__metadata__ md.sxtype = real
def start(self, content): """ Resolve to the schema type; build an object and setup metadata. @param content: The current content being unmarshalled. @type content: L{Content} @return: A subclass of Object. @rtype: L{Object} """ if content.type is None: found = self.resolver.find(content.node) if found is None: log.error(self.resolver.schema) raise TypeNotFound(content.node.qname()) content.type = found else: frame = Frame(content.type) self.resolver.push(frame) cls_name = content.type.name if cls_name is None: cls_name = content.node.name content.data = Factory.object(cls_name) md = content.data.__metadata__ md.sxtype = content.type
def resolveheaders(self, definitions): """ Resolve soap header I{message} references. @param definitions: A definitions object. @type definitions: L{Definitions} """ for op in self.operations.values(): soap = op.soap headers = soap.input.headers + soap.output.headers for header in headers: mn = header.message ref = qualify(mn, self.root, definitions.tns) message = definitions.messages.get(ref) if message is None: raise Exception("message'%s', not-found" % mn) header.message = SFactory.object('Message') header.message.name = message.name header.message.qname = message.qname header.message.parts = [] for p in message.parts: if p.name == header.part: header.message.parts.append(p) break
def create_suds_type(name='FakeSudsObject', **kwargs): return Factory.object(name, kwargs)