pyegeria 5.3.10__py3-none-any.whl → 5.4.0__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.
Files changed (163) hide show
  1. commands/cat/debug_log +2806 -0
  2. commands/cat/debug_log.2025-07-15_14-28-38_087378.zip +0 -0
  3. commands/cat/debug_log.2025-07-16_15-48-50_037087.zip +0 -0
  4. commands/cat/dr_egeria_command_help.py +273 -0
  5. commands/cat/dr_egeria_md.py +90 -20
  6. commands/cat/glossary_actions.py +2 -2
  7. commands/cat/list_collections.py +24 -10
  8. commands/cat/list_data_designer.py +183 -0
  9. md_processing/__init__.py +28 -5
  10. md_processing/data/commands.json +31474 -1096
  11. md_processing/dr_egeria_outbox-pycharm/.obsidian/app.json +1 -0
  12. md_processing/dr_egeria_outbox-pycharm/.obsidian/appearance.json +1 -0
  13. md_processing/dr_egeria_outbox-pycharm/.obsidian/core-plugins.json +31 -0
  14. md_processing/dr_egeria_outbox-pycharm/.obsidian/workspace.json +177 -0
  15. md_processing/dr_egeria_outbox-pycharm/monday/processed-2025-07-14 12:38-data_designer_out.md +663 -0
  16. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +719 -0
  17. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +41 -0
  18. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +33 -0
  19. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +192 -0
  20. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-16 19:15-gov_def2.md +527 -0
  21. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 12:08-gov_def2.md +527 -0
  22. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 14:27-gov_def2.md +474 -0
  23. md_processing/family_docs/Data Designer/Create_Data_Class.md +164 -0
  24. md_processing/family_docs/Data Designer/Create_Data_Dictionary.md +30 -0
  25. md_processing/family_docs/Data Designer/Create_Data_Field.md +162 -0
  26. md_processing/family_docs/Data Designer/Create_Data_Specification.md +36 -0
  27. md_processing/family_docs/Data Designer/Create_Data_Structure.md +38 -0
  28. md_processing/family_docs/Data Designer/View_Data_Classes.md +78 -0
  29. md_processing/family_docs/Data Designer/View_Data_Dictionaries.md +78 -0
  30. md_processing/family_docs/Data Designer/View_Data_Fields.md +78 -0
  31. md_processing/family_docs/Data Designer/View_Data_Specifications.md +78 -0
  32. md_processing/family_docs/Data Designer/View_Data_Structures.md +78 -0
  33. md_processing/family_docs/Data Designer.md +842 -0
  34. md_processing/family_docs/Digital Product Manager/Add_Member->Collection.md +42 -0
  35. md_processing/family_docs/Digital Product Manager/Attach_Collection->Resource.md +36 -0
  36. md_processing/family_docs/Digital Product Manager/Create_Agreement.md +96 -0
  37. md_processing/family_docs/Digital Product Manager/Create_Data_Sharing_Agreement.md +72 -0
  38. md_processing/family_docs/Digital Product Manager/Create_DigitalSubscription.md +102 -0
  39. md_processing/family_docs/Digital Product Manager/Create_Digital_Product.md +134 -0
  40. md_processing/family_docs/Digital Product Manager/Link_Agreement_Items.md +60 -0
  41. md_processing/family_docs/Digital Product Manager/Link_Contracts.md +26 -0
  42. md_processing/family_docs/Digital Product Manager/Link_Digital_Product_-_Digital_Product.md +30 -0
  43. md_processing/family_docs/Digital Product Manager/Link_Subscribers.md +48 -0
  44. md_processing/family_docs/Digital Product Manager.md +668 -0
  45. md_processing/family_docs/Glossary/Attach_Category_Parent.md +18 -0
  46. md_processing/family_docs/Glossary/Attach_Term-Term_Relationship.md +26 -0
  47. md_processing/family_docs/Glossary/Create_Category.md +38 -0
  48. md_processing/family_docs/Glossary/Create_Glossary.md +42 -0
  49. md_processing/family_docs/Glossary/Create_Term.md +70 -0
  50. md_processing/family_docs/Glossary.md +206 -0
  51. md_processing/family_docs/Governance Officer/Create_Business_Imperative.md +106 -0
  52. md_processing/family_docs/Governance Officer/Create_Certification_Type.md +112 -0
  53. md_processing/family_docs/Governance Officer/Create_Governance_Approach.md +114 -0
  54. md_processing/family_docs/Governance Officer/Create_Governance_Obligation.md +114 -0
  55. md_processing/family_docs/Governance Officer/Create_Governance_Principle.md +114 -0
  56. md_processing/family_docs/Governance Officer/Create_Governance_Procedure.md +128 -0
  57. md_processing/family_docs/Governance Officer/Create_Governance_Process.md +122 -0
  58. md_processing/family_docs/Governance Officer/Create_Governance_Processing_Purpose.md +106 -0
  59. md_processing/family_docs/Governance Officer/Create_Governance_Responsibility.md +122 -0
  60. md_processing/family_docs/Governance Officer/Create_Governance_Rule.md +122 -0
  61. md_processing/family_docs/Governance Officer/Create_Governance_Strategy.md +106 -0
  62. md_processing/family_docs/Governance Officer/Create_License_Type.md +112 -0
  63. md_processing/family_docs/Governance Officer/Create_Naming_Standard_Rule.md +122 -0
  64. md_processing/family_docs/Governance Officer/Create_Regulation_Article.md +106 -0
  65. md_processing/family_docs/Governance Officer/Create_Regulation_Definition.md +118 -0
  66. md_processing/family_docs/Governance Officer/Create_Security_Access_Control.md +114 -0
  67. md_processing/family_docs/Governance Officer/Create_Security_Group.md +120 -0
  68. md_processing/family_docs/Governance Officer/Create_Service_Level_Objectives.md +122 -0
  69. md_processing/family_docs/Governance Officer/Create_Threat_Definition.md +106 -0
  70. md_processing/family_docs/Governance Officer/Link_Governance_Controls.md +32 -0
  71. md_processing/family_docs/Governance Officer/Link_Governance_Drivers.md +32 -0
  72. md_processing/family_docs/Governance Officer/Link_Governance_Policies.md +32 -0
  73. md_processing/family_docs/Governance Officer/View_Governance_Definitions.md +82 -0
  74. md_processing/family_docs/Governance Officer.md +2412 -0
  75. md_processing/family_docs/Solution Architect/Create_Information_Supply_Chain.md +70 -0
  76. md_processing/family_docs/Solution Architect/Create_Solution_Blueprint.md +44 -0
  77. md_processing/family_docs/Solution Architect/Create_Solution_Component.md +96 -0
  78. md_processing/family_docs/Solution Architect/Create_Solution_Role.md +66 -0
  79. md_processing/family_docs/Solution Architect/Link_Information_Supply_Chain_Peers.md +32 -0
  80. md_processing/family_docs/Solution Architect/Link_Solution_Component_Peers.md +32 -0
  81. md_processing/family_docs/Solution Architect/View_Information_Supply_Chains.md +32 -0
  82. md_processing/family_docs/Solution Architect/View_Solution_Blueprints.md +32 -0
  83. md_processing/family_docs/Solution Architect/View_Solution_Components.md +32 -0
  84. md_processing/family_docs/Solution Architect/View_Solution_Roles.md +32 -0
  85. md_processing/family_docs/Solution Architect.md +490 -0
  86. md_processing/md_commands/data_designer_commands.py +1192 -710
  87. md_processing/md_commands/glossary_commands.py +19 -32
  88. md_processing/md_commands/governance_officer_commands.py +420 -0
  89. md_processing/md_commands/product_manager_commands.py +1180 -0
  90. md_processing/md_commands/project_commands.py +5 -2
  91. md_processing/md_commands/solution_architect_commands.py +1140 -0
  92. md_processing/md_processing_utils/common_md_proc_utils.py +288 -96
  93. md_processing/md_processing_utils/common_md_utils.py +205 -6
  94. md_processing/md_processing_utils/debug_log +574 -0
  95. md_processing/md_processing_utils/dr-egeria-help-2025-07-17T17:22:09.md +2065 -0
  96. md_processing/md_processing_utils/extraction_utils.py +1 -1
  97. md_processing/md_processing_utils/generate_dr_help.py +165 -0
  98. md_processing/md_processing_utils/generate_md_cmd_templates.py +143 -0
  99. md_processing/md_processing_utils/generate_md_templates.py +92 -0
  100. md_processing/md_processing_utils/generated_help_terms.md +842 -0
  101. md_processing/md_processing_utils/md_processing_constants.py +94 -17
  102. pyegeria/__init__.py +1 -0
  103. pyegeria/_client.py +39 -1
  104. pyegeria/classification_manager_omvs.py +1 -1
  105. pyegeria/collection_manager_omvs.py +4667 -1178
  106. pyegeria/data_designer_omvs.py +348 -31
  107. pyegeria/egeria_tech_client.py +9 -25
  108. pyegeria/glossary_browser_omvs.py +5 -6
  109. pyegeria/glossary_manager_omvs.py +2 -2
  110. pyegeria/governance_officer_omvs.py +2367 -0
  111. pyegeria/output_formatter.py +157 -32
  112. pyegeria/solution_architect_omvs.py +5063 -1110
  113. pyegeria/utils.py +22 -2
  114. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dist-info}/METADATA +3 -1
  115. pyegeria-5.4.0.dist-info/RECORD +243 -0
  116. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dist-info}/entry_points.txt +5 -0
  117. commands/cat/.DS_Store +0 -0
  118. md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +0 -254
  119. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +0 -696
  120. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +0 -254
  121. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +0 -298
  122. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +0 -608
  123. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +0 -94
  124. md_processing/dr_egeria_inbox/archive/freddie_intro.md +0 -284
  125. md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +0 -275
  126. md_processing/dr_egeria_inbox/archive/test-term.md +0 -110
  127. md_processing/dr_egeria_inbox/cat_test.md +0 -100
  128. md_processing/dr_egeria_inbox/data_field.md +0 -54
  129. md_processing/dr_egeria_inbox/data_spec.md +0 -77
  130. md_processing/dr_egeria_inbox/data_spec_test.md +0 -2406
  131. md_processing/dr_egeria_inbox/data_test.md +0 -86
  132. md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +0 -168
  133. md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +0 -280
  134. md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +0 -313
  135. md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +0 -1073
  136. md_processing/dr_egeria_inbox/dr_egeria_isc1.md +0 -44
  137. md_processing/dr_egeria_inbox/glossary_test1.md +0 -324
  138. md_processing/dr_egeria_inbox/rel.md +0 -8
  139. md_processing/dr_egeria_inbox/sb.md +0 -119
  140. md_processing/dr_egeria_inbox/search_test.md +0 -39
  141. md_processing/dr_egeria_inbox/solution-components.md +0 -154
  142. md_processing/dr_egeria_inbox/solution_blueprints.md +0 -118
  143. md_processing/dr_egeria_inbox/synonym_test.md +0 -42
  144. md_processing/dr_egeria_inbox/t1.md +0 -0
  145. md_processing/dr_egeria_inbox/t2.md +0 -268
  146. md_processing/dr_egeria_outbox/processed-2025-05-15 19:52-data_test.md +0 -94
  147. md_processing/dr_egeria_outbox/processed-2025-05-16 07:39-data_test.md +0 -88
  148. md_processing/dr_egeria_outbox/processed-2025-05-17 16:01-data_field.md +0 -56
  149. md_processing/dr_egeria_outbox/processed-2025-05-18 15:51-data_test.md +0 -103
  150. md_processing/dr_egeria_outbox/processed-2025-05-18 16:47-data_test.md +0 -94
  151. md_processing/dr_egeria_outbox/processed-2025-05-19 07:14-data_test.md +0 -96
  152. md_processing/dr_egeria_outbox/processed-2025-05-19 07:20-data_test.md +0 -100
  153. md_processing/dr_egeria_outbox/processed-2025-05-19 07:22-data_test.md +0 -88
  154. md_processing/dr_egeria_outbox/processed-2025-05-19 09:26-data_test.md +0 -91
  155. md_processing/dr_egeria_outbox/processed-2025-05-19 10:27-data_test.md +0 -91
  156. md_processing/dr_egeria_outbox/processed-2025-05-19 14:04-data_test.md +0 -91
  157. md_processing/md_commands/blueprint_commands.py +0 -303
  158. pyegeria/.DS_Store +0 -0
  159. pyegeria/m_test.py +0 -118
  160. pyegeria-5.3.10.dist-info/RECORD +0 -196
  161. /commands/cat/{list_data_structures.py → list_data_structures_full.py} +0 -0
  162. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dist-info}/LICENSE +0 -0
  163. {pyegeria-5.3.10.dist-info → pyegeria-5.4.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,273 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ SPDX-License-Identifier: Apache-2.0
4
+ Copyright Contributors to the ODPi Egeria project.
5
+
6
+
7
+ A simple display for glossary terms
8
+ """
9
+ import argparse
10
+ import os
11
+ import sys
12
+ import time
13
+
14
+ from rich import box
15
+ from rich.console import Console
16
+ from rich.markdown import Markdown
17
+ from rich.prompt import Prompt
18
+ from rich.table import Table
19
+ from rich.text import Text
20
+
21
+ from pyegeria import (
22
+ EgeriaTech,
23
+ InvalidParameterException,
24
+ PropertyServerException,
25
+ UserNotAuthorizedException, NO_CATEGORIES_FOUND,
26
+ )
27
+ from commands.cat.glossary_actions import EGERIA_HOME_GLOSSARY_GUID
28
+ from pyegeria._globals import NO_GLOSSARIES_FOUND
29
+
30
+ disable_ssl_warnings = True
31
+
32
+ EGERIA_METADATA_STORE = os.environ.get("EGERIA_METADATA_STORE", "active-metadata-store")
33
+ EGERIA_KAFKA_ENDPOINT = os.environ.get("KAFKA_ENDPOINT", "localhost:9092")
34
+ EGERIA_PLATFORM_URL = os.environ.get("EGERIA_PLATFORM_URL", "https://localhost:9443")
35
+ EGERIA_VIEW_SERVER = os.environ.get("EGERIA_VIEW_SERVER", "view-server")
36
+ EGERIA_VIEW_SERVER_URL = os.environ.get(
37
+ "EGERIA_VIEW_SERVER_URL", "https://localhost:9443"
38
+ )
39
+ EGERIA_INTEGRATION_DAEMON = os.environ.get("EGERIA_INTEGRATION_DAEMON", "integration-daemon")
40
+ EGERIA_ADMIN_USER = os.environ.get("ADMIN_USER", "garygeeke")
41
+ EGERIA_ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "secret")
42
+ EGERIA_USER = os.environ.get("EGERIA_USER", "erinoverview")
43
+ EGERIA_USER_PASSWORD = os.environ.get("EGERIA_USER_PASSWORD", "secret")
44
+ EGERIA_JUPYTER = bool(os.environ.get("EGERIA_JUPYTER", "False"))
45
+ EGERIA_WIDTH = int(os.environ.get("EGERIA_WIDTH", "250"))
46
+ EGERIA_GLOSSARY_PATH = os.environ.get("EGERIA_GLOSSARY_PATH", None)
47
+ EGERIA_ROOT_PATH = os.environ.get("EGERIA_ROOT_PATH", "../../")
48
+ EGERIA_INBOX_PATH = os.environ.get("EGERIA_INBOX_PATH", "md_processing/dr_egeria_inbox")
49
+ EGERIA_OUTBOX_PATH = os.environ.get("EGERIA_OUTBOX_PATH", "md_processing/dr_egeria_outbox")
50
+
51
+
52
+ def display_command_terms(
53
+ search_string: str = "*",
54
+ glossary_guid: str = EGERIA_HOME_GLOSSARY_GUID,
55
+ glossary_name: str = None,
56
+ view_server: str = EGERIA_VIEW_SERVER,
57
+ view_url: str = EGERIA_VIEW_SERVER_URL,
58
+ user_id: str = EGERIA_USER,
59
+ user_pass: str = EGERIA_USER_PASSWORD,
60
+ jupyter: bool = EGERIA_JUPYTER,
61
+ width: int = EGERIA_WIDTH,
62
+ output_format: str = "TABLE",
63
+ ):
64
+ """Display a table of glossary terms filtered by search_string and glossary, if specified. If no
65
+ filters then all terms are displayed. If glossary_guid or name is specified, then only terms from that
66
+ glossary are displayed.
67
+ Parameters
68
+ ----------
69
+ search_string : str, optional
70
+ The string to search for terms. Defaults to "*".
71
+ glossary_guid : str, optional
72
+ The unique identifier of the glossary. Defaults to None. If specified, then only terms from that glossary
73
+ are displayed. If both glossary_guid and glossary_name are provided then glossary_guid will take precedence.
74
+ glossary_name : str, optional
75
+ The display name of the glossary. Defaults to None. If specified, then only terms from that glossary
76
+ are displayed. If both glossary_guid and glossary_name are provided then glossary_guid will take precedence.
77
+ Note that the use of glossary display name relies on the qualified name conforming to convention. GUID is more
78
+ reliable.
79
+ view_server : str
80
+ The server where the glossary is hosted. Defaults to EGERIA_VIEW_SERVER.
81
+ view_url : str
82
+ The URL of the server where the glossary is hosted. Defaults to EGERIA_VIEW_SERVER_URL.
83
+ user_id : str
84
+ The user ID for authentication. Defaults to EGERIA_USER.
85
+ user_pass : str
86
+ The user password for authentication. Defaults to EGERIA_USER_PASSWORD.
87
+ jupyter : bool
88
+ Flag to indicate if the output should be formatted for Jupyter notebook. Defaults to EGERIA_JUPYTER.
89
+ width : int
90
+ The width of the console output. Defaults to EGERIA_WIDTH.
91
+ output_format: str, optional, default is 'JSON'
92
+ One of TABLE, FORM, REPORT
93
+ """
94
+
95
+ console = Console(
96
+ style="bold bright_white on black", width=width, force_terminal=not jupyter
97
+ )
98
+ try:
99
+ g_client = EgeriaTech(view_server, view_url, user_id, user_pass)
100
+ token = g_client.create_egeria_bearer_token(user_id, user_pass)
101
+ if (glossary_name is not None) and (glossary_name != "*"):
102
+ glossary_guid = g_client.get_guid_for_name(glossary_name)
103
+ if glossary_guid == NO_GLOSSARIES_FOUND:
104
+ console.print(
105
+ f"\nThe glossary name {glossary_name} was not found. Please try using the glossary guid"
106
+ )
107
+ sys.exit(1)
108
+ elif (glossary_guid is not None) and (len(glossary_guid) < 10):
109
+ glossary_guid = None
110
+
111
+ if output_format == "LIST":
112
+ action = "LIST"
113
+ elif output_format == "REPORT":
114
+ action = "Report"
115
+ if output_format != "TABLE":
116
+ file_path = os.path.join(EGERIA_ROOT_PATH, EGERIA_OUTBOX_PATH)
117
+ file_name = f"Command-Help-{time.strftime('%Y-%m-%d-%H-%M-%S')}-{action}.md"
118
+ full_file_path = os.path.join(file_path, file_name)
119
+ os.makedirs(os.path.dirname(full_file_path), exist_ok=True)
120
+ output = g_client.find_glossary_terms(search_string, glossary_guid, output_format=output_format)
121
+ if output == "NO_TERMS_FOUND":
122
+ print(f"\n==> No commands found for search string '{search_string}'")
123
+ return
124
+ with open(full_file_path, 'w') as f:
125
+ f.write(output)
126
+ print(f"\n==> Terms output written to {full_file_path}")
127
+ return
128
+
129
+ except (
130
+ InvalidParameterException,
131
+ PropertyServerException,
132
+ UserNotAuthorizedException,
133
+ ) as e:
134
+ console.print_exception()
135
+
136
+
137
+
138
+ def generate_table(search_string: str, glossary_guid: str) -> Table:
139
+ """Make a new table."""
140
+ table = Table(
141
+ title=f"Glossary Definitions for Terms like {search_string} @ {time.asctime()}",
142
+ style="bright_white on black",
143
+ # row_styles="bright_white on black",
144
+ header_style="bright_white on dark_blue",
145
+ title_style="bold white on black",
146
+ caption_style="white on black",
147
+ show_lines=True,
148
+ box=box.ROUNDED,
149
+ caption=f"View Server '{view_server}' @ Platform - {view_url}",
150
+ expand=True,
151
+ )
152
+ table.add_column("Term Name", width=20)
153
+ # table.add_column("Summary")
154
+ table.add_column("Description", width=40)
155
+ table.add_column("Usage", min_width=100)
156
+
157
+ terms = g_client.find_glossary_terms(
158
+ search_string,
159
+ glossary_guid,
160
+ starts_with=False,
161
+ ends_with=False,
162
+ status_filter=[],
163
+ page_size=500,
164
+ )
165
+
166
+ if type(terms) is str:
167
+ print(f"No commands found - this was not the command you were looking for?! - {search_string} : {glossary_guid} ")
168
+ sys.exit(0)
169
+ sorted_terms = sorted(
170
+ terms, key=lambda k: k["glossaryTermProperties"].get("displayName","---")
171
+ )
172
+ style = "bright_white on black"
173
+ if type(terms) is str:
174
+ return table
175
+ glossary_info = {}
176
+ for term in sorted_terms:
177
+ props = term.get("glossaryTermProperties", "None")
178
+ if props == "None":
179
+ return table
180
+
181
+ display_name = props.get("displayName","---")
182
+ qualified_name = props["qualifiedName"]
183
+ term_guid = term["elementHeader"]["guid"]
184
+ aliases = props.get("aliases", "---")
185
+ q_name = Text(
186
+ f"{qualified_name}\n&\n{term_guid}\n&\n{aliases}", style=style, justify="center"
187
+ )
188
+ abbrev = props.get("abbreviation", "---")
189
+ summary = props.get("summary", "---")
190
+ description = props.get("description",'---')
191
+ version = props.get("publishVersionIdentifier", "---")
192
+ example = props.get("example", "---")
193
+ usage = props.get("usage", "---")
194
+ # ex_us_out = Markdown(f"Example:\n{example}\n---\nUsage: \n{usage}")
195
+
196
+ classifications = term["elementHeader"]["classifications"]
197
+ glossary_guid = None
198
+ for c in classifications:
199
+ if c["classificationName"] == "Anchors":
200
+ glossary_guid = c["classificationProperties"]["anchorScopeGUID"]
201
+
202
+ if glossary_guid and glossary_guid in glossary_info:
203
+ glossary_name = glossary_info[glossary_guid]
204
+ elif glossary_guid:
205
+ g = g_client.get_glossary_for_term(term_guid)
206
+ glossary_name = g["glossaryProperties"].get("displayName", "---")
207
+ glossary_info[glossary_guid] = glossary_name
208
+ else:
209
+ glossary_name = "---"
210
+
211
+ term_abb_ver_out = Markdown(f"{display_name}\n---\n{abbrev}\n---\n{version}")
212
+
213
+ term_status = term["elementHeader"].get("status","---")
214
+ table.add_row(
215
+ Markdown(display_name),
216
+ # summary,
217
+ Markdown(description),
218
+ Markdown(usage),
219
+ style="bold white on black",
220
+ )
221
+
222
+ g_client.close_session()
223
+ return table
224
+
225
+ try:
226
+ with console.pager(styles=True):
227
+ console.print(generate_table(search_string, glossary_guid))
228
+
229
+ except (
230
+ InvalidParameterException,
231
+ PropertyServerException,
232
+ UserNotAuthorizedException,
233
+ ) as e:
234
+ console.print_exception()
235
+
236
+
237
+ def main():
238
+ sus_guid = "f9b78b26-6025-43fa-9299-a905cc6d1575"
239
+ parser = argparse.ArgumentParser()
240
+ parser.add_argument("--server", help="Name of the server to display status for")
241
+ parser.add_argument("--url", help="URL Platform to connect to")
242
+ parser.add_argument("--userid", help="User Id")
243
+ parser.add_argument("--password", help="User Password")
244
+ parser.add_argument("--guid", help="GUID of glossary to search")
245
+
246
+ args = parser.parse_args()
247
+
248
+ # server = args.server if args.server is not None else EGERIA_VIEW_SERVER
249
+ server = args.server if args.server is not None else EGERIA_VIEW_SERVER
250
+
251
+ url = args.url if args.url is not None else EGERIA_PLATFORM_URL
252
+ userid = args.userid if args.userid is not None else EGERIA_USER
253
+ user_pass = args.password if args.password is not None else EGERIA_USER_PASSWORD
254
+ guid = args.guid if args.guid is not None else EGERIA_HOME_GLOSSARY_GUID
255
+
256
+ try:
257
+ search_string = Prompt.ask("Enter the command you are searching for:", default="*")
258
+
259
+ output_format = Prompt.ask("What output format do you want?", choices=["TABLE", "LIST", "REPORT"], default="TABLE")
260
+
261
+ display_command_terms(
262
+ search_string, guid, 'Egeria-Markdown', server, url,
263
+ userid, user_pass, output_format= output_format
264
+ )
265
+
266
+ except KeyboardInterrupt:
267
+ pass
268
+
269
+
270
+
271
+
272
+ if __name__ == "__main__":
273
+ main()
@@ -2,26 +2,44 @@
2
2
  This is an ongoing experiment in parsing and playing with Freddie docs
3
3
  """
4
4
  import os
5
+ import sys
5
6
  from datetime import datetime
6
7
 
8
+ from loguru import logger
9
+
10
+ log_format = "{time} | {level} | {function} | {line} | {message} | {extra}"
11
+ logger.remove()
12
+ logger.add(sys.stderr, level="INFO", format=log_format, colorize=True)
13
+ logger.add("debug_log.log", rotation="1 day", retention="1 week", compression="zip", level="TRACE", format=log_format,
14
+ colorize=True)
7
15
  import click
8
16
  from rich import print
9
17
  from rich.console import Console
18
+ from md_processing.md_processing_utils.common_md_utils import setup_log
10
19
 
11
20
  from md_processing import (extract_command, process_glossary_upsert_command, process_term_upsert_command,
12
21
  process_category_upsert_command, process_provenance_command, get_current_datetime_string,
13
22
  process_per_proj_upsert_command, command_list, process_blueprint_upsert_command,
14
- process_solution_component_upsert_command, process_term_list_command,
23
+ process_solution_component_upsert_command, process_component_link_unlink_command,
24
+ process_term_list_command,
15
25
  process_category_list_command, process_glossary_list_command, process_term_history_command,
16
26
  process_glossary_structure_command, process_term_revision_history_command,
17
27
  process_create_term_term_relationship_command, process_term_details_command,
18
- )
28
+ process_information_supply_chain_upsert_command,
29
+ process_information_supply_chain_link_unlink_command, process_sol_arch_list_command,
30
+ process_digital_product_upsert_command, process_agreement_upsert_command,
31
+ process_gov_definition_upsert_command, GOV_COM_LIST, GOV_LINK_LIST,
32
+ process_gov_def_link_detach_command, process_gov_definition_list_command,
33
+ process_gov_def_context_command)
19
34
  from md_processing.md_commands.data_designer_commands import (process_data_spec_upsert_command,
20
35
  process_data_dict_upsert_command,
21
- process_data_dict_list_command,
36
+ process_data_collection_list_command,
37
+ process_data_structure_list_command,
38
+ process_data_field_list_command,
39
+ process_data_class_list_command,
22
40
  process_data_field_upsert_command,
23
- process_data_structure_upsert_command)
24
-
41
+ process_data_structure_upsert_command,
42
+ process_data_class_upsert_command)
25
43
  from pyegeria import EgeriaTech
