def parse_xmlschema_element(self, nsmap, element): super(ComplexAllType, self).parse_xmlschema_element(nsmap, element) complex_type = self_or_child(element, NS.tag("schema", "complexType")) self.all = self.parse_type_list( nsmap, complex_type.find(NS.tag("schema", "all"))) for type in self.all: type.min_occurs = 0
def type_from_xmlschema_element(nsmap, context, tns, element, defer=False): complex_type = self_or_child(element, NS.tag("schema", "complexType")) simple_type = self_or_child(element, NS.tag("schema", "simpleType")) simple_content = self_or_child(element, SIMPLE_CONTENT_TAG) if simple_type is not None: cls = SimpleType elif simple_content is not None: cls = SimpleContentType elif complex_type is not None: if complex_type.find(NS.tag("schema", "all")) is not None: cls = ComplexAllType elif complex_type.find(NS.tag("schema", "sequence")) is not None: cls = ComplexSequenceType else: raise ValueError("Unparsable complexType!") else: cls = Type #logger.debug("%s -> %s", element, cls) type = cls(context, tns, element.get("name")) if not defer: nsmap = nsmap.augment(element.nsmap) type.parse_xmlschema_element(nsmap, element) return type
class Binding(ContextBoundObject): protocol = None usable = False protocol_map = ( ("soap", NS.tag("soap", "binding")), ("soap12", NS.tag("soap12", "binding")), ("http", NS.tag("http", "binding")), ) def __init__(self, context, ns, name, port_type, binding_options): super(Binding, self).__init__(context, ns, name) self.port_type = port_type self.operation_bindings = {} self.binding_options = (binding_options or {}) @classmethod def detect_binding_protocol(cls, binding_tag): for protocol, tagname in cls.protocol_map: bind_tag = binding_tag.find(tagname) if bind_tag is not None: return (protocol, dict(bind_tag.attrib)) def parse_wsdl(self, binding_tag): for op_tag in binding_tag.findall(NS.tag("wsdl", "operation")): self.parse_wsdl_operation(op_tag) def parse_wsdl_operation(self, op_tag): pass def envelope_message(self, message, operation): raise NotImplementedError("Not implemented") def unenvelope_message(self, message, operation): raise NotImplementedError("Not implemented")
def parse_port_wsdl(port_tag): for protocol, tagname in ( ("soap", NS.tag("soap", "address")), ("soap12", NS.tag("soap12", "address")), ("http", NS.tag("http", "address")), ): addr_tag = port_tag.find(tagname) if addr_tag is not None: return (protocol, addr_tag.get("location"))
def _read_restriction(self, nsmap, element): rest_tag = element.find(NS.tag("schema", "restriction")) if rest_tag is None: return rest_base = self.context.resolve_type(nsmap.to_qname(rest_tag.get("base"))) restriction = [] for enum_tag in rest_tag.findall(NS.tag("schema", "enumeration")): enum_val = rest_base.unmarshal(enum_tag.text or enum_tag.get("value")) restriction.append(enum_val) self.restriction = restriction if not self.base and rest_base: self.base = rest_base
def _read_restriction(self, nsmap, element): rest_tag = element.find(NS.tag("schema", "restriction")) if rest_tag is None: return rest_base = self.context.resolve_type( nsmap.to_qname(rest_tag.get("base"))) restriction = [] for enum_tag in rest_tag.findall(NS.tag("schema", "enumeration")): enum_val = rest_base.unmarshal(enum_tag.text or enum_tag.get("value")) restriction.append(enum_val) self.restriction = restriction if not self.base and rest_base: self.base = rest_base
def parse(self): for types in self.definitions.findall(NS.tag("wsdl", "types")): self.parse_types(types) for message in self.definitions.findall(NS.tag("wsdl", "message")): self.parse_message(message) for port_type in self.definitions.findall(NS.tag("wsdl", "portType")): self.parse_port_type(port_type) for binding in self.definitions.findall(NS.tag("wsdl", "binding")): self.parse_binding(binding) for service in self.definitions.findall(NS.tag("wsdl", "service")): self.parse_service(service)
def parse_type_list(self, nsmap, list_el): lst = [] for element in list_el.findall(NS.tag("schema", "element")): typeobj = type_from_xmlschema_element(nsmap, self.context, self.ns, element) lst.append(typeobj) return TypeList(self, lst)
def parse_message(self, message_tag): message = Message(self.context, self.target_namespace, message_tag.get("name")) for part_tag in message_tag.findall(NS.tag("wsdl", "part")): typename = part_tag.get("element") or part_tag.get("type") typename = self.nsmap.to_qname(typename) message.add_part(part_tag.get("name"), self.context.resolve_type(typename)) self.context.messages.register(message)
def envelope_message(self, message, operation): # XXX: `encoded`/`literal` is blissfully ignored envelope = Element(NS.tag("soapenv", "Envelope"), nsmap=dict(NS)) header = SubElement(envelope, NS.tag("soapenv", "Header")) body = SubElement(envelope, NS.tag("soapenv", "Body")) opbind = self.operation_bindings[operation] for el in operation.input.message.marshal(message, style=opbind["style"]): body.append(el) cleanup_namespaces(envelope) xml = tostring(envelope, pretty_print=True, encoding="UTF-8", xml_declaration=True) req = Request( None, {"Content-type": "text/xml; charset=utf-8", "SOAPAction": '"%s"' % opbind.get("soapAction")}, xml ) return req
def parse_port_type(self, port_type_tag): port_type = PortType(self.context, self.target_namespace, port_type_tag.get("name")) for op_tag in port_type_tag.findall(NS.tag("wsdl", "operation")): op = Operation(port_type, op_tag.get("name")) for c_tag in op_tag.getchildren(): if c_tag.tag == NS.tag("wsdl", "input"): op.input = self.parse_op_part(c_tag) elif c_tag.tag == NS.tag("wsdl", "output"): op.output = self.parse_op_part(c_tag) elif c_tag.tag == NS.tag("wsdl", "fault"): op.faults.append(self.parse_op_part(c_tag)) elif c_tag.tag == NS.tag("wsdl", "documentation"): op.documentation = c_tag.text else: raise NotImplementedError("Not implemented: %s" % c_tag.tag) port_type.operations.register(op) self.context.port_types.register(port_type)
def parse_xmlschema_element(self, nsmap, element): super(SimpleContentType, self).parse_xmlschema_element(nsmap, element) simple_content = self_or_child(element, SIMPLE_CONTENT_TAG) ext_tag = simple_content.find(NS.tag("schema", "extension")) if ext_tag is None: raise XMLValueError("simpleContent without s:extension...", simple_content) base = ext_tag.get("base") self.base = self.context.resolve_type(nsmap.to_qname(base)) self._read_attributes(nsmap, simple_content)
def parse_xmlschema(self, schema): tns = schema.get("targetNamespace") self.nsmap = self.nsmap.augment(schema.nsmap) # XXX: Always assumes elementFormDefault="qualified" new_types = [] elts = [] elts.extend(schema.findall(NS.tag("schema", "simpleType"))) elts.extend(schema.findall(NS.tag("schema", "element"))) elts.extend(schema.findall(NS.tag("schema", "complexType"))) for element in elts: typeobj = type_from_xmlschema_element(self.nsmap, self.context, tns, element, defer=True) self.context.types.register(typeobj) new_types.append((typeobj, element)) for typeobj, element in new_types: typeobj.parse_xmlschema_element(self.nsmap, element)
def parse_wsdl_operation(self, op_tag): # XXX: Not complete! operation = self.port_type.operations[op_tag.get("name")] soap_op = op_tag.find(NS.tag("soap", "operation")) if soap_op is None: raise XMLValueError("SOAP binding, but no SOAP operation tag.", op_tag) default_dict = {"style": self.binding_options.get("style")} default_dict.update(soap_op.attrib) self.operation_bindings[operation] = default_dict
def parse_service(self, service_tag): service = Service(self.context, self.target_namespace, service_tag.get("name")) service.documentation = service_tag.get("documentation") for port_tag in service_tag.findall(NS.tag("wsdl", "port")): binding_name = self.nsmap.to_qname(port_tag.get("binding")) binding = self.context.bindings[binding_name] protocol, address = parse_port_wsdl(port_tag) port_name = port_tag.get("name") if not protocol: logger.warn("Unable to detect service %s port %s protocol", service.name, port_name) port = Port(port_name, binding, protocol, address) service.ports.register(port) self.context.services.register(service)
def envelope_message(self, message, operation): # XXX: `encoded`/`literal` is blissfully ignored envelope = Element(NS.tag("soapenv", "Envelope"), nsmap=dict(NS)) header = SubElement(envelope, NS.tag("soapenv", "Header")) body = SubElement(envelope, NS.tag("soapenv", "Body")) opbind = self.operation_bindings[operation] for el in operation.input.message.marshal(message, style=opbind["style"]): body.append(el) cleanup_namespaces(envelope) xml = tostring(envelope, pretty_print=True, encoding="UTF-8", xml_declaration=True) req = Request( None, { "Content-type": "text/xml; charset=utf-8", "SOAPAction": '"%s"' % opbind.get("soapAction") }, xml) return req
def parse_xmlschema_element(self, nsmap, element): super(ComplexSequenceType, self).parse_xmlschema_element(nsmap, element) complex_type = self_or_child(element, NS.tag("schema", "complexType")) self.sequence = self.parse_type_list(nsmap, complex_type.find(NS.tag("schema", "sequence")))
# -- encoding: UTF-8 -- from foamy.excs import XMLValueError from foamy.ns import COMMON_NAMESPACES as NS from foamy.objs import ContextBoundObject from foamy.xmlutils import self_or_child from lxml.etree import Element, tostring import logging import sys logger = logging.getLogger(__name__) SENTINEL = object() SIMPLE_CONTENT_TAG = NS.tag("schema", "simpleContent") class MarshalValueError(ValueError): pass class BaseType(object): def marshal(self, obj): raise NotImplementedError("Not implemented: marshal()") def unmarshal(self, node): raise NotImplementedError("Not implemented: unmarshal()") def craft(self): raise NotImplementedError("Not implemented: craft()") def read_object_values(obj, keys):
def _read_attributes(self, nsmap, element): for attr_tag in element.findall(NS.tag("schema", "attribute")): attr_name = attr_tag.get("name") attr_type = self.context.resolve_type( nsmap.to_qname(attr_tag.get("type"))) self.attributes[attr_name] = attr_type
def unenvelope_message(self, message, operation): tree = fromstring(message) body = tree.find(NS.tag("soapenv", "Body")) response = self.binding.unenvelope_message(body.getchildren()[0], operation) return response
def __init__(self, context, wsdl_tree): self.context = context self.definitions = wsdl_tree.getroot() self.nsmap = NS.augment(self.definitions.nsmap) assert self.definitions.tag == NS.tag("wsdl", "definitions") self.target_namespace = self.definitions.get("targetNamespace")
def parse_xmlschema_element(self, nsmap, element): super(SimpleType, self).parse_xmlschema_element(nsmap, element) if element.find(NS.tag("schema", "union")) is not None: raise NotImplementedError("Not implemented: unions") if element.find(NS.tag("schema", "list")) is not None: raise NotImplementedError("Not implemented: lists")
def parse_xmlschema_element(self, nsmap, element): super(ComplexSequenceType, self).parse_xmlschema_element(nsmap, element) complex_type = self_or_child(element, NS.tag("schema", "complexType")) self.sequence = self.parse_type_list( nsmap, complex_type.find(NS.tag("schema", "sequence")))
# -- encoding: UTF-8 -- from foamy.excs import XMLValueError from foamy.ns import COMMON_NAMESPACES as NS from foamy.objs import ContextBoundObject from foamy.xmlutils import self_or_child from lxml.etree import Element, tostring import logging import sys logger = logging.getLogger(__name__) SENTINEL = object() SIMPLE_CONTENT_TAG = NS.tag("schema", "simpleContent") class MarshalValueError(ValueError): pass class BaseType(object): def marshal(self, obj): raise NotImplementedError("Not implemented: marshal()") def unmarshal(self, node): raise NotImplementedError("Not implemented: unmarshal()") def craft(self): raise NotImplementedError("Not implemented: craft()") def read_object_values(obj, keys): is_mapping = callable(getattr(obj, "__getitem__", None))
def parse_types(self, types): for schema in types.findall(NS.tag("schema", "schema")): self.parse_xmlschema(schema)
def parse_xmlschema_element(self, nsmap, element): super(ComplexAllType, self).parse_xmlschema_element(nsmap, element) complex_type = self_or_child(element, NS.tag("schema", "complexType")) self.all = self.parse_type_list(nsmap, complex_type.find(NS.tag("schema", "all"))) for type in self.all: type.min_occurs = 0
def parse_wsdl(self, binding_tag): for op_tag in binding_tag.findall(NS.tag("wsdl", "operation")): self.parse_wsdl_operation(op_tag)
def _read_attributes(self, nsmap, element): for attr_tag in element.findall(NS.tag("schema", "attribute")): attr_name = attr_tag.get("name") attr_type = self.context.resolve_type(nsmap.to_qname(attr_tag.get("type"))) self.attributes[attr_name] = attr_type
return iso8601.parse_date(unicode(unwrap(obj))) def craft(self): return datetime.datetime(1970, 1, 1, 0, 0, 0) class DecimalType(BaseType): def marshal(self, obj): return unicode(obj) def unmarshal(self, obj): return decimal.Decimal(unicode(unwrap(obj))) def craft(self): return decimal.Decimal(0) BASIC_TYPES = { NS.tag("schema", "string"): UnicodeType(), NS.tag("schema", "int"): IntegerType(), NS.tag("schema", "integer"): IntegerType(), NS.tag("schema", "long"): LongType(), NS.tag("schema", "boolean"): BooleanType(), NS.tag("schema", "float"): FloatType(), NS.tag("schema", "double"): DoubleType(), NS.tag("schema", "decimal"): DecimalType(), NS.tag("schema", "date"): DateType(), NS.tag("schema", "dateTime"): DateTimeType(), NS.tag("schema", "time"): TimeType(), }