예제 #1
0
    def read(cls, source):
        """
        Reads one object, determining the reader method to use based on the
        tag name of the first element. For example, if the first tag name
        is `vm` then it will create a `Vm` object, if it the tag is `vms`
        it will create an array of `Vm` objects, so on.

        :param source: The string, IO or XML reader where the input will be taken from.
        """
        # If the source is a string or IO object then create a XML reader from it:
        cursor = None
        if isinstance(source, str):
            # In Python 3 str is a list of 16 bits characters, so it
            # needs to be converted to an array of bytes, using UTF-8,
            # before trying to parse it.
            if six.PY3:
                source = source.encode('utf-8')
            cursor = xml.XmlReader(io.BytesIO(source))
        elif isinstance(source, bytes):
            cursor = xml.XmlReader(io.BytesIO(source))
        elif isinstance(source, io.BytesIO):
            cursor = xml.XmlReader(source)
        elif isinstance(source, xml.XmlReader):
            cursor = source
        else:
            raise AttributeError(
                "Expected a 'str', 'BytesIO' or 'XmlReader', but got '{source}'".format(
                    source=type(source)
                )
            )

        try:
            # Do nothing if there aren't more tags:
            if not cursor.forward():
                return None

            # Select the specific reader according to the tag:
            tag = cursor.node_name()
            reader = cls._readers.get(tag)
            if reader is None:
                raise Error(
                    "Can't find a reader for tag '{tag}'".format(tag=tag)
                )

            # Read the object using the specific reader:
            return reader(cursor)
        finally:
            if cursor is not None and cursor != source:
                cursor.close()
예제 #2
0
    def _check_action(response):
        """
        Reads the response body assuming that it contains an action, checks if
        it contains an fault, and if it does converts it to an exception and
        raises it.

        This method is intended for internal use by other
        components of the SDK. Refrain from using it directly,
        as backwards compatibility isn't guaranteed.
        """

        buf = None
        xmlreader = None
        result = None
        try:
            buf = io.BytesIO(response.body)
            xmlreader = xml.XmlReader(buf)
            result = reader.Reader.read(xmlreader)
        finally:
            if xmlreader is not None:
                xmlreader.close()
            if io is not None:
                buf.close()

        if result is not None:
            if isinstance(result, types.Fault):
                Service._raise_error(response, result)
            elif isinstance(result, types.Action) and result.fault is not None:
                Service._raise_error(response, result.fault)

        return result
예제 #3
0
    def _check_fault(response):
        """
        Reads the response body assuming that it contains a fault message,
        converts it to an exception and raises it.

        This method is intended for internal use by other
        components of the SDK. Refrain from using it directly,
        as backwards compatibility isn't guaranteed.
        """

        buf = None
        xmlreader = None
        fault = None
        try:
            if response.body:
                buf = io.BytesIO(response.body)
                xmlreader = xml.XmlReader(buf)
                fault = readers.FaultReader.read_one(xmlreader)
        finally:
            if xmlreader is not None:
                xmlreader.close()
            if buf is not None:
                buf.close()
        if fault is not None or response.code >= 400:
            Service._raise_error(response, fault)
예제 #4
0
    def read(cls, source):
        """
        Reads one object, determining the reader method to use based on the
        tag name of the first element. For example, if the first tag name
        is `vm` then it will create a `Vm` object, if it the tag is `vms`
        it will create an array of `Vm` objects, so on.

        :param source: The string, IO or XML reader where the input will be taken from.
        """
        # If the source is a string or IO object then create a XML reader from it:
        cursor = None
        if isinstance(source, io.BytesIO):
            cursor = xml.XmlReader(source)
        elif isinstance(source, xml.XmlReader):
            cursor = source
        else:
            raise AttributeError(
                "Expected a 'String' or 'XmlReader', but got '{source}'".
                format(source=type(source)))

        try:
            # Do nothing if there aren't more tags:
            if not cursor.forward():
                return None

            # Select the specific reader according to the tag:
            tag = cursor.node_name()
            reader = cls._readers[tag]
            if reader is None:
                raise Exception(
                    "Can't find a reader for tag '{tag}'".format(tag=tag))

            # Read the object using the specific reader:
            return reader(cursor)
        finally:
            if cursor is not None and cursor != source:
                cursor.close()
예제 #5
0
def make_reader(text):
    """
    Creates an IO object that reads from the given text.
    """
    return xml.XmlReader(BytesIO(text.encode('utf-8')))