pyegeria 1.5.1.1.11__py3-none-any.whl → 1.5.1.1.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- commands/cat/list_terms.py +21 -13
- pyegeria/glossary_manager_omvs.py +254 -8
- {pyegeria-1.5.1.1.11.dist-info → pyegeria-1.5.1.1.12.dist-info}/METADATA +1 -1
- {pyegeria-1.5.1.1.11.dist-info → pyegeria-1.5.1.1.12.dist-info}/RECORD +7 -7
- {pyegeria-1.5.1.1.11.dist-info → pyegeria-1.5.1.1.12.dist-info}/LICENSE +0 -0
- {pyegeria-1.5.1.1.11.dist-info → pyegeria-1.5.1.1.12.dist-info}/WHEEL +0 -0
- {pyegeria-1.5.1.1.11.dist-info → pyegeria-1.5.1.1.12.dist-info}/entry_points.txt +0 -0
commands/cat/list_terms.py
CHANGED
@@ -73,12 +73,12 @@ def display_glossary_terms(
|
|
73
73
|
)
|
74
74
|
table.add_column("Term Name")
|
75
75
|
table.add_column("Qualified Name / GUID")
|
76
|
-
table.add_column("Glossary")
|
77
76
|
table.add_column("Abbreviation")
|
78
77
|
table.add_column("Summary")
|
79
78
|
table.add_column("Description")
|
80
79
|
table.add_column("Version Id")
|
81
|
-
|
80
|
+
table.add_column("Glossary")
|
81
|
+
table.add_column("Status")
|
82
82
|
|
83
83
|
terms = g_client.find_glossary_terms(
|
84
84
|
search_string,
|
@@ -98,7 +98,7 @@ def display_glossary_terms(
|
|
98
98
|
style = "bright_white on black"
|
99
99
|
if type(terms) is str:
|
100
100
|
return table
|
101
|
-
|
101
|
+
glossary_info = {}
|
102
102
|
for term in sorted_terms:
|
103
103
|
props = term.get("glossaryTermProperties", "None")
|
104
104
|
if props == "None":
|
@@ -113,19 +113,31 @@ def display_glossary_terms(
|
|
113
113
|
description = Text(props.get("description", " "), style=style)
|
114
114
|
version = Text(props.get("publishVersionIdentifier", " "), style=style)
|
115
115
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
116
|
+
classifications = term["elementHeader"]["classifications"]
|
117
|
+
glossary_guid = None
|
118
|
+
for c in classifications:
|
119
|
+
if c["classificationName"] == "Anchors":
|
120
|
+
glossary_guid = c["classificationProperties"]["anchorGUID"]
|
121
|
+
|
122
|
+
if glossary_guid and glossary_guid in glossary_info:
|
123
|
+
glossary_name = glossary_info[glossary_guid]
|
124
|
+
elif glossary_guid:
|
125
|
+
g = g_client.get_glossary_for_term(term_guid)
|
126
|
+
glossary_name = g["glossaryProperties"].get("displayName", "---")
|
127
|
+
glossary_info[glossary_guid] = glossary_name
|
128
|
+
else:
|
129
|
+
glossary_name = "---"
|
130
|
+
|
131
|
+
term_status = term["elementHeader"]["status"]
|
120
132
|
table.add_row(
|
121
133
|
display_name,
|
122
134
|
q_name,
|
123
|
-
glossary_name,
|
124
135
|
abbrev,
|
125
136
|
summary,
|
126
137
|
description,
|
127
138
|
version,
|
128
|
-
|
139
|
+
glossary_name,
|
140
|
+
term_status,
|
129
141
|
style="bold white on black",
|
130
142
|
)
|
131
143
|
|
@@ -133,10 +145,6 @@ def display_glossary_terms(
|
|
133
145
|
return table
|
134
146
|
|
135
147
|
try:
|
136
|
-
# with Live(generate_table(), refresh_per_second=4, screen=True) as live:
|
137
|
-
# while True:
|
138
|
-
# time.sleep(2)
|
139
|
-
# live.update(generate_table(search_string))
|
140
148
|
console = Console(
|
141
149
|
style="bold bright_white on black", width=width, force_terminal=not jupyter
|
142
150
|
)
|
@@ -67,7 +67,7 @@ class GlossaryManager(GlossaryBrowser):
|
|
67
67
|
|
68
68
|
def __validate_term_status__(self, status: str) -> bool:
|
69
69
|
"""Return True if the status is a legal glossary term status"""
|
70
|
-
recognized_term_status =
|
70
|
+
recognized_term_status = self.get_glossary_term_statuses()
|
71
71
|
return status in recognized_term_status
|
72
72
|
|
73
73
|
async def _async_create_glossary(
|
@@ -103,7 +103,7 @@ class GlossaryManager(GlossaryBrowser):
|
|
103
103
|
"class": "ReferenceableRequestBody",
|
104
104
|
"elementProperties": {
|
105
105
|
"class": "GlossaryProperties",
|
106
|
-
"qualifiedName": f"Glossary
|
106
|
+
"qualifiedName": f"Glossary:{display_name}-{time.asctime()}",
|
107
107
|
"displayName": display_name,
|
108
108
|
"description": description,
|
109
109
|
"language": language,
|
@@ -187,6 +187,120 @@ class GlossaryManager(GlossaryBrowser):
|
|
187
187
|
response = loop.run_until_complete(self._async_delete_glossary(glossary_guid))
|
188
188
|
return response
|
189
189
|
|
190
|
+
async def _async_update_glossary(
|
191
|
+
self,
|
192
|
+
glossary_guid: str,
|
193
|
+
body: dict,
|
194
|
+
is_merge_update: bool = True,
|
195
|
+
for_lineage: bool = False,
|
196
|
+
for_duplicate_processing: bool = False,
|
197
|
+
) -> None:
|
198
|
+
"""Update Glossary.
|
199
|
+
|
200
|
+
Async version.
|
201
|
+
|
202
|
+
Parameters
|
203
|
+
----------
|
204
|
+
glossary_guid: str
|
205
|
+
The ID of the glossary to update.
|
206
|
+
body: dict
|
207
|
+
A dict containing the properties to update.
|
208
|
+
is_merge_update: bool, optional, default = True
|
209
|
+
If true, then only those properties specified in the body will be updated. If false, then all the
|
210
|
+
properties of the glossary will be replaced with those of the body.
|
211
|
+
for_lineage: bool, optional, default = False
|
212
|
+
Normally false. Used when we want to retrieve elements that have been delete but have a Memento entry.
|
213
|
+
for_duplicate_processing: bool, optional, default = False
|
214
|
+
Normally false. Set true when Egeria is told to skip deduplication because another system will do it.
|
215
|
+
|
216
|
+
|
217
|
+
Returns
|
218
|
+
-------
|
219
|
+
None
|
220
|
+
|
221
|
+
Notes
|
222
|
+
-----
|
223
|
+
|
224
|
+
Sample body:
|
225
|
+
|
226
|
+
{
|
227
|
+
"class" : "ReferenceableRequestBody",
|
228
|
+
"elementProperties" :
|
229
|
+
{
|
230
|
+
"class" : "GlossaryProperties",
|
231
|
+
"qualifiedName" : "MyGlossary",
|
232
|
+
"displayName" : "My Glossary",
|
233
|
+
"description" : "This is an example glossary"
|
234
|
+
}
|
235
|
+
}
|
236
|
+
"""
|
237
|
+
|
238
|
+
url = (
|
239
|
+
f"{self.platform_url}/servers/{self.view_server}/api/open-metadata/glossary-manager/glossaries/"
|
240
|
+
f"{glossary_guid}/update?isMergeUpdate={is_merge_update}&forLineage={for_lineage}&"
|
241
|
+
f"forDuplicateProcessing={for_duplicate_processing}"
|
242
|
+
)
|
243
|
+
|
244
|
+
await self._async_make_request("POST", url, body_slimmer(body))
|
245
|
+
return
|
246
|
+
|
247
|
+
def update_glossary(
|
248
|
+
self,
|
249
|
+
glossary_guid: str,
|
250
|
+
body: dict,
|
251
|
+
is_merge_update: bool = True,
|
252
|
+
for_lineage: bool = False,
|
253
|
+
for_duplicate_processing: bool = False,
|
254
|
+
) -> None:
|
255
|
+
"""Update Glossary.
|
256
|
+
|
257
|
+
Parameters
|
258
|
+
----------
|
259
|
+
glossary_guid: str
|
260
|
+
The ID of the glossary to update.
|
261
|
+
body: dict
|
262
|
+
A dict containing the properties to update.
|
263
|
+
is_merge_update: bool, optional, default = True
|
264
|
+
If true, then only those properties specified in the body will be updated. If false, then all the
|
265
|
+
properties of the glossary will be replaced with those of the body.
|
266
|
+
for_lineage: bool, optional, default = False
|
267
|
+
Normally false. Used when we want to retrieve elements that have been delete but have a Memento entry.
|
268
|
+
for_duplicate_processing: bool, optional, default = False
|
269
|
+
Normally false. Set true when Egeria is told to skip deduplication because another system will do it.
|
270
|
+
|
271
|
+
|
272
|
+
Returns
|
273
|
+
-------
|
274
|
+
None
|
275
|
+
|
276
|
+
Notes
|
277
|
+
-----
|
278
|
+
|
279
|
+
Sample body:
|
280
|
+
|
281
|
+
{
|
282
|
+
"class" : "ReferenceableRequestBody",
|
283
|
+
"elementProperties" :
|
284
|
+
{
|
285
|
+
"class" : "GlossaryProperties",
|
286
|
+
"qualifiedName" : "MyGlossary",
|
287
|
+
"displayName" : "My Glossary",
|
288
|
+
"description" : "This is an example glossary"
|
289
|
+
}
|
290
|
+
}
|
291
|
+
"""
|
292
|
+
loop = asyncio.get_event_loop()
|
293
|
+
loop.run_until_complete(
|
294
|
+
self._async_update_glossary(
|
295
|
+
glossary_guid,
|
296
|
+
body,
|
297
|
+
is_merge_update,
|
298
|
+
for_lineage,
|
299
|
+
for_duplicate_processing,
|
300
|
+
)
|
301
|
+
)
|
302
|
+
return
|
303
|
+
|
190
304
|
#
|
191
305
|
# Glossaries
|
192
306
|
#
|
@@ -1473,7 +1587,7 @@ class GlossaryManager(GlossaryBrowser):
|
|
1473
1587
|
version = row.get("Version Identifier", "1.0")
|
1474
1588
|
status = row.get("Status", "DRAFT").upper()
|
1475
1589
|
|
1476
|
-
#
|
1590
|
+
# quality check the row
|
1477
1591
|
if len(term_name) < 2:
|
1478
1592
|
term_info.append(
|
1479
1593
|
{
|
@@ -1494,12 +1608,64 @@ class GlossaryManager(GlossaryBrowser):
|
|
1494
1608
|
}
|
1495
1609
|
)
|
1496
1610
|
continue
|
1611
|
+
if upsert:
|
1612
|
+
# If upsert is set we need to see if it can be done (there must be a valid qualified name) and then
|
1613
|
+
# do the update for the row - if there is no qualified name we will treat the row as an insert.
|
1614
|
+
if qualified_name:
|
1615
|
+
body = {
|
1616
|
+
"class": "ReferenceableRequestBody",
|
1617
|
+
"elementProperties": {
|
1618
|
+
"class": "GlossaryTermProperties",
|
1619
|
+
"qualifiedName": qualified_name,
|
1620
|
+
"displayName": term_name,
|
1621
|
+
"summary": summary,
|
1622
|
+
"description": description,
|
1623
|
+
"abbreviation": abbrev,
|
1624
|
+
"examples": examples,
|
1625
|
+
"usage": usage,
|
1626
|
+
"publishVersionIdentifier": version,
|
1627
|
+
},
|
1628
|
+
"initialStatus": status,
|
1629
|
+
}
|
1630
|
+
term_stuff = self.get_terms_by_name(
|
1631
|
+
qualified_name, glossary_guid
|
1632
|
+
)
|
1633
|
+
if type(term_stuff) is str:
|
1634
|
+
# An existing term was not found with that qualified name
|
1635
|
+
term_info.append(
|
1636
|
+
{
|
1637
|
+
"term_name": term_name,
|
1638
|
+
"qualified_name": qualified_name,
|
1639
|
+
"term_guid": term_guid,
|
1640
|
+
"error": "Matching term not found - skipping",
|
1641
|
+
}
|
1642
|
+
)
|
1643
|
+
continue
|
1644
|
+
else:
|
1645
|
+
# An existing term was found - so update it!
|
1646
|
+
term_guid = term_stuff["elementHeader"]["guid"]
|
1647
|
+
self.update_term(
|
1648
|
+
term_guid, body_slimmer(body), is_merge_update=True
|
1649
|
+
)
|
1650
|
+
term_info.append(
|
1651
|
+
{
|
1652
|
+
"term_name": term_name,
|
1653
|
+
"qualified_name": qualified_name,
|
1654
|
+
"term_guid": term_guid,
|
1655
|
+
"updated": "the term was updated",
|
1656
|
+
}
|
1657
|
+
)
|
1658
|
+
continue
|
1497
1659
|
|
1660
|
+
# Add the term
|
1661
|
+
term_qualified_name = (
|
1662
|
+
f"GlossaryTerm: {term_name} - {datetime.now().isoformat()}"
|
1663
|
+
)
|
1498
1664
|
body = {
|
1499
1665
|
"class": "ReferenceableRequestBody",
|
1500
1666
|
"elementProperties": {
|
1501
1667
|
"class": "GlossaryTermProperties",
|
1502
|
-
"qualifiedName":
|
1668
|
+
"qualifiedName": term_qualified_name,
|
1503
1669
|
"displayName": term_name,
|
1504
1670
|
"summary": summary,
|
1505
1671
|
"description": description,
|
@@ -1511,9 +1677,6 @@ class GlossaryManager(GlossaryBrowser):
|
|
1511
1677
|
"initialStatus": status,
|
1512
1678
|
}
|
1513
1679
|
|
1514
|
-
# if upsert:
|
1515
|
-
# if len(qualified_name) > 5:
|
1516
|
-
# existing_term =
|
1517
1680
|
# Add the term
|
1518
1681
|
term_guid = self.create_controlled_glossary_term(
|
1519
1682
|
glossary_guid, body_slimmer(body)
|
@@ -1521,12 +1684,95 @@ class GlossaryManager(GlossaryBrowser):
|
|
1521
1684
|
term_info.append(
|
1522
1685
|
{
|
1523
1686
|
"term_name": term_name,
|
1524
|
-
"qualified_name":
|
1687
|
+
"qualified_name": term_qualified_name,
|
1525
1688
|
"term_guid": term_guid,
|
1526
1689
|
}
|
1527
1690
|
)
|
1528
1691
|
return term_info
|
1529
1692
|
|
1693
|
+
async def _async_export_glossary_to_csv(
|
1694
|
+
self, glossary_guid: str, target_file: str
|
1695
|
+
) -> int:
|
1696
|
+
"""Export all the terms in a glossary to a CSV file. Async version
|
1697
|
+
|
1698
|
+
Parameters:
|
1699
|
+
-----------
|
1700
|
+
glossary_guid: str
|
1701
|
+
Identity of the glossary to export.
|
1702
|
+
target_file: str
|
1703
|
+
Complete file name with path and extension to export to.
|
1704
|
+
|
1705
|
+
Returns:
|
1706
|
+
int: Number of rows exported.
|
1707
|
+
"""
|
1708
|
+
|
1709
|
+
term_list = await self._async_get_terms_for_glossary(glossary_guid)
|
1710
|
+
|
1711
|
+
header = [
|
1712
|
+
"Term Name",
|
1713
|
+
"Qualified Name",
|
1714
|
+
"Abbreviation",
|
1715
|
+
"Summary",
|
1716
|
+
"Description",
|
1717
|
+
"Examples",
|
1718
|
+
"Usage",
|
1719
|
+
"Version Identifier",
|
1720
|
+
"Status",
|
1721
|
+
]
|
1722
|
+
|
1723
|
+
with open(target_file, mode="w") as file:
|
1724
|
+
csv_writer = csv.DictWriter(file, fieldnames=header)
|
1725
|
+
csv_writer.writeheader()
|
1726
|
+
count = 0
|
1727
|
+
for term in term_list:
|
1728
|
+
term_name = term["glossaryTermProperties"]["displayName"]
|
1729
|
+
qualified_name = term["glossaryTermProperties"]["qualifiedName"]
|
1730
|
+
abbrev = term["glossaryTermProperties"]["abbreviation"]
|
1731
|
+
summary = term["glossaryTermProperties"]["summary"]
|
1732
|
+
description = term["glossaryTermProperties"]["description"]
|
1733
|
+
examples = term["glossaryTermProperties"]["examples"]
|
1734
|
+
usage = term["glossaryTermProperties"]["usage"]
|
1735
|
+
version = term["glossaryTermProperties"]["publishVersionIdentifier"]
|
1736
|
+
status = term["elementHeader"]["status"]
|
1737
|
+
|
1738
|
+
csv_writer.writerow(
|
1739
|
+
{
|
1740
|
+
"Term Name": term_name,
|
1741
|
+
"Qualified Name": qualified_name,
|
1742
|
+
"Abbreviation": abbrev,
|
1743
|
+
"Summary": summary,
|
1744
|
+
"Description": description,
|
1745
|
+
"Examples": examples,
|
1746
|
+
"Usage": usage,
|
1747
|
+
"Version Identifier": version,
|
1748
|
+
"Status": status,
|
1749
|
+
}
|
1750
|
+
)
|
1751
|
+
|
1752
|
+
count += 1
|
1753
|
+
return count
|
1754
|
+
|
1755
|
+
def export_glossary_to_csv(self, glossary_guid: str, target_file: str) -> int:
|
1756
|
+
"""Export all the terms in a glossary to a CSV file.
|
1757
|
+
|
1758
|
+
Parameters:
|
1759
|
+
-----------
|
1760
|
+
glossary_guid: str
|
1761
|
+
Identity of the glossary to export.
|
1762
|
+
target_file: str
|
1763
|
+
Complete file name with path and extension to export to.
|
1764
|
+
|
1765
|
+
Returns:
|
1766
|
+
int: Number of rows exported.
|
1767
|
+
"""
|
1768
|
+
|
1769
|
+
loop = asyncio.get_event_loop()
|
1770
|
+
response = loop.run_until_complete(
|
1771
|
+
self._async_export_glossary_to_csv(glossary_guid, target_file)
|
1772
|
+
)
|
1773
|
+
|
1774
|
+
return response
|
1775
|
+
|
1530
1776
|
async def _async_create_term_copy(
|
1531
1777
|
self,
|
1532
1778
|
glossary_guid: str,
|
@@ -16,7 +16,7 @@ commands/cat/list_deployed_databases.py,sha256=HE8nG-mIlxa9iSUEH-n71o-G2a4ss1Zza
|
|
16
16
|
commands/cat/list_projects.py,sha256=Jzs-DtIpPhCH-gY4PYT6mnRBWnEf4m18TFfcw8UymNU,8011
|
17
17
|
commands/cat/list_relationships.py,sha256=U9f78cOi4HyaacqNaFSMq_7rRxVcEczvwPv468GYw3Q,5869
|
18
18
|
commands/cat/list_tech_types.py,sha256=20T4v6L5qeebSsaL1nGkFMDAIsy2W3A3SMm1RcgFoh0,4609
|
19
|
-
commands/cat/list_terms.py,sha256=
|
19
|
+
commands/cat/list_terms.py,sha256=8aS_TwQefU7FCqQiMIuX7BHRAcPRhyKosULEAOLfhyw,6777
|
20
20
|
commands/cat/list_todos.py,sha256=iPxHRyW3X5tiREio4TUOwRPvNPjU0gxm3pVnUI79ir4,6542
|
21
21
|
commands/cat/list_user_ids.py,sha256=7JinL7rknPbGusIb8ikXKEaV1vvbuvx_WWtbmlfS_DY,5093
|
22
22
|
commands/cli/__init__.py,sha256=hpTVSMP2gnPRhcAZPdeUEsQ-eaDySlXlk239dNWYmng,292
|
@@ -92,7 +92,7 @@ pyegeria/egeria_tech_client.py,sha256=7NfqpJFft5GR4NPRDVDw22L9caHbXB8fhx0TAf6qEo
|
|
92
92
|
pyegeria/feedback_manager_omvs.py,sha256=B66e3ZCaC_dirb0mcb2Nz3PYh2ZKsoMAYNOb3euNiro,152931
|
93
93
|
pyegeria/full_omag_server_config.py,sha256=LBnqUiz1ofBdlKBzECFs_pQbdJwcWigAukWHGJRR2nU,47340
|
94
94
|
pyegeria/glossary_browser_omvs.py,sha256=NcitYaZJqwVODBO5zBtWpXPNUJJ3DKzEbRaOFSAyUlg,93554
|
95
|
-
pyegeria/glossary_manager_omvs.py,sha256=
|
95
|
+
pyegeria/glossary_manager_omvs.py,sha256=iz1tmLaoSWh35ZNS4kow5ctqMxllYGs98LbjQy2kg6U,126262
|
96
96
|
pyegeria/mermaid_utilities.py,sha256=GXiS-subb5nJcDqlThZWX2T8WspU1neFfhf4TxRoMh4,8344
|
97
97
|
pyegeria/my_profile_omvs.py,sha256=DyECbUFEcgokrIbzdMMNljC3bqfqKGXAF2wZEpzvRYs,34666
|
98
98
|
pyegeria/platform_services.py,sha256=CJIOYIFEbcIGwdWlApAQcXxZTsdrhFtpJcm4O3p7dG0,41646
|
@@ -104,8 +104,8 @@ pyegeria/template_manager_omvs.py,sha256=heqbKeum5hPCHap4r1RUZU8YB3QaQlxVNbq4GZi
|
|
104
104
|
pyegeria/utils.py,sha256=1h6bwveadd6GpbnGLTmqPBmBk68QvxdjGTI9RfbrgKY,5415
|
105
105
|
pyegeria/valid_metadata_omvs.py,sha256=tfCGXed5LLt59YA8uZNNtd9UJ-lRZfPU_uZxK31Yux0,65069
|
106
106
|
pyegeria/x_action_author_omvs.py,sha256=xu1IQ0YbhIKi17C5a7Aq9u1Az2czwahNPpX9czmyVxE,6454
|
107
|
-
pyegeria-1.5.1.1.
|
108
|
-
pyegeria-1.5.1.1.
|
109
|
-
pyegeria-1.5.1.1.
|
110
|
-
pyegeria-1.5.1.1.
|
111
|
-
pyegeria-1.5.1.1.
|
107
|
+
pyegeria-1.5.1.1.12.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
108
|
+
pyegeria-1.5.1.1.12.dist-info/METADATA,sha256=m48ON9KQAcvs49TjxyLw4cu6OZkd3qnO4ElzA0ResI0,2998
|
109
|
+
pyegeria-1.5.1.1.12.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
110
|
+
pyegeria-1.5.1.1.12.dist-info/entry_points.txt,sha256=aSpiaOuOEL1QBfuIGOaATzDCihpVOyvIK1XCQHK3uRc,4186
|
111
|
+
pyegeria-1.5.1.1.12.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|