pyegeria 0.7.45.1__py3-none-any.whl → 0.8.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.
- examples/widgets/cat/list_cert_types.py +61 -43
- examples/widgets/cat/list_projects.py +1 -1
- examples/widgets/my/my_profile_actions.py +51 -32
- examples/widgets/ops/engine_actions.py +35 -23
- examples/widgets/ops/integration_daemon_actions.py +51 -32
- examples/widgets/tech/get_element_info.py +63 -38
- examples/widgets/tech/get_guid_info.py +50 -27
- examples/widgets/tech/list_asset_types.py +33 -23
- examples/widgets/tech/list_elements.py +44 -34
- examples/widgets/tech/list_elements_x.py +69 -49
- examples/widgets/tech/list_registered_services.py +44 -24
- examples/widgets/tech/list_related_specification.py +70 -45
- examples/widgets/tech/list_relationship_types.py +50 -31
- examples/widgets/tech/list_valid_metadata_values.py +57 -28
- examples/widgets/tech/x_list_related_elements.py +54 -34
- pyegeria/Xloaded_resources_omvs.py +43 -41
- pyegeria/__init__.py +5 -1
- pyegeria/_client.py +142 -102
- pyegeria/_deprecated_gov_engine.py +218 -167
- pyegeria/action_author_omvs.py +107 -88
- pyegeria/asset_catalog_omvs.py +467 -395
- pyegeria/automated_curation_omvs.py +2 -2
- pyegeria/classification_manager_omvs.py +3 -9
- pyegeria/collection_manager_omvs.py +1957 -1519
- pyegeria/core_omag_server_config.py +310 -192
- pyegeria/egeria_cat_client.py +88 -0
- pyegeria/egeria_config_client.py +37 -0
- pyegeria/egeria_my_client.py +47 -0
- pyegeria/egeria_ops_client.py +67 -0
- pyegeria/egeria_tech_client.py +77 -0
- pyegeria/feedback_manager_omvs.py +633 -631
- pyegeria/full_omag_server_config.py +330 -158
- pyegeria/glossary_browser_omvs.py +927 -474
- pyegeria/glossary_manager_omvs.py +1033 -543
- pyegeria/my_profile_omvs.py +714 -574
- pyegeria/platform_services.py +228 -176
- pyegeria/project_manager_omvs.py +1158 -903
- pyegeria/registered_info.py +76 -74
- pyegeria/runtime_manager_omvs.py +749 -670
- pyegeria/server_operations.py +123 -85
- pyegeria/valid_metadata_omvs.py +268 -168
- {pyegeria-0.7.45.1.dist-info → pyegeria-0.8.0.dist-info}/METADATA +1 -1
- {pyegeria-0.7.45.1.dist-info → pyegeria-0.8.0.dist-info}/RECORD +46 -42
- pyegeria/tech_guids_31-08-2024 14:33.py +0 -79
- {pyegeria-0.7.45.1.dist-info → pyegeria-0.8.0.dist-info}/LICENSE +0 -0
- {pyegeria-0.7.45.1.dist-info → pyegeria-0.8.0.dist-info}/WHEEL +0 -0
- {pyegeria-0.7.45.1.dist-info → pyegeria-0.8.0.dist-info}/entry_points.txt +0 -0
pyegeria/_client.py
CHANGED
@@ -17,14 +17,15 @@ from pyegeria._exceptions import (
|
|
17
17
|
OMAGCommonErrorCode,
|
18
18
|
InvalidParameterException,
|
19
19
|
PropertyServerException,
|
20
|
-
UserNotAuthorizedException
|
20
|
+
UserNotAuthorizedException,
|
21
|
+
)
|
21
22
|
from pyegeria._globals import max_paging_size, TEMPLATE_GUIDS, INTEGRATION_GUIDS
|
22
23
|
from pyegeria._validators import (
|
23
24
|
validate_name,
|
24
25
|
validate_server_name,
|
25
26
|
validate_url,
|
26
27
|
validate_user_id,
|
27
|
-
is_json
|
28
|
+
is_json,
|
28
29
|
)
|
29
30
|
|
30
31
|
...
|
@@ -73,27 +74,23 @@ class Client:
|
|
73
74
|
json_header = {"Content-Type": "application/json"}
|
74
75
|
|
75
76
|
def __init__(
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
token_src: str = None,
|
86
|
-
async_mode: bool = False
|
77
|
+
self,
|
78
|
+
server_name: str,
|
79
|
+
platform_url: str,
|
80
|
+
user_id: str = None,
|
81
|
+
user_pwd: str = None,
|
82
|
+
api_key: str = None,
|
83
|
+
page_size: int = max_paging_size,
|
84
|
+
token: str = None,
|
85
|
+
token_src: str = None,
|
87
86
|
):
|
88
87
|
self.server_name = None
|
89
88
|
self.platform_url = None
|
90
89
|
self.user_id = user_id
|
91
90
|
self.user_pwd = user_pwd
|
92
|
-
self.ssl_verify = verify_flag
|
93
91
|
self.page_size = page_size
|
94
92
|
self.token_src = token_src
|
95
93
|
self.token = token
|
96
|
-
self.sync_mode = async_mode
|
97
94
|
self.exc_type = None
|
98
95
|
self.exc_value = None
|
99
96
|
self.exc_tb = None
|
@@ -164,35 +161,37 @@ class Client:
|
|
164
161
|
loop.run_until_complete(self._async_close_session())
|
165
162
|
return
|
166
163
|
|
167
|
-
async def _async_create_egeria_bearer_token(
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
164
|
+
async def _async_create_egeria_bearer_token(
|
165
|
+
self, user_id: str = None, password: str = None
|
166
|
+
) -> str:
|
167
|
+
"""Create and set an Egeria Bearer Token for the user. Async version
|
168
|
+
Parameters
|
169
|
+
----------
|
170
|
+
user_id : str, opt
|
171
|
+
The user id to authenticate with. If None, then user_id from class instance used.
|
172
|
+
password : str, opt
|
173
|
+
The password for the user. If None, then user_pwd from class instance is used.
|
174
|
+
|
175
|
+
Returns
|
176
|
+
-------
|
177
|
+
token
|
178
|
+
The bearer token for the specified user.
|
179
|
+
|
180
|
+
Raises
|
181
|
+
------
|
182
|
+
InvalidParameterException
|
183
|
+
If the client passes incorrect parameters on the request - such as bad URLs or invalid values
|
184
|
+
PropertyServerException
|
185
|
+
Raised by the server when an issue arises in processing a valid request
|
186
|
+
NotAuthorizedException
|
187
|
+
The principle specified by the user_id does not have authorization for the requested action
|
188
|
+
Notes
|
189
|
+
-----
|
190
|
+
This routine creates a new bearer token for the user and updates the object with it.
|
191
|
+
It uses Egeria's mechanisms to create a token. This is useful if an Egeria token expires.
|
192
|
+
A bearer token from another source can be set with the set_bearer_token() method.
|
193
|
+
|
194
|
+
"""
|
196
195
|
if user_id is None:
|
197
196
|
validate_user_id(self.user_id)
|
198
197
|
user_id = self.user_id
|
@@ -201,10 +200,7 @@ class Client:
|
|
201
200
|
password = self.user_pwd
|
202
201
|
|
203
202
|
url = f"{self.platform_url}/api/token"
|
204
|
-
data = {
|
205
|
-
"userId": user_id,
|
206
|
-
"password": password
|
207
|
-
}
|
203
|
+
data = {"userId": user_id, "password": password}
|
208
204
|
async with AsyncClient(verify=self.ssl_verify) as client:
|
209
205
|
try:
|
210
206
|
response = await client.post(url, json=data, headers=self.headers)
|
@@ -214,15 +210,17 @@ class Client:
|
|
214
210
|
return "FAILED"
|
215
211
|
|
216
212
|
if token:
|
217
|
-
self.token_src =
|
213
|
+
self.token_src = "Egeria"
|
218
214
|
self.headers["Authorization"] = f"Bearer {token}"
|
219
215
|
self.text_headers["Authorization"] = f"Bearer {token}"
|
220
216
|
return token
|
221
217
|
else:
|
222
218
|
raise InvalidParameterException("No token returned - request issue")
|
223
219
|
|
224
|
-
def create_egeria_bearer_token(
|
225
|
-
|
220
|
+
def create_egeria_bearer_token(
|
221
|
+
self, user_id: str = None, password: str = None
|
222
|
+
) -> str:
|
223
|
+
"""Create and set an Egeria Bearer Token for the user
|
226
224
|
Parameters
|
227
225
|
----------
|
228
226
|
user_id : str
|
@@ -251,7 +249,9 @@ class Client:
|
|
251
249
|
|
252
250
|
"""
|
253
251
|
loop = asyncio.get_event_loop()
|
254
|
-
response = loop.run_until_complete(
|
252
|
+
response = loop.run_until_complete(
|
253
|
+
self._async_create_egeria_bearer_token(user_id, password)
|
254
|
+
)
|
255
255
|
return response
|
256
256
|
|
257
257
|
async def _async_refresh_egeria_bearer_token(self) -> None:
|
@@ -271,7 +271,11 @@ class Client:
|
|
271
271
|
Raises:
|
272
272
|
InvalidParameterException: If the token source is invalid.
|
273
273
|
"""
|
274
|
-
if (
|
274
|
+
if (
|
275
|
+
(self.token_src == "Egeria")
|
276
|
+
and validate_user_id(self.user_id)
|
277
|
+
and validate_name(self.user_pwd)
|
278
|
+
):
|
275
279
|
await self._async_create_egeria_bearer_token(self.user_id, self.user_pwd)
|
276
280
|
else:
|
277
281
|
raise InvalidParameterException("Invalid token source")
|
@@ -302,7 +306,7 @@ class Client:
|
|
302
306
|
return
|
303
307
|
|
304
308
|
def set_bearer_token(self, token: str) -> None:
|
305
|
-
"""
|
309
|
+
"""Retrieve and set a Bearer Token
|
306
310
|
Parameters
|
307
311
|
----------
|
308
312
|
token: str
|
@@ -331,20 +335,31 @@ class Client:
|
|
331
335
|
self.text_headers["Authorization"] = f"Bearer {token}"
|
332
336
|
|
333
337
|
def get_token(self) -> str:
|
334
|
-
"""
|
338
|
+
"""Retrieve and return the bearer token"""
|
335
339
|
return self.text_headers["Authorization"]
|
336
340
|
|
337
|
-
def make_request(
|
338
|
-
|
339
|
-
|
341
|
+
def make_request(
|
342
|
+
self,
|
343
|
+
request_type: str,
|
344
|
+
endpoint: str,
|
345
|
+
payload: str | dict = None,
|
346
|
+
time_out: int = 30,
|
347
|
+
) -> Response | str:
|
348
|
+
"""Make a request to the Egeria API"""
|
340
349
|
loop = asyncio.get_event_loop()
|
341
|
-
response = loop.run_until_complete(
|
342
|
-
|
350
|
+
response = loop.run_until_complete(
|
351
|
+
self._async_make_request(request_type, endpoint, payload, time_out)
|
352
|
+
)
|
343
353
|
return response
|
344
354
|
|
345
|
-
async def _async_make_request(
|
346
|
-
|
347
|
-
|
355
|
+
async def _async_make_request(
|
356
|
+
self,
|
357
|
+
request_type: str,
|
358
|
+
endpoint: str,
|
359
|
+
payload: str | dict = None,
|
360
|
+
time_out: int = 30,
|
361
|
+
) -> Response | str:
|
362
|
+
"""Make a request to the Egeria API - Async Version
|
348
363
|
Function to make an API call via the self.session Library. Raise an exception if the HTTP response code
|
349
364
|
is not 200/201. IF there is a REST communication exception, raise InvalidParameterException.
|
350
365
|
|
@@ -364,25 +379,37 @@ class Client:
|
|
364
379
|
try:
|
365
380
|
response = ""
|
366
381
|
if request_type == "GET":
|
367
|
-
response = await self.session.get(
|
382
|
+
response = await self.session.get(
|
383
|
+
endpoint, params=payload, headers=self.headers, timeout=time_out
|
384
|
+
)
|
368
385
|
|
369
386
|
elif request_type == "POST":
|
370
387
|
if payload is None:
|
371
|
-
response = await self.session.post(
|
388
|
+
response = await self.session.post(
|
389
|
+
endpoint, headers=self.headers, timeout=time_out
|
390
|
+
)
|
372
391
|
elif type(payload) is str:
|
373
|
-
response = await self.session.post(
|
374
|
-
|
392
|
+
response = await self.session.post(
|
393
|
+
endpoint,
|
394
|
+
headers=self.text_headers,
|
395
|
+
data=payload,
|
396
|
+
timeout=time_out,
|
397
|
+
)
|
375
398
|
else:
|
376
|
-
response = await self.session.post(
|
377
|
-
|
399
|
+
response = await self.session.post(
|
400
|
+
endpoint, headers=self.headers, json=payload, timeout=time_out
|
401
|
+
)
|
378
402
|
|
379
403
|
elif request_type == "POST-DATA":
|
380
404
|
if True:
|
381
|
-
response = await self.session.post(
|
382
|
-
|
405
|
+
response = await self.session.post(
|
406
|
+
endpoint, headers=self.headers, data=payload, timeout=time_out
|
407
|
+
)
|
383
408
|
elif request_type == "DELETE":
|
384
409
|
if True:
|
385
|
-
response = await self.session.delete(
|
410
|
+
response = await self.session.delete(
|
411
|
+
endpoint, headers=self.headers, timeout=time_out
|
412
|
+
)
|
386
413
|
|
387
414
|
status_code = response.status_code
|
388
415
|
|
@@ -484,14 +511,21 @@ class Client:
|
|
484
511
|
|
485
512
|
elif response.status_code in (500, 501, 502, 503, 504):
|
486
513
|
# server errors
|
487
|
-
msg =
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
514
|
+
msg = (
|
515
|
+
OMAGCommonErrorCode.EXCEPTION_RESPONSE_FROM_API.value[
|
516
|
+
"message_template"
|
517
|
+
].format(
|
518
|
+
str(response.status_code),
|
519
|
+
caller_method,
|
520
|
+
endpoint,
|
521
|
+
OMAGCommonErrorCode.EXCEPTION_RESPONSE_FROM_API.value[
|
522
|
+
"message_id"
|
523
|
+
],
|
524
|
+
)
|
525
|
+
+ "==>System reports:'"
|
526
|
+
+ response.reason_phrase
|
527
|
+
+ "'"
|
528
|
+
)
|
495
529
|
exc_msg = json.dumps(
|
496
530
|
{
|
497
531
|
"class": "VoidResponse",
|
@@ -527,25 +561,30 @@ class Client:
|
|
527
561
|
except UserNotAuthorizedException:
|
528
562
|
raise
|
529
563
|
except (
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
564
|
+
httpx.NetworkError,
|
565
|
+
httpx.ProtocolError,
|
566
|
+
httpx.HTTPStatusError,
|
567
|
+
httpx.TimeoutException,
|
534
568
|
) as e:
|
535
569
|
if type(response) is str:
|
536
570
|
reason = response
|
537
571
|
else:
|
538
572
|
reason = response.reason_phrase
|
539
573
|
|
540
|
-
msg =
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
574
|
+
msg = (
|
575
|
+
OMAGCommonErrorCode.CLIENT_SIDE_REST_API_ERROR.value[
|
576
|
+
"message_template"
|
577
|
+
].format(
|
578
|
+
e.args[0],
|
579
|
+
caller_method,
|
580
|
+
class_name,
|
581
|
+
endpoint,
|
582
|
+
OMAGCommonErrorCode.CLIENT_SIDE_REST_API_ERROR.value["message_id"],
|
583
|
+
)
|
584
|
+
+ "==>System reports:'"
|
585
|
+
+ reason
|
586
|
+
+ "'"
|
587
|
+
)
|
549
588
|
exc_msg = json.dumps(
|
550
589
|
{
|
551
590
|
"class": "VoidResponse",
|
@@ -573,9 +612,11 @@ class Client:
|
|
573
612
|
|
574
613
|
self.create_egeria_bearer_token(self.user_id, self.user_pwd)
|
575
614
|
# get all technology types
|
576
|
-
url = (
|
577
|
-
|
578
|
-
|
615
|
+
url = (
|
616
|
+
f"{self.platform_url}/servers/{self.server_name}/api/open-metadata/automated-curation/technology-types/"
|
617
|
+
f"by-search-string?startFrom=0&pageSize=0&startsWith=false&"
|
618
|
+
f"endsWith=false&ignoreCase=true"
|
619
|
+
)
|
579
620
|
body = {"filter": ""}
|
580
621
|
|
581
622
|
response = self.make_request("POST", url, body)
|
@@ -588,13 +629,13 @@ class Client:
|
|
588
629
|
url = f"{self.platform_url}/servers/{self.server_name}/api/open-metadata/automated-curation/technology-types/by-name"
|
589
630
|
body = {"filter": display_name}
|
590
631
|
response = self.make_request("POST", url, body)
|
591
|
-
details = response.json().get("element","no type found")
|
632
|
+
details = response.json().get("element", "no type found")
|
592
633
|
if type(details) is str:
|
593
634
|
continue
|
594
635
|
# get templates and update the template_guids global
|
595
636
|
templates = details.get("catalogTemplates", "Not Found")
|
596
637
|
if type(templates) is str:
|
597
|
-
template_guids[display_name]= None
|
638
|
+
template_guids[display_name] = None
|
598
639
|
else:
|
599
640
|
for template in templates:
|
600
641
|
template_name = template.get("name", None)
|
@@ -603,19 +644,18 @@ class Client:
|
|
603
644
|
# print(f"Added {template_name} template with GUID {template_guids[template_name]}")
|
604
645
|
|
605
646
|
# Now find the integration connector guids
|
606
|
-
resource_list = details.get(
|
647
|
+
resource_list = details.get("resourceList", " ")
|
607
648
|
if type(resource_list) is str:
|
608
649
|
integration_guids[display_name] = None
|
609
650
|
else:
|
610
651
|
for resource in resource_list:
|
611
|
-
resource_guid = resource[
|
612
|
-
resource_type = resource[
|
652
|
+
resource_guid = resource["relatedElement"]["guid"]
|
653
|
+
resource_type = resource["relatedElement"]["type"]["typeName"]
|
613
654
|
if resource_type == "IntegrationConnector":
|
614
655
|
integration_guids[display_name] = resource_guid
|
615
656
|
# print(f"Added {display_name} integration connector with GUID {integration_guids[display_name]}")
|
616
657
|
|
617
658
|
|
618
|
-
|
619
659
|
if __name__ == "__main__":
|
620
660
|
try:
|
621
661
|
connection = Client(
|