Skip to content

Commit

Permalink
Convert Decimal type results to float for Gremlin (#256)
Browse files Browse the repository at this point in the history
* Convert Decimal type values in GremlinNetwork

* replace star import

* Revert temp test change

* Convert decimal type edge properties

* Update Changelog

Co-authored-by: Michael Chin <[email protected]>
  • Loading branch information
michaelnchin and michaelnchin authored Feb 8, 2022
1 parent 486c441 commit b5d1885
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 6 deletions.
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Starting with v1.31.6, this file will contain a record of major features and upd
- Suppressed default root logger error output ([Link to PR](https://github.com/aws/graph-notebook/pull/248))
- Fixed Gremlin visualizer bug with handling non-string node IDs ([Link to PR](https://github.com/aws/graph-notebook/pull/245))
- Fixed error in openCypher Bolt query metadata output ([Link to PR](https://github.com/aws/graph-notebook/pull/255))
- 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))
Expand Down
22 changes: 20 additions & 2 deletions src/graph_notebook/network/gremlin/GremlinNetwork.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, DEPTH_GRP_KEY, DEFAULT_RAW_GRP_KEY
Expand Down Expand Up @@ -435,7 +436,20 @@ def add_vertex(self, v, path_index: int = -1):
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:
Expand Down Expand Up @@ -571,10 +585,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)
Expand Down
67 changes: 63 additions & 4 deletions test/unit/network/gremlin/test_gremlin_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""

import unittest
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
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -1402,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()
Expand Down Expand Up @@ -1863,13 +1922,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': ['-122.30899810791'], 'type': ['airport'], 'elev': [432],
T.id: '22', 'icao': ['KSEA'], 'runways': [3], 'region': ['US-WA'],
'lat': [47.4490013122559], 'desc': ['Seattle-Tacoma']},
'lat': ['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': ['-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': ['33.6366996765137'], 'desc': ['Hartsfield - Jackson Atlanta International Airport']}])
gn = GremlinNetwork(group_by_property="code")
gn.add_results([path])
node = gn.graph.nodes.get('1')
Expand Down

0 comments on commit b5d1885

Please sign in to comment.