From 0c27420184d7cc5658799f2aee3ff53b206aa71d Mon Sep 17 00:00:00 2001 From: seankane-msft Date: Thu, 10 Sep 2020 16:20:58 -0700 Subject: [PATCH 1/2] adds support for enums by converting to string before sending on the wire --- .../azure/data/tables/_serialize.py | 16 +- ..._entity.test_insert_entity_with_enums.yaml | 187 ++++++++++++++++++ .../tests/test_table_entity.py | 32 ++- 3 files changed, 232 insertions(+), 3 deletions(-) create mode 100644 sdk/tables/azure-data-tables/tests/recordings/test_table_entity.test_insert_entity_with_enums.yaml diff --git a/sdk/tables/azure-data-tables/azure/data/tables/_serialize.py b/sdk/tables/azure-data-tables/azure/data/tables/_serialize.py index eb31bb55d0d3..4d0270ebe897 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/_serialize.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/_serialize.py @@ -7,6 +7,7 @@ from uuid import UUID from datetime import datetime from math import isnan +from enum import Enum import sys import uuid import isodate @@ -116,6 +117,7 @@ def _to_entity_guid(value): def _to_entity_int32(value): + # TODO: What the heck? below if sys.version_info < (3,): value = int(value) else: @@ -159,7 +161,8 @@ def _to_entity_none(value): # pylint:disable=W0613 bool: _to_entity_bool, datetime: _to_entity_datetime, float: _to_entity_float, - UUID: _to_entity_guid + UUID: _to_entity_guid, + Enum: _to_entity_str } try: _PYTHON_TO_ENTITY_CONVERSIONS.update({ @@ -213,7 +216,16 @@ def _add_entity_properties(source): for name, value in source.items(): mtype = '' - if isinstance(value, EntityProperty): + if isinstance(name, Enum): + try: + name = unicode(name) + except NameError: + name = str(name) + + if isinstance(value, Enum): + conv = _PYTHON_TO_ENTITY_CONVERSIONS.get(str) + mtype, value = conv(value) + elif isinstance(value, EntityProperty): conv = _EDM_TO_ENTITY_CONVERSIONS.get(value.type) if conv is None: raise TypeError( diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_entity.test_insert_entity_with_enums.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_entity.test_insert_entity_with_enums.yaml new file mode 100644 index 000000000000..414a6de86199 --- /dev/null +++ b/sdk/tables/azure-data-tables/tests/recordings/test_table_entity.test_insert_entity_with_enums.yaml @@ -0,0 +1,187 @@ +interactions: +- request: + body: '{"TableName": "uttabled43513a4"}' + headers: + Accept: + - application/json;odata=minimalmetadata + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '32' + Content-Type: + - application/json;odata=nometadata + DataServiceVersion: + - '3.0' + Date: + - Thu, 10 Sep 2020 23:19:18 GMT + User-Agent: + - azsdk-python-data-tables/12.0.0b2 Python/3.8.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Thu, 10 Sep 2020 23:19:18 GMT + x-ms-version: + - '2019-02-02' + method: POST + uri: https://storagename.table.core.windows.net/Tables + response: + body: + string: '{"odata.metadata":"https://storagename.table.core.windows.net/$metadata#Tables/@Element","TableName":"uttabled43513a4"}' + headers: + cache-control: + - no-cache + content-type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + date: + - Thu, 10 Sep 2020 23:19:18 GMT + location: + - https://storagename.table.core.windows.net/Tables('uttabled43513a4') + server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-ms-version: + - '2019-02-02' + status: + code: 201 + message: Created +- request: + body: '{"PartitionKey": "pkd43513a4", "PartitionKey@odata.type": "Edm.String", + "RowKey": "rkd43513a4", "RowKey@odata.type": "Edm.String", "test1": "Color.YELLOW", + "test1@odata.type": "Edm.String", "test2": "Color.BLUE", "test2@odata.type": + "Edm.String", "test3": "Color.RED", "test3@odata.type": "Edm.String"}' + headers: + Accept: + - application/json;odata=minimalmetadata + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '302' + Content-Type: + - application/json;odata=nometadata + DataServiceVersion: + - '3.0' + Date: + - Thu, 10 Sep 2020 23:19:18 GMT + User-Agent: + - azsdk-python-data-tables/12.0.0b2 Python/3.8.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Thu, 10 Sep 2020 23:19:18 GMT + x-ms-version: + - '2019-02-02' + method: POST + uri: https://storagename.table.core.windows.net/uttabled43513a4 + response: + body: + string: '{"odata.metadata":"https://storagename.table.core.windows.net/$metadata#uttabled43513a4/@Element","odata.etag":"W/\"datetime''2020-09-10T23%3A19%3A19.0175285Z''\"","PartitionKey":"pkd43513a4","RowKey":"rkd43513a4","Timestamp":"2020-09-10T23:19:19.0175285Z","test1":"Color.YELLOW","test2":"Color.BLUE","test3":"Color.RED"}' + headers: + cache-control: + - no-cache + content-type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + date: + - Thu, 10 Sep 2020 23:19:18 GMT + etag: + - W/"datetime'2020-09-10T23%3A19%3A19.0175285Z'" + location: + - https://storagename.table.core.windows.net/uttabled43513a4(PartitionKey='pkd43513a4',RowKey='rkd43513a4') + server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-ms-version: + - '2019-02-02' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - application/json;odata=minimalmetadata + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + DataServiceVersion: + - '3.0' + Date: + - Thu, 10 Sep 2020 23:19:19 GMT + User-Agent: + - azsdk-python-data-tables/12.0.0b2 Python/3.8.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Thu, 10 Sep 2020 23:19:19 GMT + x-ms-version: + - '2019-02-02' + method: GET + uri: https://storagename.table.core.windows.net/uttabled43513a4(PartitionKey='pkd43513a4',RowKey='rkd43513a4') + response: + body: + string: '{"odata.metadata":"https://storagename.table.core.windows.net/$metadata#uttabled43513a4/@Element","odata.etag":"W/\"datetime''2020-09-10T23%3A19%3A19.0175285Z''\"","PartitionKey":"pkd43513a4","RowKey":"rkd43513a4","Timestamp":"2020-09-10T23:19:19.0175285Z","test1":"Color.YELLOW","test2":"Color.BLUE","test3":"Color.RED"}' + headers: + cache-control: + - no-cache + content-type: + - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 + date: + - Thu, 10 Sep 2020 23:19:18 GMT + etag: + - W/"datetime'2020-09-10T23%3A19%3A19.0175285Z'" + server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + transfer-encoding: + - chunked + x-content-type-options: + - nosniff + x-ms-version: + - '2019-02-02' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Date: + - Thu, 10 Sep 2020 23:19:19 GMT + User-Agent: + - azsdk-python-data-tables/12.0.0b2 Python/3.8.4 (Windows-10-10.0.19041-SP0) + x-ms-date: + - Thu, 10 Sep 2020 23:19:19 GMT + x-ms-version: + - '2019-02-02' + method: DELETE + uri: https://storagename.table.core.windows.net/Tables('uttabled43513a4') + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + date: + - Thu, 10 Sep 2020 23:19:18 GMT + server: + - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 + x-content-type-options: + - nosniff + x-ms-version: + - '2019-02-02' + status: + code: 204 + message: No Content +version: 1 diff --git a/sdk/tables/azure-data-tables/tests/test_table_entity.py b/sdk/tables/azure-data-tables/tests/test_table_entity.py index 9e0cb8cf6ed2..8bc2c08f5e3e 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_entity.py +++ b/sdk/tables/azure-data-tables/tests/test_table_entity.py @@ -14,6 +14,7 @@ import uuid from base64 import b64encode from datetime import datetime, timedelta +from enum import Enum from azure.data.tables import TableServiceClient, TableClient, generate_table_sas from dateutil.tz import tzutc, tzoffset @@ -303,7 +304,6 @@ def _assert_valid_metadata(self, metadata): self.assertIn("etag", keys) self.assertEqual(len(keys), 3) - # --Test cases for entities ------------------------------------------ @GlobalStorageAccountPreparer() def test_insert_etag(self, resource_group, location, storage_account, storage_account_key): @@ -592,6 +592,36 @@ def test_insert_entity_property_name_too_long(self, resource_group, location, st finally: self._tear_down() + @GlobalStorageAccountPreparer() + def test_insert_entity_with_enums(self, resource_group, location, storage_account, + storage_account_key): + # Arrange + self._set_up(storage_account, storage_account_key) + try: + # Act + class Color(Enum): + RED = 1 + BLUE = 2 + YELLOW = 3 + + pk, rk = self._create_pk_rk(None, None) + entity = TableEntity() + entity.PartitionKey = pk + entity.RowKey = rk + entity.test1 = Color.YELLOW + entity.test2 = Color.BLUE + entity.test3 = Color.RED + + + self.table.create_entity(entity=entity) + resp_entity = self.table.get_entity(partition_key=pk, row_key=rk) + assert str(entity.test1) == resp_entity.test1.value + assert str(entity.test2) == resp_entity.test2.value + assert str(entity.test3) == resp_entity.test3.value + + finally: + self._tear_down() + # @pytest.mark.skip("pending") @GlobalStorageAccountPreparer() def test_get_entity(self, resource_group, location, storage_account, storage_account_key): From 2426dea262b4f80764004a2f307cd704e80a4116 Mon Sep 17 00:00:00 2001 From: seankane-msft Date: Thu, 10 Sep 2020 16:54:47 -0700 Subject: [PATCH 2/2] forgot about considerations for python2 strings/unicode stuff --- .../azure/data/tables/_serialize.py | 9 +-- ..._entity.test_insert_entity_with_enums.yaml | 66 +++++++++---------- 2 files changed, 36 insertions(+), 39 deletions(-) diff --git a/sdk/tables/azure-data-tables/azure/data/tables/_serialize.py b/sdk/tables/azure-data-tables/azure/data/tables/_serialize.py index 4d0270ebe897..56d336dbdca6 100644 --- a/sdk/tables/azure-data-tables/azure/data/tables/_serialize.py +++ b/sdk/tables/azure-data-tables/azure/data/tables/_serialize.py @@ -216,14 +216,11 @@ def _add_entity_properties(source): for name, value in source.items(): mtype = '' - if isinstance(name, Enum): + if isinstance(value, Enum): try: - name = unicode(name) + conv = _PYTHON_TO_ENTITY_CONVERSIONS.get(unicode) except NameError: - name = str(name) - - if isinstance(value, Enum): - conv = _PYTHON_TO_ENTITY_CONVERSIONS.get(str) + conv = _PYTHON_TO_ENTITY_CONVERSIONS.get(str) mtype, value = conv(value) elif isinstance(value, EntityProperty): conv = _EDM_TO_ENTITY_CONVERSIONS.get(value.type) diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_entity.test_insert_entity_with_enums.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_entity.test_insert_entity_with_enums.yaml index 414a6de86199..9c4e400cf416 100644 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_entity.test_insert_entity_with_enums.yaml +++ b/sdk/tables/azure-data-tables/tests/recordings/test_table_entity.test_insert_entity_with_enums.yaml @@ -1,6 +1,6 @@ interactions: - request: - body: '{"TableName": "uttabled43513a4"}' + body: !!python/unicode '{"TableName": "uttabled43513a4"}' headers: Accept: - application/json;odata=minimalmetadata @@ -15,27 +15,27 @@ interactions: DataServiceVersion: - '3.0' Date: - - Thu, 10 Sep 2020 23:19:18 GMT + - Thu, 10 Sep 2020 23:51:25 GMT User-Agent: - - azsdk-python-data-tables/12.0.0b2 Python/3.8.4 (Windows-10-10.0.19041-SP0) + - azsdk-python-data-tables/12.0.0b2 Python/2.7.18 (Windows-10-10.0.19041) x-ms-date: - - Thu, 10 Sep 2020 23:19:18 GMT + - Thu, 10 Sep 2020 23:51:25 GMT x-ms-version: - '2019-02-02' method: POST - uri: https://storagename.table.core.windows.net/Tables + uri: !!python/unicode https://storagename.table.core.windows.net/Tables response: body: - string: '{"odata.metadata":"https://storagename.table.core.windows.net/$metadata#Tables/@Element","TableName":"uttabled43513a4"}' + string: !!python/unicode '{"odata.metadata":"https://storagename.table.core.windows.net/$metadata#Tables/@Element","TableName":"uttabled43513a4"}' headers: cache-control: - no-cache content-type: - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 date: - - Thu, 10 Sep 2020 23:19:18 GMT + - Thu, 10 Sep 2020 23:51:24 GMT location: - - https://storagename.table.core.windows.net/Tables('uttabled43513a4') + - !!python/unicode https://storagename.table.core.windows.net/Tables('uttabled43513a4') server: - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 transfer-encoding: @@ -48,10 +48,10 @@ interactions: code: 201 message: Created - request: - body: '{"PartitionKey": "pkd43513a4", "PartitionKey@odata.type": "Edm.String", - "RowKey": "rkd43513a4", "RowKey@odata.type": "Edm.String", "test1": "Color.YELLOW", - "test1@odata.type": "Edm.String", "test2": "Color.BLUE", "test2@odata.type": - "Edm.String", "test3": "Color.RED", "test3@odata.type": "Edm.String"}' + body: !!python/unicode '{"test1": "Color.YELLOW", "test1@odata.type": "Edm.String", + "test3": "Color.RED", "test2": "Color.BLUE", "RowKey@odata.type": "Edm.String", + "PartitionKey@odata.type": "Edm.String", "PartitionKey": "pkd43513a4", "test2@odata.type": + "Edm.String", "test3@odata.type": "Edm.String", "RowKey": "rkd43513a4"}' headers: Accept: - application/json;odata=minimalmetadata @@ -66,29 +66,29 @@ interactions: DataServiceVersion: - '3.0' Date: - - Thu, 10 Sep 2020 23:19:18 GMT + - Thu, 10 Sep 2020 23:51:25 GMT User-Agent: - - azsdk-python-data-tables/12.0.0b2 Python/3.8.4 (Windows-10-10.0.19041-SP0) + - azsdk-python-data-tables/12.0.0b2 Python/2.7.18 (Windows-10-10.0.19041) x-ms-date: - - Thu, 10 Sep 2020 23:19:18 GMT + - Thu, 10 Sep 2020 23:51:25 GMT x-ms-version: - '2019-02-02' method: POST - uri: https://storagename.table.core.windows.net/uttabled43513a4 + uri: !!python/unicode https://storagename.table.core.windows.net/uttabled43513a4 response: body: - string: '{"odata.metadata":"https://storagename.table.core.windows.net/$metadata#uttabled43513a4/@Element","odata.etag":"W/\"datetime''2020-09-10T23%3A19%3A19.0175285Z''\"","PartitionKey":"pkd43513a4","RowKey":"rkd43513a4","Timestamp":"2020-09-10T23:19:19.0175285Z","test1":"Color.YELLOW","test2":"Color.BLUE","test3":"Color.RED"}' + string: !!python/unicode '{"odata.metadata":"https://storagename.table.core.windows.net/$metadata#uttabled43513a4/@Element","odata.etag":"W/\"datetime''2020-09-10T23%3A51%3A25.711904Z''\"","PartitionKey":"pkd43513a4","RowKey":"rkd43513a4","Timestamp":"2020-09-10T23:51:25.711904Z","test1":"Color.YELLOW","test3":"Color.RED","test2":"Color.BLUE"}' headers: cache-control: - no-cache content-type: - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 date: - - Thu, 10 Sep 2020 23:19:18 GMT + - Thu, 10 Sep 2020 23:51:25 GMT etag: - - W/"datetime'2020-09-10T23%3A19%3A19.0175285Z'" + - W/"datetime'2020-09-10T23%3A51%3A25.711904Z'" location: - - https://storagename.table.core.windows.net/uttabled43513a4(PartitionKey='pkd43513a4',RowKey='rkd43513a4') + - !!python/unicode https://storagename.table.core.windows.net/uttabled43513a4(PartitionKey='pkd43513a4',RowKey='rkd43513a4') server: - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 transfer-encoding: @@ -112,27 +112,27 @@ interactions: DataServiceVersion: - '3.0' Date: - - Thu, 10 Sep 2020 23:19:19 GMT + - Thu, 10 Sep 2020 23:51:25 GMT User-Agent: - - azsdk-python-data-tables/12.0.0b2 Python/3.8.4 (Windows-10-10.0.19041-SP0) + - azsdk-python-data-tables/12.0.0b2 Python/2.7.18 (Windows-10-10.0.19041) x-ms-date: - - Thu, 10 Sep 2020 23:19:19 GMT + - Thu, 10 Sep 2020 23:51:25 GMT x-ms-version: - '2019-02-02' method: GET - uri: https://storagename.table.core.windows.net/uttabled43513a4(PartitionKey='pkd43513a4',RowKey='rkd43513a4') + uri: !!python/unicode https://storagename.table.core.windows.net/uttabled43513a4(PartitionKey='pkd43513a4',RowKey='rkd43513a4') response: body: - string: '{"odata.metadata":"https://storagename.table.core.windows.net/$metadata#uttabled43513a4/@Element","odata.etag":"W/\"datetime''2020-09-10T23%3A19%3A19.0175285Z''\"","PartitionKey":"pkd43513a4","RowKey":"rkd43513a4","Timestamp":"2020-09-10T23:19:19.0175285Z","test1":"Color.YELLOW","test2":"Color.BLUE","test3":"Color.RED"}' + string: !!python/unicode '{"odata.metadata":"https://storagename.table.core.windows.net/$metadata#uttabled43513a4/@Element","odata.etag":"W/\"datetime''2020-09-10T23%3A51%3A25.711904Z''\"","PartitionKey":"pkd43513a4","RowKey":"rkd43513a4","Timestamp":"2020-09-10T23:51:25.711904Z","test1":"Color.YELLOW","test3":"Color.RED","test2":"Color.BLUE"}' headers: cache-control: - no-cache content-type: - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 date: - - Thu, 10 Sep 2020 23:19:18 GMT + - Thu, 10 Sep 2020 23:51:25 GMT etag: - - W/"datetime'2020-09-10T23%3A19%3A19.0175285Z'" + - W/"datetime'2020-09-10T23%3A51%3A25.711904Z'" server: - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 transfer-encoding: @@ -156,25 +156,25 @@ interactions: Content-Length: - '0' Date: - - Thu, 10 Sep 2020 23:19:19 GMT + - Thu, 10 Sep 2020 23:51:25 GMT User-Agent: - - azsdk-python-data-tables/12.0.0b2 Python/3.8.4 (Windows-10-10.0.19041-SP0) + - azsdk-python-data-tables/12.0.0b2 Python/2.7.18 (Windows-10-10.0.19041) x-ms-date: - - Thu, 10 Sep 2020 23:19:19 GMT + - Thu, 10 Sep 2020 23:51:25 GMT x-ms-version: - '2019-02-02' method: DELETE - uri: https://storagename.table.core.windows.net/Tables('uttabled43513a4') + uri: !!python/unicode https://storagename.table.core.windows.net/Tables('uttabled43513a4') response: body: - string: '' + string: !!python/unicode headers: cache-control: - no-cache content-length: - '0' date: - - Thu, 10 Sep 2020 23:19:18 GMT + - Thu, 10 Sep 2020 23:51:25 GMT server: - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 x-content-type-options: