pyPreservica 0.9.9__py3-none-any.whl → 3.3.4__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.
@@ -1,5 +1,16 @@
1
+ """
2
+ pyPreservica RetentionAPI module definition
3
+
4
+ A client library for the Preservica Repository web services Entity API
5
+ https://us.preservica.com/api/entity/documentation.html
6
+
7
+ author: James Carr
8
+ licence: Apache License 2.0
9
+
10
+ """
11
+
1
12
  import xml.etree.ElementTree
2
- from typing import Set
13
+ from typing import Set, Callable
3
14
 
4
15
  from pyPreservica.common import *
5
16
 
@@ -31,6 +42,9 @@ class RetentionPolicy:
31
42
  self.start_date_field = ""
32
43
  self.period = ""
33
44
  self.expiry_action = ""
45
+ self.assignable = True
46
+ self.restriction = ""
47
+ self.period_unit = ""
34
48
 
35
49
  def __str__(self):
36
50
  return f"Ref:\t\t\t{self.reference}\n" \
@@ -43,17 +57,28 @@ class RetentionPolicy:
43
57
 
44
58
  class RetentionAPI(AuthenticatedAPI):
45
59
 
46
- def __init__(self, username=None, password=None, tenant=None, server=None, use_shared_secret=False):
47
- super().__init__(username, password, tenant, server, use_shared_secret)
60
+ def __init__(self, username=None, password=None, tenant=None, server=None, use_shared_secret=False,
61
+ two_fa_secret_key: str = None, protocol: str = "https", request_hook: Callable = None, credentials_path: str = 'credentials.properties'):
62
+ super().__init__(username, password, tenant, server, use_shared_secret, two_fa_secret_key,
63
+ protocol, request_hook, credentials_path)
64
+
48
65
  if self.major_version < 7 and self.minor_version < 2:
49
66
  raise RuntimeError("Retention API is only available when connected to a v6.2 System")
50
67
 
51
68
  def policy(self, reference: str) -> RetentionPolicy:
