def test_add_prop(self): """Test addProp as a dict. """ basic_xml = """<?xml version="1.0"?> <Data> <Metadata> <Key1>value1</Key1> <Key2>value2</Key2> </Metadata> </Data>""" class XmlModel(Model): _attribute_map = { 'metadata': { 'key': 'Metadata', 'type': '{str}', 'xml': { 'name': 'Metadata' } }, } _xml_map = {'name': 'Data'} s = Deserializer({"XmlModel": XmlModel}) result = s(XmlModel, basic_xml, "application/xml") assert len(result.metadata) == 2 assert result.metadata['Key1'] == "value1" assert result.metadata['Key2'] == "value2"
def test_list_not_wrapped_basic_types(self): """Test XML list and no wrap, items is basic type and there is no itemsName. """ basic_xml = """<?xml version="1.0"?> <AppleBarrel> <GoodApples>granny</GoodApples> <GoodApples>fuji</GoodApples> </AppleBarrel>""" class AppleBarrel(Model): _attribute_map = { 'good_apples': { 'key': 'GoodApples', 'type': '[str]', 'xml': { 'name': 'GoodApples' } }, } _xml_map = {'name': 'AppleBarrel'} s = Deserializer({"AppleBarrel": AppleBarrel}) result = s(AppleBarrel, basic_xml, "application/xml") assert result.good_apples == ["granny", "fuji"]
def test_basic(self): """Test an ultra basic XML.""" basic_xml = """<?xml version="1.0"?> <Data country="france"> <Age>37</Age> </Data>""" class XmlModel(Model): _attribute_map = { 'age': { 'key': 'age', 'type': 'int', 'xml': { 'name': 'Age' } }, 'country': { 'key': 'country', 'type': 'str', 'xml': { 'name': 'country', 'attr': True } }, } _xml_map = {'name': 'Data'} s = Deserializer({"XmlModel": XmlModel}) result = s(XmlModel, basic_xml, "application/xml") assert result.age == 37 assert result.country == "france"
def test_basic_namespace(self): """Test an ultra basic XML.""" basic_xml = """<?xml version="1.0"?> <Data xmlns:fictional="http://characters.example.com"> <fictional:Age>37</fictional:Age> </Data>""" class XmlModel(Model): _attribute_map = { 'age': { 'key': 'age', 'type': 'int', 'xml': { 'name': 'Age', 'prefix': 'fictional', 'ns': 'http://characters.example.com' } }, } _xml_map = {'name': 'Data'} s = Deserializer({"XmlModel": XmlModel}) result = s(XmlModel, basic_xml, "application/xml") assert result.age == 37
def test_list_not_wrapped_complex_types(self): """Test XML list and wrap, items is ref and there is no itemsName. """ basic_xml = """<?xml version="1.0"?> <AppleBarrel> <Apple name="granny"/> <Apple name="fuji"/> </AppleBarrel>""" class AppleBarrel(Model): _attribute_map = { # Name is ignored if wrapped is False 'good_apples': {'key': 'GoodApples', 'type': '[Apple]', 'xml': {'name': 'GoodApples'}}, } _xml_map = { 'name': 'AppleBarrel' } class Apple(Model): _attribute_map = { 'name': {'key': 'name', 'type': 'str', 'xml':{'name': 'name', 'attr': True}}, } _xml_map = { 'name': 'Apple' } s = Deserializer({"AppleBarrel": AppleBarrel, "Apple": Apple}) result = s(AppleBarrel, basic_xml, "application/xml") assert [apple.name for apple in result.good_apples] == ["granny", "fuji"]
def test_basic(self): """Test an ultra basic XML.""" basic_xml = """<?xml version="1.0"?> <Data country="france"> <Long>12</Long> <EmptyLong/> <Age>37</Age> <EmptyAge/> <EmptyString/> </Data>""" class XmlModel(Model): _attribute_map = { 'longnode': {'key': 'longnode', 'type': 'long', 'xml':{'name': 'Long'}}, 'empty_long': {'key': 'empty_long', 'type': 'long', 'xml':{'name': 'EmptyLong'}}, 'age': {'key': 'age', 'type': 'int', 'xml':{'name': 'Age'}}, 'empty_age': {'key': 'empty_age', 'type': 'int', 'xml':{'name': 'EmptyAge'}}, 'empty_string': {'key': 'empty_string', 'type': 'str', 'xml':{'name': 'EmptyString'}}, 'not_set': {'key': 'not_set', 'type': 'str', 'xml':{'name': 'NotSet'}}, 'country': {'key': 'country', 'type': 'str', 'xml':{'name': 'country', 'attr': True}}, } _xml_map = { 'name': 'Data' } s = Deserializer({"XmlModel": XmlModel}) result = s(XmlModel, basic_xml, "application/xml") assert result.longnode == 12 assert result.empty_long is None assert result.age == 37 assert result.empty_age is None assert result.country == "france" assert result.empty_string == "" assert result.not_set is None
def test_list_wrapped_items_name_complex_types(self): """Test XML list and wrap, items is ref and there is itemsName. """ basic_xml = """<?xml version="1.0"?> <AppleBarrel> <GoodApples> <Apple name="granny"/> <Apple name="fuji"/> </GoodApples> </AppleBarrel>""" class AppleBarrel(Model): _attribute_map = { 'good_apples': {'key': 'GoodApples', 'type': '[Apple]', 'xml': {'name': 'GoodApples', 'wrapped': True, 'itemsName': 'Apple'}}, } _xml_map = { 'name': 'AppleBarrel' } class Apple(Model): _attribute_map = { 'name': {'key': 'name', 'type': 'str', 'xml':{'name': 'name', 'attr': True}}, } _xml_map = { 'name': 'Pomme' # Should be ignored, since "itemsName" is defined } s = Deserializer({"AppleBarrel": AppleBarrel, "Apple": Apple}) result = s('AppleBarrel', basic_xml, "application/xml") assert [apple.name for apple in result.good_apples] == ["granny", "fuji"]
def duration_format(value): """Validate the correct format of a timespan string and deserilize.""" try: duration_obj = Deserializer.deserialize_duration(value) except DeserializationError: message = "Argument {} is not in a valid ISO-8601 duration format" raise ValueError(message.format(value)) return duration_obj
def datetime_format(value): """Validate the correct format of a datetime string and deserialize.""" try: datetime_obj = Deserializer.deserialize_iso(value) except DeserializationError: message = "Argument {} is not a valid ISO-8601 datetime format" raise ValueError(message.format(value)) return datetime_obj
def validate_key_frame_interval_duration(ns): """Validate the correct format of a datetime string and the range.""" if ns.key_frame_interval_duration is not None: from msrest.serialization import Deserializer from msrest.exceptions import DeserializationError try: datetime_obj = Deserializer.deserialize_duration( ns.key_frame_interval_duration) except DeserializationError: message = "key-frame-interval-duration {} is not a valid ISO-8601 duration format" raise ValueError(message.format(ns.key_frame_interval_duration)) minwindow = Deserializer.deserialize_duration("PT1S") maxwindow = Deserializer.deserialize_duration("PT30S") if datetime_obj < minwindow or datetime_obj > maxwindow: message = "key-frame-interval-duration '{}' is not in the range of PT1S and PT30S"\ .format(ns.key_frame_interval_duration) raise ValueError(message)
def validate_archive_window_length(ns): """Validate the correct format of a datetime string and the range.""" if ns.archive_window_length is not None: from msrest.serialization import Deserializer from msrest.exceptions import DeserializationError try: datetime_obj = Deserializer.deserialize_duration( ns.archive_window_length) except DeserializationError: message = "archive-window-length {} is not a valid ISO-8601 duration format" raise ValueError(message.format(ns.archive_window_length)) minwindow = Deserializer.deserialize_duration("PT5M") maxwindow = Deserializer.deserialize_duration("PT25H") if datetime_obj < minwindow or datetime_obj > maxwindow: message = "archive-window-length '{}' is not in the range of PT5M and PT25H"\ .format(ns.archive_window_length) raise ValueError(message)
def exitDyn_datetime(self, ctx): from msrest.serialization import Deserializer from msrest.exceptions import DeserializationError datetime_str = ctx.getText().strip() try: self.parameters[ 'ignore_data_before'] = Deserializer.deserialize_iso( datetime_str) except DeserializationError: message = "Datetime {} is not a valid ISO-8601 format" raise ValueError(message.format(datetime_str))
def test_object_no_text(self): basic_xml = """<?xml version="1.0"?><Data country="france"><Age>37</Age></Data>""" s = Deserializer() result = s('object', basic_xml, "application/xml") # Should be a XML tree assert result.tag == "Data" assert result.get("country") == "france" for child in result: assert child.tag == "Age" assert child.text == "37"
def __init__(self, response, error=None, *args): deserialize = Deserializer() self.error = None self.message = None self.response = response self.status_code = self.response.status_code self.request_id = None if error: self.message = error self.error = response else: try: data = response.json() except ValueError: data = response else: data = data.get('error', data) try: self.error = deserialize(CloudErrorData(), data) except DeserializationError: self.error = None try: self.message = self.error.message except AttributeError: self.message = None if not self.error or not self.message: try: content = response.json() except ValueError: server_message = "none" else: server_message = content.get('message', "none") try: response.raise_for_status() except RequestException as err: if not self.error: self.error = err if not self.message: if server_message == "none": server_message = str(err) msg = "Operation failed with status: {!r}. Details: {}" self.message = msg.format(response.reason, server_message) else: if not self.error: self.error = response if not self.message: msg = "Operation failed with status: {!r}. Details: {}" self.message = msg.format(response.status_code, server_message) super(CloudError, self).__init__(self.message, self.error, *args)
def test_request_exception(self): def raise_for_status(): raise requests.RequestException() deserializer = Deserializer() response = mock.create_autospec(requests.Response) response.raise_for_status = raise_for_status response.reason = "TESTING" excep = HttpOperationError(deserializer, response) self.assertIn("TESTING", str(excep)) self.assertIn("Operation returned an invalid status code", str(excep))
def deserializer_helper(msrest_cls: Type[Model], dict_to_deserialize: dict) -> Model: dependencies = [ schema_cls for key, schema_cls in getmembers(schema) if isinstance(schema_cls, type) and issubclass(schema_cls, (Model, Enum)) ] dependencies += [ schema_cls for key, schema_cls in getmembers(teams_schema) if isinstance(schema_cls, type) and issubclass(schema_cls, (Model, Enum)) ] dependencies_dict = {dependency.__name__: dependency for dependency in dependencies} deserializer = Deserializer(dependencies_dict) return deserializer(msrest_cls.__name__, dict_to_deserialize)
def test_basic_empty_list(self): """Test an basic XML with an empty node.""" basic_xml = """<?xml version="1.0"?> <Data/>""" class XmlModel(Model): _attribute_map = { 'age': {'key': 'age', 'type': 'str', 'xml':{'name': 'Age'}}, } _xml_map = { 'name': 'Data' } s = Deserializer({"XmlModel": XmlModel}) result = s('[XmlModel]', basic_xml, "application/xml") assert result == []
def __init__(self, response, error=None, *args, **kwargs): self.deserializer = Deserializer({'CloudErrorData': CloudErrorData}) self.error = None self.message = None self.response = response self.status_code = self.response.status_code self.request_id = None if error: self.message = error self.error = response else: self._build_error_data(response) if not self.error or not self.message: self._build_error_message(response) super(CloudError, self).__init__(self.message, self.error, *args, **kwargs)
def test_object_from_requests(self): basic_xml = b"""<?xml version="1.0"?> <Data country="france"> <Age>37</Age> </Data>""" response = requests.Response() response.headers["content-type"] = "application/xml; charset=utf-8" response._content = basic_xml response._content_consumed = True s = Deserializer() result = s('object', response) # Should be a XML tree assert result.tag == "Data" assert result.get("country") == "france" for child in result: assert child.tag == "Age" assert child.text == "37"
def message(self, value): """Attempt to deconstruct error message to retrieve further error data. """ try: value = eval(value) except (SyntaxError, TypeError): pass try: value = value.get('value', value) msg_data = value.split('\n') self._message = msg_data[0] except AttributeError: self._message = value return try: self.request_id = msg_data[1].partition(':')[2] time_str = msg_data[2].partition(':') self.error_time = Deserializer.deserialize_iso("".join( time_str[2:])) except (IndexError, DeserializationError): pass
def message(self, value): """Attempt to deconstruct error message to retrieve further error data. """ try: value = eval(value) except (SyntaxError, TypeError): pass try: value = value.get('value', value) msg_data = value.split('\n') self._message = msg_data[0] except AttributeError: self._message = value return try: self.request_id = msg_data[1].partition(':')[2] time_str = msg_data[2].partition(':') self.error_time = Deserializer.deserialize_iso( "".join(time_str[2:])) except (IndexError, DeserializationError): pass
def test_basic_unicode(self): """Test a XML with unicode.""" basic_xml = u"""<?xml version="1.0" encoding="utf-8"?> <Data language="français"/>""" class XmlModel(Model): _attribute_map = { 'language': { 'key': 'language', 'type': 'str', 'xml': { 'name': 'language', 'attr': True } }, } _xml_map = {'name': 'Data'} s = Deserializer({"XmlModel": XmlModel}) result = s(XmlModel, basic_xml, "application/xml") assert result.language == u"français"
def _get_deserializer(): client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} return Deserializer(client_models)
_attribute_map = { 'next_link': { 'key': 'nextLink', 'type': 'str' }, 'current_page': { 'key': 'value', 'type': '[str]' } } def __init__(self, *args, **kwargs): super(FakePaged, self).__init__(*args, **kwargs) _test_deserializer = Deserializer({}) class TestPaging(unittest.TestCase): def test_basic_paging(self): def internal_paging(next_link=None, raw=False): if not next_link: return {'nextLink': 'page2', 'value': ['value1.0', 'value1.1']} else: return {'nextLink': None, 'value': ['value2.0', 'value2.1']} deserialized = FakePaged(internal_paging, _test_deserializer) result_iterated = list(deserialized) self.assertListEqual(['value1.0', 'value1.1', 'value2.0', 'value2.1'], result_iterated)
def deserializer_helper(msrest_cls: Type[Model], dict_to_deserialize: dict) -> Model: deserializer = Deserializer(DEPENDICIES_DICT) return deserializer(msrest_cls.__name__, dict_to_deserialize)
def test_custom_exception(self): class ErrorResponse(Model): _attribute_map = { 'error': { 'key': 'error', 'type': 'ErrorDetails' }, } def __init__(self, error=None): self.error = error class ErrorResponseException(HttpOperationError): def __init__(self, deserialize, response, *args): super(ErrorResponseException, self).__init__(deserialize, response, 'ErrorResponse', *args) class ErrorDetails(Model): _validation = { 'code': { 'readonly': True }, 'message': { 'readonly': True }, 'target': { 'readonly': True }, } _attribute_map = { 'code': { 'key': 'code', 'type': 'str' }, 'message': { 'key': 'message', 'type': 'str' }, 'target': { 'key': 'target', 'type': 'str' }, } def __init__(self): self.code = None self.message = None self.target = None deserializer = Deserializer({ 'ErrorResponse': ErrorResponse, 'ErrorDetails': ErrorDetails }) response = mock.create_autospec(requests.Response) response.text = json.dumps({ "error": { "code": "NotOptedIn", "message": "You are not allowed to download invoices. Please contact your account administrator to turn on access in the management portal for allowing to download invoices through the API." } }) response.headers = {"content-type": "application/json; charset=utf8"} excep = ErrorResponseException(deserializer, response) self.assertIn("NotOptedIn", str(excep)) self.assertIn("You are not allowed to download invoices", str(excep))