From 398db2e184b49a81182be6f3c970c953109b7b6c Mon Sep 17 00:00:00 2001 From: Michael Chin Date: Fri, 4 Feb 2022 21:22:21 -0800 Subject: [PATCH 1/5] Convert Decimal type values in GremlinNetwork --- .../network/gremlin/GremlinNetwork.py | 16 +++++- .../network/gremlin/test_gremlin_network.py | 51 +++++++++++++++++-- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/graph_notebook/network/gremlin/GremlinNetwork.py b/src/graph_notebook/network/gremlin/GremlinNetwork.py index 6950804c..7617db6f 100644 --- a/src/graph_notebook/network/gremlin/GremlinNetwork.py +++ b/src/graph_notebook/network/gremlin/GremlinNetwork.py @@ -7,6 +7,7 @@ import json import uuid import logging +from decimal import * from enum import Enum from graph_notebook.network.EventfulNetwork import EventfulNetwork, DEFAULT_GRP @@ -419,7 +420,20 @@ def add_vertex(self, v): for k in v: if str(k) == T_ID: node_id = str(v[k]) - properties[k] = str(v[k]) if isinstance(v[k], dict) else v[k] + + if isinstance(v[k], dict): + properties[k] = str(v[k]) + elif isinstance(v[k], list): + copy_val = v[k] + for i, subvalue in enumerate(copy_val): + if isinstance(subvalue, Decimal): + copy_val[i] = float(subvalue) + properties[k] = copy_val + elif isinstance(v[k], Decimal): + properties[k] = float(v[k]) + else: + properties[k] = v[k] + if not group_is_set: if isinstance(self.group_by_property, dict): try: diff --git a/test/unit/network/gremlin/test_gremlin_network.py b/test/unit/network/gremlin/test_gremlin_network.py index be73522f..0d88977b 100644 --- a/test/unit/network/gremlin/test_gremlin_network.py +++ b/test/unit/network/gremlin/test_gremlin_network.py @@ -4,6 +4,7 @@ """ import unittest +from decimal import * from gremlin_python.structure.graph import Path, Edge, Vertex from gremlin_python.process.traversal import T, Direction from graph_notebook.network.EventfulNetwork import EVENT_ADD_NODE @@ -710,6 +711,48 @@ def test_add_vertex_with_valid_label_and_invalid_tooltip(self): self.assertEqual(node['label'], 'SEA') self.assertEqual(node['title'], 'SEA') + def test_add_vertex_with_Decimal_type_property(self): + vertex = { + T.id: '1234', + T.label: 'airport', + 'type': 'Airport', + 'runways': '4', + 'code': 'SEA', + 'lon': Decimal('-21.940599441500001631766281207092106342315673828125'), + 'lat': Decimal('64.129997253400006229639984667301177978515625') + } + + gn = GremlinNetwork() + gn.add_vertex(vertex) + node = gn.graph.nodes.get(vertex[T.id]) + final_lon_value = node['properties']['lon'] + final_lat_value = node['properties']['lat'] + self.assertEqual(final_lon_value, -21.9405994415) + self.assertEqual(final_lat_value, 64.1299972534) + self.assertIsInstance(final_lon_value, float) + self.assertIsInstance(final_lat_value, float) + + def test_add_vertex_with_Decimal_type_property_in_list(self): + vertex = { + T.id: '1234', + T.label: 'airport', + 'type': ['Airport'], + 'runways': ['4'], + 'code': ['SEA'], + 'lon': [Decimal('-21.940599441500001631766281207092106342315673828125')], + 'lat': [Decimal('64.129997253400006229639984667301177978515625')] + } + + gn = GremlinNetwork() + gn.add_vertex(vertex) + node = gn.graph.nodes.get(vertex[T.id]) + final_lon_value = node['properties']['lon'][0] + final_lat_value = node['properties']['lat'][0] + self.assertEqual(final_lon_value, -21.9405994415) + self.assertEqual(final_lat_value, 64.1299972534) + self.assertIsInstance(final_lon_value, float) + self.assertIsInstance(final_lat_value, float) + def test_add_explicit_type_single_edge_without_edge_property(self): vertex1 = Vertex(id='1') vertex2 = Vertex(id='2') @@ -1777,13 +1820,13 @@ def test_add_path_without_groupby(self): def test_add_path_with_groupby(self): path = Path([], [{'country': ['US'], 'code': ['SEA'], 'longest': [11901], 'city': ['Seattle'], - T.label: 'airport', 'lon': [-122.30899810791], 'type': ['airport'], 'elev': [432], + T.label: 'airport', 'lon': [Decimal('-122.30899810791')], 'type': ['airport'], 'elev': [432], T.id: '22', 'icao': ['KSEA'], 'runways': [3], 'region': ['US-WA'], - 'lat': [47.4490013122559], 'desc': ['Seattle-Tacoma']}, + 'lat': [Decimal('47.4490013122559')], 'desc': ['Seattle-Tacoma']}, {'country': ['US'], 'code': ['ATL'], 'longest': [12390], 'city': ['Atlanta'], - T.label: 'airport', 'lon': [-84.4281005859375], 'type': ['airport'], 'elev': [1026], + T.label: 'airport', 'lon': [Decimal('-84.4281005859375')], 'type': ['airport'], 'elev': [1026], T.id: '1', 'icao': ['KATL'], 'runways': [5], 'region': ['US-GA'], - 'lat': [33.6366996765137], 'desc': ['Hartsfield - Jackson Atlanta International Airport']}]) + 'lat': [Decimal('33.6366996765137')], 'desc': ['Hartsfield - Jackson Atlanta International Airport']}]) gn = GremlinNetwork(group_by_property="code") gn.add_results([path]) node = gn.graph.nodes.get('1') From 18c2d247d952e88fa52cd7d8d362d7bdf7fea186 Mon Sep 17 00:00:00 2001 From: Michael Chin Date: Fri, 4 Feb 2022 21:28:48 -0800 Subject: [PATCH 2/5] replace star import --- test/unit/network/gremlin/test_gremlin_network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/network/gremlin/test_gremlin_network.py b/test/unit/network/gremlin/test_gremlin_network.py index 0d88977b..e532c66b 100644 --- a/test/unit/network/gremlin/test_gremlin_network.py +++ b/test/unit/network/gremlin/test_gremlin_network.py @@ -4,7 +4,7 @@ """ import unittest -from decimal import * +from decimal import Decimal from gremlin_python.structure.graph import Path, Edge, Vertex from gremlin_python.process.traversal import T, Direction from graph_notebook.network.EventfulNetwork import EVENT_ADD_NODE From 8da20eba85829eec4f4a7845c633fde54e351857 Mon Sep 17 00:00:00 2001 From: Michael Chin Date: Sat, 5 Feb 2022 15:15:33 -0800 Subject: [PATCH 3/5] Revert temp test change --- test/unit/network/gremlin/test_gremlin_network.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unit/network/gremlin/test_gremlin_network.py b/test/unit/network/gremlin/test_gremlin_network.py index e532c66b..095ea914 100644 --- a/test/unit/network/gremlin/test_gremlin_network.py +++ b/test/unit/network/gremlin/test_gremlin_network.py @@ -1820,13 +1820,13 @@ def test_add_path_without_groupby(self): def test_add_path_with_groupby(self): path = Path([], [{'country': ['US'], 'code': ['SEA'], 'longest': [11901], 'city': ['Seattle'], - T.label: 'airport', 'lon': [Decimal('-122.30899810791')], 'type': ['airport'], 'elev': [432], + T.label: 'airport', 'lon': ['-122.30899810791'], 'type': ['airport'], 'elev': [432], T.id: '22', 'icao': ['KSEA'], 'runways': [3], 'region': ['US-WA'], - 'lat': [Decimal('47.4490013122559')], 'desc': ['Seattle-Tacoma']}, + 'lat': ['47.4490013122559'], 'desc': ['Seattle-Tacoma']}, {'country': ['US'], 'code': ['ATL'], 'longest': [12390], 'city': ['Atlanta'], - T.label: 'airport', 'lon': [Decimal('-84.4281005859375')], 'type': ['airport'], 'elev': [1026], + T.label: 'airport', 'lon': ['-84.4281005859375'], 'type': ['airport'], 'elev': [1026], T.id: '1', 'icao': ['KATL'], 'runways': [5], 'region': ['US-GA'], - 'lat': [Decimal('33.6366996765137')], 'desc': ['Hartsfield - Jackson Atlanta International Airport']}]) + 'lat': ['33.6366996765137'], 'desc': ['Hartsfield - Jackson Atlanta International Airport']}]) gn = GremlinNetwork(group_by_property="code") gn.add_results([path]) node = gn.graph.nodes.get('1') From fe2e8e5f85bde3680c0b2401cbd2f1fb93c1fbef Mon Sep 17 00:00:00 2001 From: Michael Chin Date: Sat, 5 Feb 2022 15:46:46 -0800 Subject: [PATCH 4/5] Convert decimal type edge properties --- .../network/gremlin/GremlinNetwork.py | 6 +++++- .../unit/network/gremlin/test_gremlin_network.py | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/graph_notebook/network/gremlin/GremlinNetwork.py b/src/graph_notebook/network/gremlin/GremlinNetwork.py index 7617db6f..c81300b0 100644 --- a/src/graph_notebook/network/gremlin/GremlinNetwork.py +++ b/src/graph_notebook/network/gremlin/GremlinNetwork.py @@ -553,10 +553,14 @@ def add_path_edge(self, edge, from_id='', to_id='', data=None): for k in edge: if str(k) == T_ID: edge_id = str(edge[k]) - if type(edge[k]) is dict: # Handle Direction properties, where the value is a map + + if isinstance(edge[k], dict): # Handle Direction properties, where the value is a map properties[k] = get_id(edge[k]) + elif isinstance(edge[k], Decimal): + properties[k] = float(edge[k]) else: properties[k] = edge[k] + if self.edge_display_property is not T_LABEL and not display_is_set: label_property_raw_value = self.get_dict_element_property_value(edge, k, edge_title_plc, self.edge_display_property) diff --git a/test/unit/network/gremlin/test_gremlin_network.py b/test/unit/network/gremlin/test_gremlin_network.py index 095ea914..e47e44f2 100644 --- a/test/unit/network/gremlin/test_gremlin_network.py +++ b/test/unit/network/gremlin/test_gremlin_network.py @@ -1445,6 +1445,22 @@ def test_add_single_edge_with_valid_label_and_invalid_tooltip(self): self.assertEqual(edge['1']['label'], 'v[2]') self.assertEqual(edge['1']['title'], 'v[2]') + def test_add_edge_with_decimal_property(self): + vertex1 = Vertex(id='1') + vertex2 = Vertex(id='2') + + edge1 = {T.id: '1', T.label: 'route', 'outV': 'v[1]', 'inV': 'v[2]', + 'dist': Decimal('917.09438902349805490380928798847027304002305757893')} + + gn = GremlinNetwork() + gn.add_vertex(vertex1) + gn.add_vertex(vertex2) + gn.add_path_edge(edge1, from_id='1', to_id='2') + edge = gn.graph.get_edge_data('1', '2') + edge_dist = edge['1']['properties']['dist'] + self.assertEqual(edge_dist, 917.094389023498) + self.assertIsInstance(edge_dist, float) + def test_add_path_with_integer(self): path = Path([], ['ANC', 3030, 'DFW']) gn = GremlinNetwork() From 842de96dcf0ca899e40d51cec8ec2fb4f9cdaf27 Mon Sep 17 00:00:00 2001 From: Michael Chin Date: Mon, 7 Feb 2022 13:09:35 -0800 Subject: [PATCH 5/5] Update Changelog --- ChangeLog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index dd3c7518..232e9735 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -2,6 +2,9 @@ Starting with v1.31.6, this file will contain a record of major features and updates made in each release of graph-notebook. +## Upcoming +- Fixed handling of Decimal type properties when rendering Gremlin query results ([Link to PR](https://github.com/aws/graph-notebook/pull/256)) + ## Release 3.1.1 (December 21, 2021) - Added new dataset for DiningByFriends, and associated notebook ([Link to PR](https://github.com/aws/graph-notebook/pull/235)) - Added new Neptune ML Sample Application for People Analytics ([Link to PR](https://github.com/aws/graph-notebook/pull/235))