52
69
  """
53
- Return a retention policy by its reference
54
- """
70
+ Return a retention policy by reference
71
+
72
+ :param reference: The policy reference
73
+ :type reference: str
74
+
75
+ :return: The retention policy
76
+ :rtype: RetentionPolicy
77
+
78
+ """
55
79
  headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/xml;charset=UTF-8'}
56
- request = requests.get(f'https://{self.server}/api/entity/retention-policies/{reference}', headers=headers)
80
+ request = self.session.get(f'{self.protocol}://{self.server}/api/entity/retention-policies/{reference}',
81
+ headers=headers)
57
82
  if request.status_code == requests.codes.ok:
58
83
  xml_response = str(request.content.decode('utf-8'))
59
84
  logger.debug(xml_response)
@@ -67,22 +92,33 @@ class RetentionAPI(AuthenticatedAPI):
67
92
  security_tag = entity_response.find(f'.//{{{self.rm_ns}}}RetentionPolicy/{{{self.rm_ns}}}SecurityTag').text
68
93
  rp.security_tag = security_tag
69
94
  start_date_field = entity_response.find(
70
- f'.//{{{self.rm_ns}}}RetentionPolicy/{{{self.rm_ns}}}StartDateField').text
71
- rp.start_date_field = start_date_field
72
- period = entity_response.find(f'.//{{{self.rm_ns}}}RetentionPolicy/{{{self.rm_ns}}}Period').text
73
- rp.period = period
74
- period_unit = entity_response.find(f'.//{{{self.rm_ns}}}RetentionPolicy/{{{self.rm_ns}}}PeriodUnit').text
75
- rp.period_unit = period_unit
76
- expiry_action = entity_response.find(
77
- f'.//{{{self.rm_ns}}}RetentionPolicy/{{{self.rm_ns}}}ExpiryAction').text
78
- rp.expiry_action = expiry_action
95
+ f'.//{{{self.rm_ns}}}RetentionPolicy/{{{self.rm_ns}}}StartDateField')
96
+ if start_date_field is not None:
97
+ rp.start_date_field = start_date_field.text
98
+ else:
99
+ rp.start_date_field = None
100
+ period = entity_response.find(f'.//{{{self.rm_ns}}}RetentionPolicy/{{{self.rm_ns}}}Period')
101
+ if period is not None:
102
+ rp.period = period.text
103
+ else:
104
+ rp.period = None
105
+ period_unit = entity_response.find(f'.//{{{self.rm_ns}}}RetentionPolicy/{{{self.rm_ns}}}PeriodUnit')
106
+ if period_unit is not None:
107
+ rp.period_unit = period_unit.text
108
+ else:
109
+ rp.period_unit = None
110
+ expiry_action = entity_response.find(f'.//{{{self.rm_ns}}}RetentionPolicy/{{{self.rm_ns}}}ExpiryAction')
111
+ if expiry_action is not None:
112
+ rp.expiry_action = expiry_action.text
113
+ else:
114
+ rp.expiry_action = None
79
115
  restriction = entity_response.find(f'.//{{{self.rm_ns}}}RetentionPolicy/{{{self.rm_ns}}}Restriction')
80
116
  if restriction is not None:
81
117
  rp.restriction = restriction.text
82
118
  else:
83
119
  rp.restriction = None
84
120
  assignable = entity_response.find(f'.//{{{self.rm_ns}}}RetentionPolicy/{{{self.rm_ns}}}Assignable')
85
- rp.assignable = bool(assignable.text == "true")
121
+ rp.assignable = strtobool(assignable.text)
86
122
  return rp
87
123
  elif request.status_code == requests.codes.unauthorized:
88
124
  self.token = self.__token__()
@@ -92,10 +128,23 @@ class RetentionAPI(AuthenticatedAPI):
92
128
  raise RuntimeError(request.status_code, "policy failed")
93
129
 
94
130
  def assignable_policy(self, reference: str, status: bool):
131
+ """
132
+ Make a policy assignable
133
+
134
+ :param reference: The policy ID
135
+ :type reference: str
136
+
137
+ :param status: The assignable status
138
+ :type status: bool
139
+
140
+
141
+ :return:
142
+ """
95
143
  headers = {HEADER_TOKEN: self.token, 'Content-Type': 'text/plain;charset=UTF-8'}
96
144
  data = str(status)
97
- request = requests.put(f'https://{self.server}/api/entity/retention-policies/{reference}/assignable',
98
- headers=headers, data=data)
145
+ request = self.session.put(
146
+ f'{self.protocol}://{self.server}/api/entity/retention-policies/{reference}/assignable',
147
+ headers=headers, data=data)
99
148
  if request.status_code == requests.codes.ok:
100
149
  pass
101
150
  elif request.status_code == requests.codes.unauthorized:
@@ -190,16 +239,17 @@ class RetentionAPI(AuthenticatedAPI):
190
239
 
191
240
  xml_request = xml.etree.ElementTree.tostring(retention_policy, encoding='utf-8')
192
241
 
193
- request = requests.put(f'https://{self.server}/api/entity/retention-policies', data=xml_request,
194
- headers=headers)
242
+ request = self.session.put(f'{self.protocol}://{self.server}/api/entity/retention-policies/{reference}',
243
+ data=xml_request,
244
+ headers=headers)
195
245
  if request.status_code == requests.codes.ok:
196
246
  return self.policy(reference)
197
247
  elif request.status_code == requests.codes.unauthorized:
198
248
  self.token = self.__token__()
199
249
  return self.update_policy(reference, **kwargs)
200
250
  else:
201
- print(str(request.content.decode('utf-8')))
202
- raise RuntimeError(request.status_code, "update_policy failed")
251
+ logger.error(str(request.content.decode('utf-8')))
252
+ raise RuntimeError(request.status_code, "update_policy failed " + str(request.content.decode('utf-8')))
203
253
 
204
254
  def create_policy(self, **kwargs):
205
255
  """
@@ -285,8 +335,8 @@ class RetentionAPI(AuthenticatedAPI):
285
335
 
286
336
  xml_request = xml.etree.ElementTree.tostring(retention_policy, encoding='utf-8')
287
337
 
288
- request = requests.post(f'https://{self.server}/api/entity/retention-policies', data=xml_request,
289
- headers=headers)
338
+ request = self.session.post(f'{self.protocol}://{self.server}/api/entity/retention-policies', data=xml_request,
339
+ headers=headers)
290
340
  if request.status_code == requests.codes.ok:
