pyegeria 0.1.1.5__py3-none-any.whl → 0.1.1.6__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.
@@ -27,9 +27,6 @@ class CoreServerConfig(Client):
27
27
  services in the OMAG server.
28
28
 
29
29
  Methods:
30
- - __init__(server_name: str, platform_url: str, user_id: str, user_pwd: str = None,
31
- verify_flag: bool = enable_ssl_check):
32
- Constructor method for the CoreServerConfig class.
33
30
 
34
31
  - get_stored_configuration(server_name: str = None) -> dict:
35
32
  Retrieves all the configuration documents for a server.
@@ -0,0 +1,437 @@
1
+ """
2
+
3
+ This module contains the core OMAG configuration class and its methods.
4
+
5
+ """
6
+ from datetime import datetime
7
+
8
+ # import json
9
+ from pyegeria._client import Client, max_paging_size
10
+ from pyegeria._globals import enable_ssl_check
11
+ from pyegeria._validators import (
12
+ validate_name,
13
+ validate_guid,
14
+ validate_url, validate_search_string,
15
+ )
16
+ from pyegeria.utils import body_slimmer
17
+
18
+ class GlossaryBrowser(Client):
19
+ """
20
+ CoreServerConfig is a class that extends the Client class. It provides methods to configure and interact with access
21
+ services in the OMAG server.
22
+
23
+ Methods:
24
+
25
+ - get_stored_configuration(server_name: str = None) -> dict:
26
+ Retrieves all the configuration documents for a server.
27
+
28
+ - get_configured_access_services(server_name: str = None) -> dict:
29
+ Returns the list of access services that are configured for this server.
30
+
31
+ - configure_all_access_services(server_name: str = None) -> None:
32
+ Enables all access services that are registered with this server platform.
33
+
34
+ - configure_all_access_services_no_topics(server_name: str = None) -> None:
35
+ Configures all access services for the specified server with no cohort/Event Bus.
36
+
37
+ - clear_all_access_services(server_name: str = None) -> None:
38
+ Disables the access services. This removes all configuration for the access services and disables the
39
+ enterprise repository services.
40
+
41
+ - get_access_service_config(access_service_name: str, server_name: str = None) -> dict:
42
+ Retrieves the config for an access service.
43
+
44
+ - configure_access_service(access_service_name: str, server_name: str = None) -> None:
45
+ Enables a single access service.
46
+ """
47
+
48
+ def __init__(
49
+ self,
50
+ server_name: str,
51
+ platform_url: str,
52
+ token: str = None,
53
+ user_id: str = None,
54
+ user_pwd: str = None,
55
+ verify_flag: bool = enable_ssl_check,
56
+ ):
57
+ self.admin_command_root: str
58
+ Client.__init__(self, server_name, platform_url, user_id = user_id, token=token)
59
+
60
+ #
61
+ # Glossaries
62
+ #
63
+ def find_glossaries(self, search_string: str, effective_time: str = None, starts_with: bool = False,
64
+ ends_with:bool = False, ignore_case: bool = False, for_lineage:bool = False,
65
+ for_duplicate_processing: bool = False, type_name: str= None,server_name: str = None,
66
+ start_from: int = 0, page_size: int = None) -> list | str:
67
+ """ Retrieve the list of glossary metadata elements that contain the search string.
68
+ The search string is located in the request body and is interpreted as a plain string.
69
+ The request parameters, startsWith, endsWith and ignoreCase can be used to allow a fuzzy search.
70
+
71
+ Parameters
72
+ ----------
73
+ search_string: str,
74
+ Search string to use to find matching glossaries. If the search string is '*' then all glossaries returned.
75
+
76
+ effective_time: str, [default=None], optional
77
+ Effective time of the query. If not specified will default to any time.
78
+ server_name : str, optional
79
+ The name of the server to configure.
80
+ If not provided, the server name associated with the instance is used.
81
+ starts_with : bool, [default=False], optional
82
+ Starts with the supplied string.
83
+ ends_with : bool, [default=False], optional
84
+ Ends with the supplied string
85
+ ignore_case : bool, [default=False], optional
86
+ Ignore case when searching
87
+ for_lineage : bool, [default=False], optional
88
+
89
+ for_duplicate_processing : bool, [default=False], optional
90
+ type_name: str, [default=None], optional
91
+ An optional parameter indicating the subtype of the glossary to filter by.
92
+ Values include 'ControlledGlossary', 'EditingGlossary', and 'StagingGlossary'
93
+ Returns
94
+ -------
95
+ List | str
96
+
97
+ A list of glossary definitions
98
+
99
+ Raises
100
+ ------
101
+
102
+ InvalidParameterException
103
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
104
+ PropertyServerException
105
+ Raised by the server when an issue arises in processing a valid request
106
+ NotAuthorizedException
107
+ The principle specified by the user_id does not have authorization for the requested action
108
+
109
+ """
110
+ if server_name is None:
111
+ server_name = self.server_name
112
+ if page_size is None:
113
+ page_size = self.page_size
114
+ starts_with_s = str(starts_with).lower()
115
+ ends_with_s = str(ends_with).lower()
116
+ ignore_case_s = str(ignore_case).lower()
117
+ for_lineage_s = str(for_lineage).lower()
118
+ for_duplicate_processing_s = str(for_duplicate_processing).lower()
119
+
120
+ validate_search_string(search_string)
121
+
122
+ if search_string is '*':
123
+ search_string = None
124
+
125
+ body = {
126
+ "class": "SearchStringRequestBody",
127
+ "searchString": search_string,
128
+ "effectiveTime": effective_time,
129
+ "typeName" : type_name
130
+ }
131
+ body = body_slimmer(body)
132
+ # print(f"\n\nBody is: \n{body}")
133
+
134
+ url = (f"{self.platform_url}/servers/{server_name}/api/open-metadata/glossary-browser/glossaries/"
135
+ f"by-search-string?startFrom={start_from}&pageSize={page_size}&startsWith={starts_with_s}&"
136
+ f"endsWith={ends_with_s}&ignoreCase={ignore_case_s}&forLineage={for_lineage_s}&"
137
+ f"forDuplicateProcessing={for_duplicate_processing_s}")
138
+
139
+ response = self.make_request("POST", url, body)
140
+ return response.json().get("elementList","No glossaries found")
141
+
142
+
143
+ def get_glossary_by_guid(self, glossary_guid: str, server_name: str = None) -> dict:
144
+ """ Retrieves information about a glossary
145
+ Parameters
146
+ ----------
147
+ glossary_guid : str
148
+ Unique idetifier for the glossary
149
+ server_name : str, optional
150
+ The name of the server to get the configured access services for.
151
+ If not provided, the server name associated with the instance is used.
152
+ Returns
153
+ -------
154
+ dict
155
+ The glossary definition associated with the glossary_guid
156
+
157
+ Raises
158
+ ------
159
+ InvalidParameterException
160
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
161
+ PropertyServerException
162
+ Raised by the server when an issue arises in processing a valid request.
163
+ NotAuthorizedException
164
+ The principle specified by the user_id does not have authorization for the requested action.
165
+ Notes
166
+ -----
167
+ """
168
+
169
+ if server_name is None:
170
+ server_name = self.server_name
171
+ validate_guid(glossary_guid)
172
+
173
+ url = (f"{self.platform_url}/servers/{server_name}/api/open-metadata/glossary-browser/glosaries/"
174
+ f"{glossary_guid}/retrieve")
175
+
176
+ response = self.make_request("GET", url)
177
+ return response.json()
178
+
179
+
180
+ def get_glossaries_by_name(self, glossary_name: str, effective_time: datetime = None, server_name: str = None,
181
+ start_from: int = 0, page_size: int = None) -> dict | str:
182
+ """ Retrieve the list of glossary metadata elements with an exactly matching qualified or display name.
183
+ There are no wildcards supported on this request.
184
+
185
+ Parameters
186
+ ----------
187
+ glossary_name: str,
188
+ Name of the glossary to be retrieved
189
+ effective_time: datetime, [default=None], optional
190
+ Effective time of the query. If not specified will default to any effective time.
191
+ server_name : str, optional
192
+ The name of the server to configure.
193
+ If not provided, the server name associated with the instance is used.
194
+
195
+ Returns
196
+ -------
197
+ None
198
+
199
+ Raises
200
+ ------
201
+
202
+ InvalidParameterException
203
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
204
+ PropertyServerException
205
+ Raised by the server when an issue arises in processing a valid request
206
+ NotAuthorizedException
207
+ The principle specified by the user_id does not have authorization for the requested action
208
+ ConfigurationErrorException
209
+ Raised when configuration parameters passed on earlier calls turn out to be
210
+ invalid or make the new call invalid.
211
+ """
212
+ if server_name is None:
213
+ server_name = self.server_name
214
+ if page_size is None:
215
+ page_size = self.page_size
216
+ validate_name(glossary_name)
217
+
218
+ if effective_time is None:
219
+ body = {"name": glossary_name}
220
+ else:
221
+ body = {"name": glossary_name, "effectiveTime": effective_time}
222
+
223
+ url = (f"{self.platform_url}/servers/{server_name}/api/open-metadata/glossary-browser/glossaries/"
224
+ f"by-name?startFrom={start_from}&pageSize={page_size}")
225
+
226
+ response = self.make_request("POST", url, body)
227
+ return response.json()
228
+
229
+
230
+ def get_terms_for_glossary(self, glossary_guid: str, server_name: str = None, effective_time: datetime= None,
231
+ start_from: int = 0, page_size: int = None) -> list | str:
232
+ """ Retrieve the list of glossary terms associated with a glossary.
233
+ The request body also supports the specification of an effective time for the query.
234
+ Parameters
235
+ ----------
236
+ glossary_guid : str
237
+ Unique idetifier for the glossary
238
+ server_name : str, optional
239
+ The name of the server to get the configured access services for.
240
+ If not provided, the server name associated with the instance is used.
241
+ effective_time : str, optional
242
+ If specified, the query is performed as of the `effective_time`
243
+ start_from: int, optional defaults to 0
244
+ The page number to start retrieving elements from
245
+ page_size : int, optional defaults to None
246
+ The number of elements to retrieve
247
+ Returns
248
+ -------
249
+ dict
250
+ The glossary definition associated with the glossary_guid
251
+
252
+ Raises
253
+ ------
254
+ InvalidParameterException
255
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values.
256
+ PropertyServerException
257
+ Raised by the server when an issue arises in processing a valid request.
258
+ NotAuthorizedException
259
+ The principle specified by the user_id does not have authorization for the requested action.
260
+ Notes
261
+ -----
262
+ """
263
+
264
+ if server_name is None:
265
+ server_name = self.server_name
266
+ validate_guid(glossary_guid)
267
+
268
+ if page_size is None:
269
+ page_size = self.page_size
270
+
271
+ url = (f"{self.platform_url}/servers/{server_name}/api/open-metadata/glossary-browser/glossaries/"
272
+ f"{glossary_guid}/terms/retrieve?startFrom={start_from}&pageSize={page_size}")
273
+
274
+ if effective_time is not None:
275
+ body = {
276
+ "effectiveTime": str(effective_time)
277
+ }
278
+ response = self.make_request("POST", url, body)
279
+ else:
280
+ response = self.make_request("POST", url)
281
+ return response.json().get("elementList","No terms found")
282
+
283
+ def get_glossary_for_term(self, term_guid: str, server_name: str=None, effective_time: datetime = None,
284
+ for_lineage: bool=False, for_duplicate_processing: bool=False) ->dict:
285
+ if server_name is None:
286
+ server_name = self.server_name
287
+ validate_guid(term_guid)
288
+ for_lineage_s = str(for_lineage).lower()
289
+ for_duplicate_processing_s = str(for_duplicate_processing).lower()
290
+
291
+ body = {
292
+ "class" : "EffectiveTimeQueryRequestBody",
293
+ "effectiveTime" : effective_time
294
+ }
295
+ url = (f"{self.platform_url}/servers/{server_name}/api/open-metadata/glossary-browser/glossaries/"
296
+ f"for-term/{term_guid}/retrieve?forLineage={for_lineage_s}&"
297
+ f"forDuplicateProcessing={for_duplicate_processing_s}"
298
+
299
+ )
300
+
301
+ response = self.make_request("POST", url, body)
302
+ return response.json()
303
+
304
+
305
+ def get_terms_by_name(self, term: str, glossary_guid:str = None, status_filter: list=[], server_name: str=None,
306
+ effective_time: datetime=None, for_lineage: bool=False, for_duplicate_processing: bool=False,
307
+ start_from: int=0, page_size: int=None) ->list:
308
+ if server_name is None:
309
+ server_name = self.server_name
310
+ if page_size is None:
311
+ page_size = self.page_size
312
+
313
+ validate_name(term)
314
+
315
+ for_lineage_s = str(for_lineage).lower()
316
+ for_duplicate_processing_s = str(for_duplicate_processing).lower()
317
+
318
+
319
+ body = {
320
+ "class": "GlossaryNameRequestBody",
321
+ "glossaryGUID": glossary_guid,
322
+ "name" : term,
323
+ "effectiveTime": effective_time,
324
+ "limitResultsByStatus" : status_filter
325
+ }
326
+ # body = body_slimmer(body)
327
+
328
+
329
+ url = (f"{self.platform_url}/servers/{server_name}/api/open-metadata/glossary-browser/glossaries/"
330
+ f"terms/by-name?startFrom={start_from}&pageSize={page_size}&"
331
+ f"&forLineage={for_lineage_s}&forDuplicateProcessing={for_duplicate_processing_s}")
332
+
333
+ # print(f"\n\nURL is: \n {url}\n\nBody is: \n{body}")
334
+
335
+ response = self.make_request("POST", url, body)
336
+ return response.json().get("elementList","No terms found")
337
+
338
+ def find_glossary_terms(self, search_string: str, glossary_guid: str = None, status_filter: list=[],
339
+ effective_time: str = None, starts_with: bool = False,
340
+ ends_with:bool = False, ignore_case: bool = False, for_lineage:bool = False,
341
+ for_duplicate_processing: bool = False,server_name: str = None,
342
+ start_from: int = 0, page_size: int = None) -> list | str:
343
+
344
+ """ Retrieve the list of glossary term metadata elements that contain the search string.
345
+
346
+ Parameters
347
+ ----------
348
+ search_string: str
349
+ Search string to use to find matching glossaries. If the search string is '*' then all glossaries returned.
350
+ glossary_guid str
351
+ Identifier of the glossary to search within. If None, then all glossaries are searched.
352
+ status_filter: list, default = [], optional
353
+ Filters the results by the included Term statuses (such as 'ACTIVE', 'DRAFT'). If not specified,
354
+ the results will not be filtered.
355
+ effective_time: str, [default=None], optional
356
+ Effective time of the query. If not specified will default to any time.
357
+ If the effective time is not in the right format then it will be considered any.
358
+ server_name : str, optional
359
+ The name of the server to configure.
360
+ If not provided, the server name associated with the instance is used.
361
+ starts_with : bool, [default=False], optional
362
+ Starts with the supplied string.
363
+ ends_with : bool, [default=False], optional
364
+ Ends with the supplied string
365
+ ignore_case : bool, [default=False], optional
366
+ Ignore case when searching
367
+ for_lineage : bool, [default=False], optional
368
+
369
+ for_duplicate_processing : bool, [default=False], optional
370
+
371
+ start_from: str, [default=0], optional
372
+ Page of results to start from
373
+ page_size : int, optional
374
+ Number of elements to return per page - if None, then default for class will be used.
375
+
376
+ Returns
377
+ -------
378
+ List | str
379
+
380
+ A list of term definitions
381
+
382
+ Raises
383
+ ------
384
+ InvalidParameterException
385
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
386
+ PropertyServerException
387
+ Raised by the server when an issue arises in processing a valid request
388
+ NotAuthorizedException
389
+ The principle specified by the user_id does not have authorization for the requested action
390
+
391
+ Notes
392
+ -----
393
+ The search string is located in the request body and is interpreted as a plain string.
394
+ The request parameters, startsWith, endsWith and ignoreCase can be used to allow a fuzzy search.
395
+ The request body also supports the specification of a glossaryGUID to restrict the search to within a single glossary.
396
+ """
397
+ if server_name is None:
398
+ server_name = self.server_name
399
+ if page_size is None:
400
+ page_size = self.page_size
401
+ if effective_time is None:
402
+ effective_time = datetime.now().isoformat()
403
+ starts_with_s = str(starts_with).lower()
404
+ ends_with_s = str(ends_with).lower()
405
+ ignore_case_s = str(ignore_case).lower()
406
+ for_lineage_s = str(for_lineage).lower()
407
+ for_duplicate_processing_s = str(for_duplicate_processing).lower()
408
+ if search_string is '*':
409
+ search_string = None
410
+
411
+ # validate_search_string(search_string)
412
+
413
+
414
+ body = {
415
+ "class": "GlossarySearchStringRequestBody",
416
+ "glossaryGUID": glossary_guid,
417
+ "searchString": search_string,
418
+ "effectiveTime": effective_time,
419
+ "limitResultsByStatus": status_filter
420
+ }
421
+ # body = body_slimmer(body)
422
+
423
+
424
+ url = (f"{self.platform_url}/servers/{server_name}/api/open-metadata/glossary-browser/glossaries/"
425
+ f"terms/by-search-string?startFrom={start_from}&pageSize={page_size}&startsWith={starts_with_s}&"
426
+ f"endsWith={ends_with_s}&ignoreCase={ignore_case_s}&forLineage={for_lineage_s}&"
427
+ f"forDuplicateProcessing={for_duplicate_processing_s}")
428
+
429
+ print(f"\n\nURL is: \n {url}\n\nBody is: \n{body}")
430
+
431
+ response = self.make_request("POST", url, body)
432
+ return response.json().get("elementList","No terms found")
433
+ # return response.text
434
+
435
+ #
436
+ # Catagories
437
+ #
@@ -49,6 +49,8 @@ class Platform(ServerOps):
49
49
 
50
50
  activate_server_supplied_config(self, config_body: str, server: str = None, timeout: int = 30) -> None
51
51
 
52
+ get_active_server_instance_status(self, server: str = None)-> dict | str
53
+
52
54
  get_known_servers(self) -> list[str] | str
53
55
 
54
56
  is_server_known(self, server: str = None) -> bool
@@ -270,6 +272,34 @@ class Platform(ServerOps):
270
272
  url = self.admin_command_root + "/servers/" + server + "/instance/configuration"
271
273
  self.make_request("POST", url, config_body, time_out=timeout)
272
274
 
275
+ def get_active_server_instance_status(self, server: str = None)-> dict | str:
276
+ """ Get the current status of all services running in the specified active server.
277
+
278
+ Parameters
279
+ ----------
280
+ server : str, optional
281
+ The current active server we want to get status from.
282
+ If None, use the default server associated with the Platform object.
283
+ Returns
284
+ -------
285
+ List of server status.
286
+
287
+ Raises
288
+ ------
289
+ InvalidParameterException
290
+ If the client passes incorrect parameters on the request - such as bad URLs or invalid values
291
+ PropertyServerException
292
+ Raised by the server when an issue arises in processing a valid request
293
+ NotAuthorizedException
294
+ The principle specified by the user_id does not have authorization for the requested action
295
+ """
296
+ if server is None:
297
+ server = self.server_name
298
+
299
+ url = f"{self.admin_command_root}/servers/{server}/instance/status"
300
+ response = self.make_request("GET", url)
301
+ return response.json().get("serverStatus", "No status found")
302
+
273
303
  def get_known_servers(self) -> list[str] | str:
274
304
  """ List all known servers on the associated platform.
275
305
 
@@ -510,7 +540,7 @@ class Platform(ServerOps):
510
540
  except (InvalidParameterException, PropertyServerException, UserNotAuthorizedException) as e:
511
541
  raise (e)
512
542
 
513
- def activate_servers_on_platform(self, server_list: str) -> bool:
543
+ def activate_servers_on_platform(self, server_list: [str]) -> bool:
514
544
  """ Activate the servers from the list provided.
515
545
  Parameters
516
546
  ----------
@@ -13,7 +13,6 @@ companion service is also configured and running.
13
13
  import pandas as pd
14
14
  from tabulate import tabulate
15
15
 
16
- from ._validators import validate_name
17
16
  from .utils import wrap_text
18
17
 
19
18
  from ._client import Client
@@ -49,13 +48,14 @@ class RegisteredInfo(Client):
49
48
 
50
49
  def __init__(
51
50
  self,
52
- server_name: str,
53
51
  platform_url: str,
54
52
  user_id: str,
55
53
  user_pwd: str = None,
56
54
  verify_flag: bool = False,
55
+ server_name: str = None
57
56
  ):
58
- validate_name(server_name)
57
+ if server_name is None:
58
+ server_name = "NA"
59
59
  Client.__init__(self, server_name, platform_url,
60
60
  user_id, user_pwd, verify_flag)
61
61
  self.admin_command_root = (f"{self.platform_url}/open-metadata/platform-services/users/"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyegeria
3
- Version: 0.1.1.5
3
+ Version: 0.1.1.6
4
4
  Summary: A python client for Egeria
5
5
  Project-URL: Homepage, https://github.com/odpi/egeria-python
6
6
  Project-URL: Issues, https://github.com/odpi/egeria-python/issues
@@ -4,12 +4,13 @@ pyegeria/_exceptions.py,sha256=E4d60USV3A6X7e3WzE0f7o7U7wAntS0ajvXeMrBKRzg,18306
4
4
  pyegeria/_globals.py,sha256=WgJ6O7_ACiAG8CUUHT_AbGgahLhO0APU8Y4rCwv9DRw,558
5
5
  pyegeria/_validators.py,sha256=1K50pJQrppx1r6-bJU5saEQ8Q7DBZcxS8hjMCWcSjJY,12626
6
6
  pyegeria/config.toml,sha256=2Jp6ozhlVgDLWeG5702dTTAYEUv_jYNAFFWpEyR8xV8,214
7
- pyegeria/core_omag_server_config.py,sha256=AhJqXxNkbY_lKDlXJxyZ-UrmGr2Ohqsg-W35W5h9gQ8,89024
8
- pyegeria/platform_services.py,sha256=DCEkcQ-qXZ115crfc4sSpow-YgcVNF-PBMTYJy52Va4,19653
9
- pyegeria/registered_info.py,sha256=TZ35uRmR-lgYZjGa09Ae6wbigm7c9XhNCx_7K67JT6E,7407
7
+ pyegeria/core_omag_server_config.py,sha256=h8DQVACLxYNPE9C4my_-jCAfh7XgAlS9AW5iLAIBI2s,88812
8
+ pyegeria/glossary_omvs.py,sha256=uK3RF5-NyyuUuUWGVzdt-mXGvj07SvALD67fQGxB8wI,18487
9
+ pyegeria/platform_services.py,sha256=ic9SPpI8s6_PEiudqJEVAXveysvXcUJhWQh21zs78VM,21016
10
+ pyegeria/registered_info.py,sha256=f9cskHLHFrbLFtE4kBqkIV1ljS0W_M798A2gUV4KuLc,7402
10
11
  pyegeria/server_operations.py,sha256=HADaidO7lGygbGHxNYeBVv36orxFOJ7c-js56jtOM1w,7959
11
12
  pyegeria/utils.py,sha256=uRw8TFlVBOQl_lem8Inm-zzXoWgCJblZHRNvEgSc738,5257
12
- pyegeria-0.1.1.5.dist-info/METADATA,sha256=v-bxRvDjoXdZW6GBARxyGI8tsRLGeaXjqxk2r348jzY,2124
13
- pyegeria-0.1.1.5.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
14
- pyegeria-0.1.1.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
15
- pyegeria-0.1.1.5.dist-info/RECORD,,
13
+ pyegeria-0.1.1.6.dist-info/METADATA,sha256=WhOUqNZlhE1zbGhMLsXr29WKCFCbAmrsEbIyM2XmDHU,2124
14
+ pyegeria-0.1.1.6.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
15
+ pyegeria-0.1.1.6.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
16
+ pyegeria-0.1.1.6.dist-info/RECORD,,