26
44
 
27
45
  EGERIA_METADATA_STORE = os.environ.get("EGERIA_METADATA_STORE", "active-metadata-store")
@@ -43,28 +61,33 @@ EGERIA_ROOT_PATH = os.environ.get("EGERIA_ROOT_PATH", "../../")
43
61
  EGERIA_INBOX_PATH = os.environ.get("EGERIA_INBOX_PATH", "md_processing/dr_egeria_inbox")
44
62
  EGERIA_OUTBOX_PATH = os.environ.get("EGERIA_OUTBOX_PATH", "md_processing/dr_egeria_outbox")
45
63
 
46
-
64
+ setup_log()
47
65
  @click.command("process_markdown_file", help="Process a markdown file and return the output as a string.")
48
- @click.option("--file-path", help="File path to markdown file", default="glossary_test1.md", required=True,
66
+ @click.option("--input-file", help="Markdown file to process.", default="dr_egeria_intro_part1.md", required=True,
49
67
  prompt=False)
50
- @click.option("--directive", default="display", help="How to process the file",
68
+ @click.option("--output-folder", help="Output folder.", default=".", required=False)
69
+ @click.option("--directive", default="process", help="How to process the file",
51
70
  type=click.Choice(["display", "validate", "process"], case_sensitive=False), prompt=False, )
52
71
  @click.option("--server", default=EGERIA_VIEW_SERVER, help="Egeria view server to use.")
53
72
  @click.option("--url", default=EGERIA_VIEW_SERVER_URL, help="URL of Egeria platform to connect to")
54
73
  @click.option("--userid", default=EGERIA_USER, help="Egeria user")
55
74
  @click.option("--user_pass", default=EGERIA_USER_PASSWORD, help="Egeria user password")
56
- def process_markdown_file(file_path: str, directive: str, server: str, url: str, userid: str, user_pass: str, ) -> None:
75
+ @logger.catch
76
+ def process_markdown_file(input_file: str, output_folder:str, directive: str, server: str, url: str, userid: str,
77
+ user_pass: str, ) -> None:
57
78
  """
58
79
  Process a markdown file by parsing and executing Dr. Egeria md_commands. Write output to a new file.
59
80
  """
81
+
60
82
  cmd_list = command_list
61
83
  console = Console(width=int(EGERIA_WIDTH))
62
84
  client = EgeriaTech(server, url, user_id=userid)
63
85
  token = client.create_egeria_bearer_token(userid, user_pass)
64
86
 
65
87
  updated = False
66
- full_file_path = os.path.join(EGERIA_ROOT_PATH, EGERIA_INBOX_PATH, file_path)
67
- print(f"Processing Markdown File: {full_file_path}")
88
+ full_file_path = os.path.join(EGERIA_ROOT_PATH, EGERIA_INBOX_PATH, input_file)
89
+ logger.info("\n\n====================================================\n\n")
90
+ logger.info(f"Processing Markdown File: {full_file_path}")
68
91
  try:
69
92
  with open(full_file_path, 'r') as f:
70
93
  lines = f.readlines()
@@ -74,7 +97,7 @@ def process_markdown_file(file_path: str, directive: str, server: str, url: str,
74
97
 
75
98
  final_output = []
76
99
  prov_found = False
77
- prov_output = (f"\n# Provenance\n\n* Results from processing file {file_path} on "
100
+ prov_output = (f"\n# Provenance\n\n* Results from processing file {input_file} on "
78
101
  f"{datetime.now().strftime("%Y-%m-%d %H:%M")}\n")
79
102
  h1_blocks = []
80
103
  current_block = ""
@@ -91,7 +114,7 @@ def process_markdown_file(file_path: str, directive: str, server: str, url: str,
91
114
  if potential_command in cmd_list:
92
115
  # Process the block based on the object_action
93
116
  if potential_command == "Provenance":
94
- result = process_provenance_command(file_path, current_block)
117
+ result = process_provenance_command(input_file, current_block)
95
118
  prov_found = True
96
119
 
97
120
  elif potential_command in ["Create Glossary", "Update Glossary"]:
@@ -121,8 +144,27 @@ def process_markdown_file(file_path: str, directive: str, server: str, url: str,
121
144
  elif potential_command in ["Create Blueprint", "Update Blueprint", "Create Solution Blueprint",
122
145
  "Update Solution Blueprint"]:
123
146
  result = process_blueprint_upsert_command(client, current_block, directive)
147
+ elif potential_command in ["View Solution Blueprints", "View Blueprint", "View Solution Blueprint"]:
148
+ result = process_sol_arch_list_command(client, current_block, "Solution Blueprints", directive)
149
+ elif potential_command in ["View Solution Component", "View Solution Components"]:
150
+ result = process_sol_arch_list_command(client, current_block, "Solution Components", directive)
151
+ elif potential_command in ["View Solution Roles", "View Solution Role"]:
152
+ result = process_sol_arch_list_command(client, current_block, "Solution Roles", directive)
153
+ elif potential_command in ["View Information Supply Chain", "View Information Supply Chains"]:
154
+ result = process_sol_arch_list_command(client, current_block, "Information Supply Chains", directive)
124
155
  elif potential_command in ["Create Solution Component", "Update Solution Component"]:
125
156
  result = process_solution_component_upsert_command(client, current_block, directive)
157
+ elif potential_command in ["Link Solution Components", "Link Solution Component Peers", "Wire Solution Components",
158
+ "Unlink Solution Components", "Detach Solution Components", "Detach Solution Component Peers"]:
159
+ result = process_component_link_unlink_command(client, current_block, directive)
160
+ elif potential_command in ["Create Information Supply Chain", "Update Information Supply Chain"]:
161
+ result = process_information_supply_chain_upsert_command(client, current_block, directive)
162
+
163
+ elif potential_command in ["Link Information Supply Chain Peers", "Link Information Supply Chains",
164
+ "Link Supply Chains", "Unlink Information Supply Chain Peers",
165
+ "Unlink Information Supply Chains", "Unlink Supply Chains"]:
166
+ result = process_information_supply_chain_link_unlink_command(client, current_block, directive)
167
+
126
168
  elif potential_command in ["Create Data Spec", "Create Data Specification", "Update Data Spec",
127
169
  "Update Data Specification"]:
128
170
  result = process_data_spec_upsert_command(client, current_block, directive)
@@ -133,13 +175,36 @@ def process_markdown_file(file_path: str, directive: str, server: str, url: str,
133
175
  result = process_data_field_upsert_command(client, current_block, directive)
134
176
  elif potential_command in ["Create Data Structure", "Update Data Structure"]:
135
177
  result = process_data_structure_upsert_command(client, current_block, directive)
136
- elif potential_command in ["View Data Dictionaries", "View Data Dictionary"]:
137
- result = process_data_dict_list_command(client, current_block, directive)
178
+ elif potential_command in ["Create Data Class", "Update Data Class"]:
179
+ result = process_data_class_upsert_command(client, current_block, directive)
180
+ elif potential_command in ["View Data Dictionaries", "View Data Dictionary", "View Data Specifications",
181
+ "View Data Specs"]:
182
+ result = process_data_collection_list_command(client, current_block, directive)
183
+ elif potential_command in ["View Data Structures", "View Data Structure"]:
184
+ result = process_data_structure_list_command(client, current_block, directive)
185
+ elif potential_command in ["View Data Fields", "View Data Field"]:
186
+ result = process_data_field_list_command(client, current_block, directive)
187
+ elif potential_command in ["View Data Classes", "View Data Class"]:
188
+ result = process_data_class_list_command(client, current_block, directive)
189
+ elif potential_command in ["Create Digital Product", "Create Data Product","Update Digital Product", "Update Data Product"]:
190
+ result = process_digital_product_upsert_command(client, current_block, directive)
191
+ elif potential_command in ["Create Agreement", "Create Data Sharing Agreement", "Update Agreement", "Update Data Sharing Agreement"]:
192
+ result = process_agreement_upsert_command(client, current_block, directive)
193
+ elif potential_command in GOV_COM_LIST:
194
+ result = process_gov_definition_upsert_command(client, current_block, directive)
195
+ elif potential_command in ['View Governance Definitions', 'List Governance Definitions',
196
+ 'View Gov Definitions', 'List Gov Definitions']:
197
+ result = process_gov_definition_list_command(client, current_block, directive)
198
+ elif potential_command in ['View Governance Definition Context', 'List Governance Definition Context',
199
+ 'View Gov Definition Context', 'List Gov Definition Context']:
200
+ result = process_gov_def_context_command(client, current_block, directive)
201
+
138
202
 
139
203
 
140
204
  else:
141
205
  # If object_action is not recognized, keep the block as-is
142
206
  result = None
207
+ print(f"\n===> Unknown command: {potential_command}")
143
208
  # print(json.dumps(dr_egeria_state.get_element_dictionary(), indent=4))
144
209
  if result:
145
210
  if directive == "process":
@@ -197,9 +262,13 @@ def process_markdown_file(file_path: str, directive: str, server: str, url: str,
197
262
 
198
263
  try:
199
264
  if updated:
200
- path, filename = os.path.split(file_path) # Get both parts
265
+ path, filename = os.path.split(input_file) # Get both parts
201
266
  new_filename = f"processed-{get_current_datetime_string()}-{filename}" # Create the new filename
202
- new_file_path = os.path.join(EGERIA_ROOT_PATH, EGERIA_OUTBOX_PATH, new_filename) # Construct the new path
267
+
268
+ if output_folder:
269
+ new_file_path = os.path.join(EGERIA_ROOT_PATH, EGERIA_OUTBOX_PATH, output_folder, new_filename)
270
+ else:
271
+ new_file_path = os.path.join(EGERIA_ROOT_PATH, EGERIA_OUTBOX_PATH, new_filename)
203
272
  os.makedirs(os.path.dirname(new_file_path), exist_ok=True)
204
273
 
205
274
  with open(new_file_path, 'w') as f2:
@@ -210,6 +279,7 @@ def process_markdown_file(file_path: str, directive: str, server: str, url: str,
210
279
  else:
211
280
  if directive != 'display':
212
281
  click.echo("\nNo updates detected. New File not created.")
282
+ logger.error("===> Unknown Command? <===")
213
283
 
214
284
  except (Exception):
215
285
  console.print_exception(show_locals=True)
@@ -231,11 +301,11 @@ def process_markdown_file(file_path: str, directive: str, server: str, url: str,
231
301
  # user_pass = args.password if args.password is not None else EGERIA_USER_PASSWORD
232
302
  # time_out = args.time_out if args.time_out is not None else 60
233
303
  # try:
234
- # file_path = Prompt.ask("Markdown File name to process:", default="")
304
+ # input_file = Prompt.ask("Markdown File name to process:", default="")
235
305
  # directive = Prompt.ask("Processing Directive:", choices=[ "display", "validate", "process"],
236
306
  # default="validate")
237
307
  #
238
- # process_markdown_file(file_path, directive, server, url, userid, user_pass)
308
+ # process_markdown_file(input_file, directive, server, url, userid, user_pass)
239
309
  # except KeyboardInterrupt:
240
310
  # pass
241
311
  #
@@ -244,4 +314,4 @@ def process_markdown_file(file_path: str, directive: str, server: str, url: str,
244
314
  # main()
245
315
 
246
316
  if __name__ == "__main__":
247
- process_markdown_file()
317
+ process_markdown_file()
@@ -315,7 +315,7 @@ def remove_term_from_category(server, url, userid, password, timeout, term_guid,
315
315
  @click.option("--glossary_name", help="Name of Glossary", required=True)
316
316
  @click.option("--file_name", help="Name of CSV file", required=True)
317
317
  @click.option(
318
- "--file_path", help="Path of CSV file", default=EGERIA_GLOSSARY_PATH, required=False
318
+ "--input_file", help="Path of CSV file", default=EGERIA_GLOSSARY_PATH, required=False
319
319
  )
320
320
  @click.option(
321
321
  "--verbose",
@@ -380,7 +380,7 @@ def import_terms_csv(
380
380
  )
381
381
  @click.option("--file_name", help="Name of CSV file", required=True)
382
382
  @click.option(
383
- "--file_path", help="Path of CSV file", default=EGERIA_GLOSSARY_PATH, required=False
383
+ "--input_file", help="Path of CSV file", default=EGERIA_GLOSSARY_PATH, required=False
384
384
  )
385
385
  @click.option("--server", default=EGERIA_VIEW_SERVER, help="Egeria view server to use")
386
386
  @click.option(
@@ -87,14 +87,21 @@ def display_collections(
87
87
  action = "Report"
88
88
  elif output_format == "DICT":
89
89
  action = "Dict"
90
+ elif output_format == "HTML":
91
+ action = "html"
92
+ elif output_format == "LIST":
93
+ action = "List"
90
94
 
91
95
  if output_format != "TABLE":
92
96
  file_path = os.path.join(EGERIA_ROOT_PATH, EGERIA_OUTBOX_PATH)
93
- file_name = f"Terms-{time.strftime('%Y-%m-%d-%H-%M-%S')}-{action}.md"
97
+ if output_format == "HTML":
98
+ file_name = f"Collections-{time.strftime('%Y-%m-%d-%H-%M-%S')}-{action}.html"
99
+ else:
100
+ file_name = f"Collections-{time.strftime('%Y-%m-%d-%H-%M-%S')}-{action}.md"
94
101
  full_file_path = os.path.join(file_path, file_name)
95
102
  os.makedirs(os.path.dirname(full_file_path), exist_ok=True)
96
103
  output = m_client.find_collections(
97
- search_string.strip(), None, False, ends_with=False, ignore_case=True,
104
+ search_string.strip(), None, True, False, ignore_case=True,
98
105
  output_format=output_format
99
106
  )
100
107
  if output == NO_ELEMENTS_FOUND:
@@ -129,24 +136,31 @@ def display_collections(
129
136
  table.add_column("Members")
130
137
 
131
138
  collections = m_client.find_collections(
132
- search_string.strip(), None, False, ends_with=False, ignore_case=True,
139
+ search_string.strip(), None, True, False, ignore_case=True,
133
140
  output_format = "DICT"
134
141
  )
135
142
  if type(collections) is list:
136
143
  sorted_collection_list = sorted(
137
- collections, key=lambda k: k["name"]
144
+ collections, key=lambda k: k["display_name"]
138
145
  )
139
146
  for collection in sorted_collection_list:
140
- display_name = collection["name"]
141
- qualified_name = collection["qualifiedName"]
142
- guid = collection["guid"]
147
+ display_name = collection["display_name"]
148
+ qualified_name = collection["qualified_name"]
149
+ guid = collection["GUID"]
143
150
  q_name = Text(f"{qualified_name}\n&\n{guid}", justify="center")
144
151
  description = collection.get("description",'---')
145
152
  collection_type = collection.get("collectionType", "---")
146
153
  classifications = collection.get("classifications", "---")
154
+
147
155
  classifications_md = Markdown(classifications)
148
- members = "\n* ".join(collection.get("members", []))
149
- members_md = Markdown(members)
156
+ members_struct = m_client.get_member_list(collection_guid=guid)
157
+ member_list = ""
158
+ if isinstance(members_struct, list):
159
+ for member in members_struct:
160
+ member_list = member_list + f"- {member.get('qualifiedName','---')}\n"
161
+
162
+ # members = "\n* ".join(collection.get("members", []))
163
+ members_md = Markdown(member_list)
150
164
 
151
165
  table.add_row(
152
166
  display_name,
@@ -193,7 +207,7 @@ def main():
193
207
  search_string = Prompt.ask(
194
208
  "Enter the collection you are searching for or '*' for all:", default="*"
195
209
  ).strip()
196
- output_format = Prompt.ask("What output format do you want?", choices=["DICT", "TABLE", "FORM", "REPORT"], default="TABLE")
210
+ output_format = Prompt.ask("What output format do you want?", choices=["DICT", "TABLE", "FORM", "REPORT", "HTML", "LIST"], default="TABLE")
197
211
 
198
212
  display_collections(search_string, server, url, userid, user_pass, output_format = output_format)
199
213