Skip to content

Commit fd97f65

Browse files
author
Yi-Ting Lee
committed
feature: query lineage visualizer for general case
edge.association_type added style changes of graph
1 parent e0c59c2 commit fd97f65

File tree

1 file changed

+103
-13
lines changed

1 file changed

+103
-13
lines changed

src/sagemaker/lineage/query.py

Lines changed: 103 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,12 @@ def __str__(self):
9797
9898
Format:
9999
{
100-
'source_arn': 'string', 'destination_arn': 'string',
100+
'source_arn': 'string', 'destination_arn': 'string',
101101
'association_type': 'string'
102102
}
103-
103+
104104
"""
105-
return (str(self.__dict__))
105+
return str(self.__dict__)
106106

107107

108108
class Vertex:
@@ -147,13 +147,13 @@ def __str__(self):
147147
148148
Format:
149149
{
150-
'arn': 'string', 'lineage_entity': 'string',
151-
'lineage_source': 'string',
150+
'arn': 'string', 'lineage_entity': 'string',
151+
'lineage_source': 'string',
152152
'_session': <sagemaker.session.Session object>
153153
}
154-
154+
155155
"""
156-
return (str(self.__dict__))
156+
return str(self.__dict__)
157157

158158
def to_lineage_object(self):
159159
"""Convert the ``Vertex`` object to its corresponding lineage object.
@@ -226,29 +226,119 @@ def __init__(
226226

227227
def __str__(self):
228228
"""Define string representation of ``LineageQueryResult``.
229-
229+
230230
Format:
231231
{
232232
'edges':[
233233
{
234-
'source_arn': 'string', 'destination_arn': 'string',
234+
'source_arn': 'string', 'destination_arn': 'string',
235235
'association_type': 'string'
236236
},
237237
...
238238
]
239239
'vertices':[
240240
{
241-
'arn': 'string', 'lineage_entity': 'string',
242-
'lineage_source': 'string',
241+
'arn': 'string', 'lineage_entity': 'string',
242+
'lineage_source': 'string',
243243
'_session': <sagemaker.session.Session object>
244244
},
245245
...
246246
]
247247
}
248-
248+
249249
"""
250250
result_dict = vars(self)
251-
return (str({k: [vars(val) for val in v] for k, v in result_dict.items()}))
251+
return str({k: [vars(val) for val in v] for k, v in result_dict.items()})
252+
253+
def _import_visual_modules(self):
254+
"""Import modules needed for visualization."""
255+
import dash_cytoscape as cyto
256+
257+
from jupyter_dash import JupyterDash
258+
259+
from dash import html
260+
261+
return cyto, JupyterDash, html
262+
263+
def _get_verts(self):
264+
"""Convert vertices to tuple format for visualizer."""
265+
verts = []
266+
for vert in self.vertices:
267+
verts.append((vert.arn, vert.lineage_source))
268+
return verts
269+
270+
def _get_edges(self):
271+
"""Convert edges to tuple format for visualizer."""
272+
edges = []
273+
for edge in self.edges:
274+
edges.append((edge.source_arn, edge.destination_arn, edge.association_type))
275+
return edges
276+
277+
def visualize(self):
278+
"""Visualize lineage query result."""
279+
cyto, JupyterDash, html = self._import_visual_modules()
280+
281+
cyto.load_extra_layouts() # load "klay" layout (hierarchical layout) from extra layouts
282+
app = JupyterDash(__name__)
283+
284+
verts = self._get_verts()
285+
edges = self._get_edges()
286+
287+
nodes = [
288+
{
289+
"data": {"id": id, "label": label},
290+
}
291+
for id, label in verts
292+
]
293+
294+
edges = [
295+
{"data": {"source": source, "target": target, "label": label}}
296+
for source, target, label in edges
297+
]
298+
299+
elements = nodes + edges
300+
301+
app.layout = html.Div(
302+
[
303+
cyto.Cytoscape(
304+
id="cytoscape-layout-1",
305+
elements=elements,
306+
style={"width": "100%", "height": "350px"},
307+
layout={"name": "klay"},
308+
stylesheet=[
309+
{
310+
"selector": "node",
311+
"style": {
312+
"label": "data(label)",
313+
"font-size": "3.5vw",
314+
"height": "10vw",
315+
"width": "10vw",
316+
},
317+
},
318+
{
319+
"selector": "edge",
320+
"style": {
321+
"label": "data(label)",
322+
"color": "gray",
323+
"text-halign": "left",
324+
"text-margin-y": "3px",
325+
"text-margin-x": "-2px",
326+
"font-size": "3%",
327+
"width": "1%",
328+
"curve-style": "taxi",
329+
"target-arrow-color": "gray",
330+
"target-arrow-shape": "triangle",
331+
"line-color": "gray",
332+
"arrow-scale": "0.5",
333+
},
334+
},
335+
],
336+
responsive=True,
337+
)
338+
]
339+
)
340+
341+
return app.run_server(mode="inline")
252342

253343

254344
class LineageFilter(object):

0 commit comments

Comments
 (0)