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()
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
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)
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()
def make_reader(text): """ Creates an IO object that reads from the given text. """ return xml.XmlReader(BytesIO(text.encode('utf-8')))