291
341
  xml_response = str(request.content.decode('utf-8'))
292
342
  entity_response = xml.etree.ElementTree.fromstring(xml_response)
@@ -304,9 +354,14 @@ class RetentionAPI(AuthenticatedAPI):
304
354
  def delete_policy(self, reference: str):
305
355
  """
306
356
  Delete a retention policy
357
+
358
+ :param reference: The policy reference
359
+ :type reference: str
360
+
307
361
  """
308
362
  headers = {HEADER_TOKEN: self.token}
309
- request = requests.delete(f'https://{self.server}/api/entity/retention-policies/{reference}', headers=headers)
363
+ request = self.session.delete(f'{self.protocol}://{self.server}/api/entity/retention-policies/{reference}',
364
+ headers=headers)
310
365
  if request.status_code == requests.codes.no_content:
311
366
  pass
312
367
  elif request.status_code == requests.codes.unauthorized:
@@ -319,10 +374,18 @@ class RetentionAPI(AuthenticatedAPI):
319
374
  def policy_by_name(self, name: str) -> RetentionPolicy:
320
375
  """
321
376
  Return a retention policy by name
377
+
378
+ :param name: The policy name
379
+ :type name: str
380
+
381
+ :return: The retention policy
382
+ :rtype: RetentionPolicy
383
+
322
384
  """
323
385
  headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/xml;charset=UTF-8'}
324
386
  data = {'start': str(0), 'max': "250"}
325
- request = requests.get(f'https://{self.server}/api/entity/retention-policies', data=data, headers=headers)
387
+ request = self.session.get(f'{self.protocol}://{self.server}/api/entity/retention-policies', data=data,
388
+ headers=headers)
326
389
  if request.status_code == requests.codes.ok:
327
390
  xml_response = str(request.content.decode('utf-8'))
328
391
  logger.debug(xml_response)
@@ -338,28 +401,44 @@ class RetentionAPI(AuthenticatedAPI):
338
401
  else:
339
402
  raise RuntimeError(request.status_code, "policies failed")
340
403
 
341
- def policies(self) -> Set[RetentionPolicy]:
404
+ def policies(self, maximum: int = 250, next_page: str = None) -> PagedSet:
342
405
  """
343
406
  Return a list of all retention policies
344
- Only returns the first 250 policies in the system
407
+ Returns a maximum of 250 policies by default
408
+
409
+
410
+ :return: Set of retention policies
411
+ :rtype: Set[RetentionPolicy]
412
+
345
413
  """
346
414
  headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/xml;charset=UTF-8'}
347
- data = {'start': str(0), 'max': "250"}
348
- request = requests.get(f'https://{self.server}/api/entity/retention-policies', data=data, headers=headers)
415
+
416
+ if next_page is None:
417
+ params = {'start': '0', 'max': str(maximum)}
418
+ request = self.session.get(f'{self.protocol}://{self.server}/api/entity/retention-policies', params=params,
419
+ headers=headers)
420
+ else:
421
+ request = self.session.get(next_page, headers=headers)
422
+
349
423
  if request.status_code == requests.codes.ok:
350
424
  xml_response = str(request.content.decode('utf-8'))
351
425
  entity_response = xml.etree.ElementTree.fromstring(xml_response)
352
426
  logger.debug(xml_response)
353
427
  result = set()
428
+ next_url = entity_response.find(f'.//{{{self.entity_ns}}}Paging/{{{self.entity_ns}}}Next')
354
429
  total_results = int(entity_response.find(
355
430
  f'.//{{{self.entity_ns}}}TotalResults').text)
356
- if total_results > 250:
357
- logger.error("Not all retention policies have been returned.")
358
431
  for assignment in entity_response.findall(f'.//{{{self.entity_ns}}}RetentionPolicy'):
359
432
  ref = assignment.attrib['ref']
360
433
  name = assignment.attrib['name']
361
434
  result.add(self.policy(reference=ref))
362
- return result
435
+ has_more = True
436
+ url = None
437
+ if next_url is None:
438
+ has_more = False
439
+ else:
440
+ url = next_url.text
441
+ return PagedSet(result, has_more, total_results, url)
363
442
  elif request.status_code == requests.codes.unauthorized:
364
443
  self.token = self.__token__()
365
444
  return self.policies()
@@ -368,7 +447,16 @@ class RetentionAPI(AuthenticatedAPI):
368
447
 
369
448
  def add_assignments(self, entity: Entity, policy: RetentionPolicy) -> RetentionAssignment:
370
449
  """
371
- assign a retention policy to an asset.
450
+ Assign a retention policy to an Asset.
451
+
452
+ :param entity: The Preservica Entity to assign a policy to
453
+ :type entity: Entity
454
+
455
+ :param policy: The RetentionAssignment
456
+ :type policy: RetentionPolicy
457
+
458
+ :return: The RetentionAssignment
459
+ :rtype: RetentionAssignment
372
460
 
373
461
  """
374
462
  headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/xml;charset=UTF-8'}
@@ -379,8 +467,8 @@ class RetentionAPI(AuthenticatedAPI):
379
467
  xml.etree.ElementTree.SubElement(assignment, "RetentionPolicy").text = policy.reference
380
468
  xml_request = xml.etree.ElementTree.tostring(assignment, encoding='utf-8').decode('utf-8')
381
469
  logger.debug(xml_request)
382
- request = requests.post(
383
- f'https://{self.server}/api/entity/{entity.path}/{entity.reference}/retention-assignments',
470
+ request = self.session.post(
471
+ f'{self.protocol}://{self.server}/api/entity/{entity.path}/{entity.reference}/retention-assignments',
384
472
  headers=headers, data=xml_request)
385
473
 
386
474
  if request.status_code == requests.codes.ok:
@@ -389,7 +477,11 @@ class RetentionAPI(AuthenticatedAPI):
389
477
  api_id = entity_response.find(f'.//{{{self.rm_ns}}}ApiId').text
390
478
  policy_ref = entity_response.find(f'.//{{{self.rm_ns}}}RetentionPolicy').text
391
479
  entity_ref = entity_response.find(f'.//{{{self.rm_ns}}}Entity').text
392
- start_date = entity_response.find(f'.//{{{self.rm_ns}}}StartDate').text
480
+ start_date = entity_response.find(f'.//{{{self.rm_ns}}}StartDate')
481
+ if start_date is not None:
482
+ start_date = start_date.text
483
+ else:
484
+ start_date = None
393
485
  assert entity_ref == entity.reference
394
486
  assert policy_ref == policy.reference
395
487
  return RetentionAssignment(entity_ref, policy_ref, api_id, start_date)
@@ -403,13 +495,21 @@ class RetentionAPI(AuthenticatedAPI):
403
495
 
404
496
  def remove_assignments(self, retention_assignment: RetentionAssignment):
405
497
  """
406
- Delete a retention policy from an asset
407
- """
498
+ Delete a retention policy from an asset
499
+
500
+ :param retention_assignment: The Preservica Entity to assign a policy to
501
+ :type retention_assignment: RetentionAssignment
502
+
503
+
504
+ :return: The Asset Reference
505
+ :rtype: str
506
+
507
+ """
408
508
 
409
509
  headers = {HEADER_TOKEN: self.token}
410
510
 
411
- request = requests.delete(
412
- f'https://{self.server}/api/entity/information-objects/{retention_assignment.entity_reference}/retention'
511
+ request = self.session.delete(
512
+ f'{self.protocol}://{self.server}/api/entity/information-objects/{retention_assignment.entity_reference}/retention'
413
513
  f'-assignments/{retention_assignment.api_id}', headers=headers)
414
514
  if request.status_code == requests.codes.no_content:
415
515
  return retention_assignment.entity_reference
@@ -422,10 +522,17 @@ class RetentionAPI(AuthenticatedAPI):
422
522
  def assignments(self, entity: Entity) -> Set[RetentionAssignment]:
423
523
  """
424
524
  Return a list of retention policies for an entity.
525
+
526
+ :param entity: The entity to fetch assignments for
527
+ :type entity: class:`Entity`
528
+
529
+ :return: Set of policy assignments
530
+ :rtype: Set[RetentionAssignment]
531
+
425
532
  """
426
533
  headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/xml;charset=UTF-8'}
427
- request = requests.get(
428
- f'https://{self.server}/api/entity/{entity.path}/{entity.reference}/retention-assignments',
534
+ request = self.session.get(
535
+ f'{self.protocol}://{self.server}/api/entity/{entity.path}/{entity.reference}/retention-assignments',
429
536
  headers=headers)
430
537
  if request.status_code == requests.codes.ok:
431
538
  xml_response = str(request.content.decode('utf-8'))
@@ -435,7 +542,11 @@ class RetentionAPI(AuthenticatedAPI):
435
542
  entity_ref = assignment.find(f'.//{{{self.rm_ns}}}Entity').text
436
543
  assert entity_ref == entity.reference
437
544
  policy = assignment.find(f'.//{{{self.rm_ns}}}RetentionPolicy').text
438
- start_date = assignment.find(f'.//{{{self.rm_ns}}}StartDate').text
545
+ start_date = assignment.find(f'.//{{{self.rm_ns}}}StartDate')
546
+ if start_date is not None:
547
+ start_date = start_date.text
548
+ else:
549
+ start_date = None
439
550
  expired = bool(assignment.find(f'.//{{{self.rm_ns}}}Expired').text == 'true')
440
551
  api_id = assignment.find(f'.//{{{self.rm_ns}}}ApiId').text
441
552
  ra = RetentionAssignment(entity_ref, policy, api_id, start_date, expired)
@@ -0,0 +1,295 @@
1
+ """
2
+ pyPreservica Settings API module definition
3
+
4
+ API for retrieving information about configuration settings.
5
+
6
+ author: James Carr
7
+ licence: Apache License 2.0
8
+
9
+ """
10
+
11
+ from typing import Callable
12
+
13
+ from pyPreservica.common import *
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class SettingsAPI(AuthenticatedAPI):
19
+ """
20
+ API for retrieving information about configuration settings.
21
+
22
+ Includes methods for:
23
+
24
+ * metadata-enrichment
25
+
26
+ """
27
+
28
+ def __init__(
29
+ self,
30
+ username=None,
31
+ password=None,
32
+ tenant=None,
33
+ server=None,
34
+ use_shared_secret=False,
35
+ two_fa_secret_key: str = None,
36
+ protocol: str = "https",
37
+ request_hook: Callable = None,
38
+ credentials_path: str = "credentials.properties",
39
+ ):
40
+ super().__init__(
41
+ username,
42
+ password,
43
+ tenant,
44
+ server,
45
+ use_shared_secret,
46
+ two_fa_secret_key,
47
+ protocol,
48
+ request_hook,
49
+ credentials_path,
50
+ )
51
+
52
+ if self.major_version < 7 and self.minor_version < 7:
53
+ raise RuntimeError(
54
+ "Settings API is only available when connected to a v7.7 System or higher"
55
+ )
56
+
57
+ self.base_url = "api/settings"
58
+
59
+ def metadata_enrichment_rules(self, profile_id: str = None) -> dict:
60
+ """
61
+ Returns a list of metadata enrichment rules.
62
+ An empty selection implies that the rule is applied to all content.
63
+ Rules define where particular behaviours, defined by profiles, will be applied.
64
+ Rules are evaluated in order, with the first matching rule being applied.
65
+
66
+ :param profile_id: The rules for a specific profile id, Set to None for all rules
67
+ :type profile_id: str
68
+
69
+ """
70
+ headers = {
71
+ HEADER_TOKEN: self.token,
72
+ "Accept": "application/json",
73
+ "Content-Type": "application/json;charset=UTF-8",
74
+ }
75
+
76
+ endpoint: str = "/metadata-enrichment/config/rules"
77
+
78
+ request = self.session.get(
79
+ f"{self.protocol}://{self.server}/{self.base_url}{endpoint}",
80
+ headers=headers)
81
+
82
+ if request.status_code == requests.codes.ok:
83
+ rules: dict = json.loads(request.content.decode("utf-8"))
84
+ if profile_id is None:
85
+ return rules
86
+ else:
87
+ profile_rules = []
88
+ for rule in rules["rules"]:
89
+ if rule["profileId"] == profile_id:
90
+ profile_rules.append(rule)
91
+ return {"rules": profile_rules}
92
+ else:
93
+ logger.debug(request.content.decode("utf-8"))
94
+ raise RuntimeError(request.status_code, f"metadata_enrichment_rules failed")
95
+
96
+ def metadata_enrichment_delete_rule(self, rule_id: str):
97
+ """
98
+ Deletes a metadata enrichment rule.
99
+
100
+ :param rule_id: The rule id
101
+ :type rule_id: str
102
+
103
+ :return: No return value
104
+ :rtype: None
105
+
106
+ """
107
+ headers = {
108
+ HEADER_TOKEN: self.token,
109
+ "Accept": "application/json",
110
+ "Content-Type": "application/json;charset=UTF-8",
111
+ }
112
+
113
+ endpoint: str = f"/metadata-enrichment/config/rules/{rule_id}"
114
+
115
+ request = self.session.delete(
116
+ f"{self.protocol}://{self.server}/{self.base_url}{endpoint}", headers=headers)
117
+
118
+ if request.status_code == requests.codes.no_content:
119
+ return
120
+ else:
121
+ logger.debug(request.content.decode("utf-8"))
122
+ raise RuntimeError(request.status_code, f"metadata_enrichment_delete_rule failed")
123
+
124
+ def metadata_enrichment_add_rule(self, profile_id: str, priority: int = 1):
125
+ """
126
+ Create a metadata enrichment rule to control when metadata enrichment profiles are applied and return it.
127
+ Rules define where particular behaviours, defined by profiles, will be applied.
128
+ Rules are evaluated in order, with the first matching rule being applied.
129
+ Note that not specifying, or specifying an empty selection implies that the rule will be applied to all content.
130
+ Currently only securityDescriptorSelector, representationSelector and hierarchySelector are supported selectors.
131
+ If a rule already exists for the requested priority, existing rules will be shifted down priority to accommodate the new entry.
132
+
133
+ :param profile_id: The profile id
134
+ :type profile_id: str
135
+
136
+ :param priority: The rule priority
137
+ :type priority: int
138
+
139
+ :return: The metadata enrichment rule
140
+ :rtype: dict
141
+ """
142
+
143
+ headers = {
144
+ HEADER_TOKEN: self.token,
145
+ "Accept": "application/json",
146
+ "Content-Type": "application/json;charset=UTF-8",
147
+ }
148
+
149
+ endpoint: str = "/metadata-enrichment/config/rules"
150
+
151
+ rule: dict = {
152
+ "profileId": profile_id,
153
+ "priority": str(priority),
154
+ "selectorSettings": {},
155
+ }
156
+
157
+ request = self.session.post(
158
+ f"{self.protocol}://{self.server}/{self.base_url}/{endpoint}",
159
+ headers=headers,
160
+ json=rule,
161
+ )
162
+ if request.status_code == requests.codes.created:
163
+ return json.loads(request.content.decode("utf-8"))
164
+ else:
165
+ logger.debug(request.content.decode("utf-8"))
166
+ raise RuntimeError(
167
+ request.status_code, f"metadata_enrichment_add_rule failed"
168
+ )
169
+
170
+ def metadata_enrichment_add_profile(self, name: str, active: bool = True):
171
+ """
172
+ Create a metadata enrichment profile to control automatic metadata enrichment of content and return it.
173
+ Profiles define a set of behaviours that will be applied when the profile is selected by a rule.
174
+ A profile has no effect if it is not used by a rule. Includes settings for PII identification.
175
+ PII detection tools may be run against the full text extracted from content.
176
+
177
+
178
+ :param name: The profile name
179
+ :type name: str
180
+
181
+ :param active: The profile active status
182
+ :type active: bool
183
+
184
+ :return: The metadata enrichment profile
185
+ :rtype: dict
186
+
187
+ """
188
+
189
+ headers = {
190
+ HEADER_TOKEN: self.token,
191
+ "Accept": "application/json",
192
+ "Content-Type": "application/json;charset=UTF-8",
193
+ }
194
+
195
+ endpoint: str = "/metadata-enrichment/config/profiles"
196
+
197
+ profile: dict = {"name": name, "piiSettings": {"active": str(active).lower()}}
198
+
199
+ request = self.session.post(
200
+ f"{self.protocol}://{self.server}/{self.base_url}{endpoint}",
201
+ headers=headers, json=profile)
202
+
203
+ if request.status_code == requests.codes.created:
204
+ return json.loads(request.content.decode("utf-8"))
205
+ else:
206
+ logger.debug(request.content.decode("utf-8"))
207
+ raise RuntimeError(request.status_code, f"metadata_enrichment_add_profile failed")
208
+
209
+ def metadata_enrichment_profile(self, profile_id: str) -> dict:
210
+ """
211
+ Returns a single profile by its ID
212
+ Profiles define a set of behaviours that will be applied when the profile is selected by a rule.
213
+ A profile has no effect if it is not used by a rule. Includes settings for PII identification.
214
+ PII detection tools may be run against the full text extracted from content.
215
+
216
+ :param profile_id: The profile name
217
+ :type profile_id: str
218
+
219
+ :return: The metadata enrichment profile
220
+ :rtype: dict
221
+
222
+ """
223
+ headers = {
224
+ HEADER_TOKEN: self.token,
225
+ "Accept": "application/json",
226
+ "Content-Type": "application/json;charset=UTF-8",
227
+ }
228
+
229
+ endpoint: str = f"/metadata-enrichment/config/profiles/{profile_id}"
230
+
231
+ request = self.session.get(
232
+ f"{self.protocol}://{self.server}/{self.base_url}{endpoint}", headers=headers)
233
+
234
+ if request.status_code == requests.codes.ok:
235
+ return json.loads(request.content.decode("utf-8"))
236
+ else:
237
+ logger.debug(request.content.decode("utf-8"))
238
+ raise RuntimeError(request.status_code, f"metadata_enrichment_profile failed")
239
+
240
+ def metadata_enrichment_delete_profile(self, profile_id: str) -> None:
241
+ """
242
+ Deletes a metadata enrichment profile
243
+
244
+ :param profile_id: The profile name
245
+ :type profile_id: str
246
+
247
+ :return: No return value
248
+ :rtype: None
249
+
250
+ """
251
+ headers = {
252
+ HEADER_TOKEN: self.token,
253
+ "Accept": "application/json",
254
+ "Content-Type": "application/json;charset=UTF-8",
255
+ }
256
+
257
+ endpoint: str = f"/metadata-enrichment/config/profiles/{profile_id}"
258
+
259
+ request = self.session.delete(
260
+ f"{self.protocol}://{self.server}/{self.base_url}{endpoint}", headers=headers)
261
+
262
+ if request.status_code == requests.codes.forbidden:
263
+ logger.debug(request.content.decode("utf-8"))
264
+ raise RuntimeError(request.status_code, f"Can't delete a profile with rules assigned")
265
+
266
+ if request.status_code == requests.codes.no_content:
267
+ return
268
+ else:
269
+ logger.debug(request.content.decode("utf-8"))
270
+ raise RuntimeError(request.status_code, f"metadata_enrichment_delete_profile failed")
271
+
272
+ def metadata_enrichment_profiles(self) -> dict:
273
+ """
274
+ Returns the list of all metadata enrichment profiles.
275
+ Profiles define a set of behaviours that will be applied when the profile is selected by a rule.
276
+ A profile has no effect if it is not used by a rule. Includes settings for PII identification.
277
+ PII detection tools may be run against the full text extracted from content.
278
+ """
279
+
280
+ headers = {
281
+ HEADER_TOKEN: self.token,
282
+ "Accept": "application/json",
283
+ "Content-Type": "application/json;charset=UTF-8",
284
+ }
285
+
286
+ endpoint: str = "/metadata-enrichment/config/profiles"
287
+
288
+ request = self.session.get(
289
+ f"{self.protocol}://{self.server}/{self.base_url}{endpoint}", headers=headers)
290
+
291
+ if request.status_code == requests.codes.ok:
292
+ return json.loads(request.content.decode("utf-8"))
293
+ else:
294
+ logger.debug(request.content.decode("utf-8"))
295
+ raise RuntimeError(request.status_code, f"metadata_enrichment_profiles failed")