pyPreservica 2.7.4__tar.gz → 2.8.1__tar.gz

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 (49) hide show
  1. {pypreservica-2.7.4 → pypreservica-2.8.1}/PKG-INFO +1 -1
  2. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/__init__.py +2 -2
  3. pypreservica-2.8.1/pyPreservica/mdformsAPI.py +362 -0
  4. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica.egg-info/PKG-INFO +1 -1
  5. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica.egg-info/SOURCES.txt +1 -0
  6. {pypreservica-2.7.4 → pypreservica-2.8.1}/setup.py +1 -1
  7. pypreservica-2.8.1/tests/test_groups.py +91 -0
  8. pypreservica-2.7.4/pyPreservica/mdformsAPI.py +0 -105
  9. {pypreservica-2.7.4 → pypreservica-2.8.1}/LICENSE.txt +0 -0
  10. {pypreservica-2.7.4 → pypreservica-2.8.1}/README.md +0 -0
  11. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/adminAPI.py +0 -0
  12. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/authorityAPI.py +0 -0
  13. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/common.py +0 -0
  14. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/contentAPI.py +0 -0
  15. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/entityAPI.py +0 -0
  16. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/monitorAPI.py +0 -0
  17. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/opex.py +0 -0
  18. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/parAPI.py +0 -0
  19. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/retentionAPI.py +0 -0
  20. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/uploadAPI.py +0 -0
  21. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/webHooksAPI.py +0 -0
  22. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica/workflowAPI.py +0 -0
  23. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica.egg-info/dependency_links.txt +0 -0
  24. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica.egg-info/requires.txt +0 -0
  25. {pypreservica-2.7.4 → pypreservica-2.8.1}/pyPreservica.egg-info/top_level.txt +0 -0
  26. {pypreservica-2.7.4 → pypreservica-2.8.1}/setup.cfg +0 -0
  27. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_authority_records.py +0 -0
  28. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_bitstream.py +0 -0
  29. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_children.py +0 -0
  30. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_content_api.py +0 -0
  31. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_crawl_fs.py +0 -0
  32. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_delete.py +0 -0
  33. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_download.py +0 -0
  34. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_entity.py +0 -0
  35. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_export_opex.py +0 -0
  36. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_identifier.py +0 -0
  37. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_ingest.py +0 -0
  38. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_integrity_check.py +0 -0
  39. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_metadata.py +0 -0
  40. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_par.py +0 -0
  41. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_replace.py +0 -0
  42. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_retention.py +0 -0
  43. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_schema.py +0 -0
  44. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_security.py +0 -0
  45. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_thumbnail.py +0 -0
  46. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_upload.py +0 -0
  47. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_users.py +0 -0
  48. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_workflow.py +0 -0
  49. {pypreservica-2.7.4 → pypreservica-2.8.1}/tests/test_xml_metadata.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyPreservica
3
- Version: 2.7.4
3
+ Version: 2.8.1
4
4
  Summary: Python library for the Preservica API
5
5
  Home-page: https://pypreservica.readthedocs.io/
6
6
  Author: James Carr
@@ -18,11 +18,11 @@ from .adminAPI import AdminAPI
18
18
  from .monitorAPI import MonitorAPI, MonitorCategory, MonitorStatus, MessageStatus
19
19
  from .webHooksAPI import WebHooksAPI, TriggerType, WebHookHandler
20
20
  from .authorityAPI import AuthorityAPI, Table
21
- from .mdformsAPI import MDFormsAPI
21
+ from .mdformsAPI import MetadataGroupsAPI, GroupFieldType, GroupField, Group
22
22
 
23
23
  __author__ = "James Carr (drjamescarr@gmail.com)"
24
24
 
25
25
  # Version of the pyPreservica package
26
- __version__ = "2.7.4"
26
+ __version__ = "2.8.1"
27
27
 
28
28
  __license__ = "Apache License Version 2.0"
@@ -0,0 +1,362 @@
1
+ """
2
+ pyPreservica MDFormsAPI module definition
3
+
4
+ A client library for the Preservica Repository web services Metadata API
5
+ https://demo.preservica.com/api/metadata/documentation.html
6
+
7
+ author: James Carr
8
+ licence: Apache License 2.0
9
+
10
+ """
11
+ import xml.etree.ElementTree
12
+ from enum import StrEnum
13
+ from typing import Callable, List, Union, Generator
14
+
15
+ from pyPreservica.common import *
16
+
17
+
18
+ class GroupFieldType(StrEnum):
19
+ STRING = "STRING"
20
+ LONG_STRING = "LONGSTRING"
21
+ DATE = "DATE"
22
+ NUMBER = "NUMBER"
23
+
24
+
25
+ class GroupField:
26
+ field_id: str
27
+ name: str
28
+ field_type: GroupFieldType
29
+ maxLength: int
30
+ default: str
31
+ visible: bool
32
+ editable: bool
33
+ minOccurs: int
34
+ maxOccurs: int
35
+ values: List[str]
36
+ indexed: bool
37
+
38
+ def __init__(self, field_id: str, name: str, field_type: GroupFieldType = GroupFieldType.STRING,
39
+ maxLength: int = -1, default: str = "", visible: bool = True, editable: bool = True,
40
+ minOccurs: int = 0, maxOccurs: int = 1, indexed: bool = True, values: List = None):
41
+ self.field_id = field_id
42
+ self.name = name
43
+ self.field_type = field_type
44
+ self.maxLength = maxLength
45
+ self.default = default
46
+ self.visible = visible
47
+ self.editable = editable
48
+ self.minOccurs = minOccurs
49
+ self.maxOccurs = maxOccurs
50
+ self.values = values
51
+ self.indexed = indexed
52
+
53
+ def __str__(self):
54
+ return (f"Field ID: {self.field_id}\n" + f"Field Name: {self.name}\n" + f"Field Type: {self.field_type}\n" +
55
+ f"Field Visible: {self.visible}\n" + f"Field Editable: {self.editable}\n")
56
+
57
+
58
+ class Group:
59
+ group_id: str
60
+ name: str
61
+ description: str
62
+ schemaUri: str
63
+ fields: List[GroupField] = []
64
+
65
+ def __init__(self, name: str, description: str):
66
+ self.name = name
67
+ self.description = description
68
+
69
+ def __str__(self):
70
+ return (f"Group ID: {self.group_id}\n" + f"Group Name: {self.name}\n" +
71
+ f"Group Description: {self.description}\n" + f"Group Schema URI: {self.schemaUri}")
72
+
73
+
74
+ def _object_from_json_(json_doc: dict) -> Group:
75
+ """
76
+ Create a JSON dict object from a Group object
77
+ """
78
+
79
+ group: Group = Group(name=json_doc['name'], description=json_doc['description'])
80
+ group.fields = []
81
+ if 'id' in json_doc:
82
+ group.group_id = json_doc['id']
83
+ if 'schemaUri' in json_doc:
84
+ group.schemaUri = json_doc['schemaUri']
85
+
86
+ if 'fields' in json_doc:
87
+ for field in json_doc['fields']:
88
+ gf: GroupField = GroupField(field['id'], field['name'], GroupFieldType(str(field['type'])))
89
+ if 'minOccurs' in field:
90
+ gf.minOccurs = int(field['minOccurs'])
91
+ if 'maxOccurs' in field:
92
+ gf.maxOccurs = int(field['maxOccurs'])
93
+ if 'visible' in field:
94
+ gf.visible = bool(field['visible'])
95
+ if 'editable' in field:
96
+ gf.editable = bool(field['editable'])
97
+ if 'values' in field:
98
+ for v in field['values']:
99
+ gf.values.append(str(v))
100
+ if 'defaultValue' in field:
101
+ gf.default = str(field['defaultValue'])
102
+ if 'indexed' in field:
103
+ gf.indexed = bool(field['indexed'])
104
+
105
+ group.fields.append(gf)
106
+
107
+ return group
108
+
109
+
110
+ def _json_from_object_(group: Group) -> dict:
111
+ """
112
+ Create a JSON dict object from a Group object
113
+ """
114
+
115
+ fields = []
116
+ for field in group.fields:
117
+ f = {"id": field.field_id, "name": field.name, "type": str(field.field_type)}
118
+ f["minOccurs"] = str(field.minOccurs)
119
+ f["maxOccurs"] = str(field.maxOccurs)
120
+ f["visible"] = str(field.visible)
121
+ f["editable"] = str(field.editable)
122
+ if (field.values is not None) and (len(field.values) > 0):
123
+ f["values"] = [item for item in field.values]
124
+ f["defaultValue"] = str(field.default)
125
+ f["indexed"] = str(field.indexed)
126
+ fields.append(f)
127
+
128
+ json_doc = {"name": group.name, "description": group.description, "fields": fields}
129
+
130
+ return json_doc
131
+
132
+
133
+ class MetadataGroupsAPI(AuthenticatedAPI):
134
+ def __init__(self, username: str = None, password: str = None, tenant: str = None, server: str = None,
135
+ use_shared_secret: bool = False, two_fa_secret_key: str = None,
136
+ protocol: str = "https", request_hook: Callable = None):
137
+
138
+ super().__init__(username, password, tenant, server, use_shared_secret, two_fa_secret_key,
139
+ protocol, request_hook)
140
+
141
+ xml.etree.ElementTree.register_namespace("oai_dc", "http://www.openarchives.org/OAI/2.0/oai_dc/")
142
+ xml.etree.ElementTree.register_namespace("ead", "urn:isbn:1-931666-22-9")
143
+
144
+ def delete_group_namespace(self, schema: str):
145
+ """
146
+ Delete a new Metadata Group using its schema URI
147
+
148
+ :param schema: The Group namespace schema URI
149
+ :type schema: str
150
+
151
+ :return: None
152
+ :rtype: None
153
+
154
+ """
155
+ for group in self.groups():
156
+ if group.schemaUri == schema:
157
+ self.delete_group(group.group_id)
158
+
159
+ def delete_group(self, group_id: str):
160
+ """
161
+ Delete a new Metadata Group using its ID
162
+
163
+ :param group_id: Group ID
164
+ :type group_id: str
165
+
166
+ :return:
167
+ :rtype: None
168
+
169
+ """
170
+ headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
171
+ url = f'{self.protocol}://{self.server}/api/metadata/groups/{group_id}'
172
+ with self.session.delete(url, headers=headers) as request:
173
+ if request.status_code == requests.codes.unauthorized:
174
+ self.token = self.__token__()
175
+ return self.delete_group(group_id)
176
+ elif request.status_code == requests.codes.no_content:
177
+ return None
178
+ else:
179
+ exception = HTTPException(None, request.status_code, request.url, "delete_group",
180
+ request.content.decode('utf-8'))
181
+ logger.error(exception)
182
+ raise exception
183
+
184
+ def add_fields(self, group_id: str, new_fields: List[GroupField]) -> dict:
185
+ """
186
+ Add new metadata fields to an existing Group
187
+
188
+ The new fields are appended to the end of the group
189
+
190
+ :param group_id: The group ID of the group to update
191
+ :type group_id: str
192
+
193
+ :param new_fields: The list of new fields to add to the group
194
+ :type new_fields: List[GroupField]
195
+
196
+ :return: The updated Metadata Group as a JSON dict
197
+ :rtype: dict
198
+
199
+
200
+ """
201
+
202
+ this_group: Group = self.group(group_id)
203
+
204
+ for field in new_fields:
205
+ this_group.fields.append(field)
206
+
207
+ doc = _json_from_object_(this_group)
208
+
209
+ headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
210
+ url = f'{self.protocol}://{self.server}/api/metadata/groups/{group_id}'
211
+ with self.session.put(url, headers=headers, json=doc) as request:
212
+ if request.status_code == requests.codes.unauthorized:
213
+ self.token = self.__token__()
214
+ return self.add_fields(group_id, new_fields)
215
+ elif request.status_code == requests.codes.created:
216
+ return json.loads(str(request.content.decode('utf-8')))
217
+ else:
218
+ exception = HTTPException(None, request.status_code, request.url, "add_fields",
219
+ request.content.decode('utf-8'))
220
+ logger.error(exception)
221
+ raise exception
222
+
223
+ def add_group(self, group_name: str, group_description: str, fields: List[GroupField]) -> dict:
224
+ """
225
+ Create a new Metadata Group GroupFields
226
+
227
+ :param group_name: The name of the new Group
228
+ :type group_name: str
229
+
230
+ :param group_description: The description of the new Group
231
+ :type group_description: str
232
+
233
+ :param fields: The list of fields
234
+ :type fields: List[GroupField]
235
+
236
+ :return: The new metadata Group as a JSON dict
237
+ :rtype: dict
238
+
239
+ """
240
+
241
+ group: Group = Group(group_name, group_description)
242
+ group.fields = fields
243
+
244
+ json_document: dict = _json_from_object_(group)
245
+ json_response: dict = self.add_group_json(json_document)
246
+ return json_response
247
+
248
+ def add_group_json(self, json_object: Union[dict, str]) -> dict:
249
+ """
250
+ Create a new Metadata Group using a JSON dictionary object or document
251
+
252
+ :param json_object: JSON dictionary or string
253
+ :type json_object: dict
254
+
255
+ :return: JSON document
256
+ :rtype: dict
257
+
258
+ """
259
+ headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
260
+ url = f'{self.protocol}://{self.server}/api/metadata/groups/'
261
+
262
+ if isinstance(json_object, dict):
263
+ with self.session.post(url, headers=headers, json=json_object) as request:
264
+ if request.status_code == requests.codes.unauthorized:
265
+ self.token = self.__token__()
266
+ return self.add_group_json(json_object)
267
+ elif request.status_code == requests.codes.created:
268
+ return json.loads(str(request.content.decode('utf-8')))
269
+ else:
270
+ exception = HTTPException(None, request.status_code, request.url, "add_group_json",
271
+ request.content.decode('utf-8'))
272
+ logger.error(exception)
273
+ raise exception
274
+
275
+ elif isinstance(json_object, str):
276
+ with self.session.post(url, headers=headers, data=json_object) as request:
277
+ if request.status_code == requests.codes.unauthorized:
278
+ self.token = self.__token__()
279
+ return self.add_group_json(json_object)
280
+ elif request.status_code == requests.codes.created:
281
+ return json.loads(str(request.content.decode('utf-8')))
282
+ else:
283
+ exception = HTTPException(None, request.status_code, request.url, "add_group_json",
284
+ request.content.decode('utf-8'))
285
+ logger.error(exception)
286
+ raise exception
287
+ else:
288
+ raise RuntimeError("Argument must be a JSON dictionary or a JSON str")
289
+
290
+ def group_json(self, group_id: str) -> dict:
291
+ """
292
+ Return a Group as a JSON object
293
+
294
+ :param group_id: The Group id
295
+ :type group_id: str
296
+
297
+ :return: JSON document
298
+ :rtype: dict
299
+
300
+ """
301
+ headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
302
+ url = f'{self.protocol}://{self.server}/api/metadata/groups/{group_id}'
303
+ with self.session.get(url, headers=headers) as request:
304
+ if request.status_code == requests.codes.unauthorized:
305
+ self.token = self.__token__()
306
+ return self.group_json(group_id)
307
+ elif request.status_code == requests.codes.ok:
308
+ return json.loads(str(request.content.decode('utf-8')))
309
+ else:
310
+ exception = HTTPException(None, request.status_code, request.url, "group_json",
311
+ request.content.decode('utf-8'))
312
+ logger.error(exception)
313
+ raise exception
314
+
315
+ def group(self, group_id: str) -> Group:
316
+ """
317
+ Return a Group object by its ID
318
+
319
+ :param group_id: The Group id
320
+ :type group_id: str
321
+
322
+ :return: The metadata Group Object
323
+ :rtype: Group
324
+
325
+ """
326
+
327
+ return _object_from_json_(self.group_json(group_id))
328
+
329
+ def groups_json(self) -> List[dict]:
330
+ """
331
+ Return all the metadata Groups in the tenancy as a list of JSON dict objects
332
+
333
+ :return: List of JSON dictionary object
334
+ :rtype: List[dict]
335
+
336
+ """
337
+
338
+ headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
339
+ url = f'{self.protocol}://{self.server}/api/metadata/groups'
340
+ with self.session.get(url, headers=headers) as request:
341
+ if request.status_code == requests.codes.unauthorized:
342
+ self.token = self.__token__()
343
+ return self.groups_json()
344
+ elif request.status_code == requests.codes.ok:
345
+ return json.loads(str(request.content.decode('utf-8')))['groups']
346
+ else:
347
+ exception = HTTPException(None, request.status_code, request.url, "groups_json",
348
+ request.content.decode('utf-8'))
349
+ logger.error(exception)
350
+ raise exception
351
+
352
+ def groups(self) -> Generator[Group, None, None]:
353
+ """
354
+ Return all the metadata Groups in the tenancy as Group Objects
355
+
356
+ :return: Generator of Group Objects
357
+ :rtype: Group
358
+
359
+ """
360
+
361
+ for group in self.groups_json():
362
+ yield _object_from_json_(group)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyPreservica
3
- Version: 2.7.4
3
+ Version: 2.8.1
4
4
  Summary: Python library for the Preservica API
5
5
  Home-page: https://pypreservica.readthedocs.io/
6
6
  Author: James Carr
@@ -29,6 +29,7 @@ tests/test_delete.py
29
29
  tests/test_download.py
30
30
  tests/test_entity.py
31
31
  tests/test_export_opex.py
32
+ tests/test_groups.py
32
33
  tests/test_identifier.py
33
34
  tests/test_ingest.py
34
35
  tests/test_integrity_check.py
@@ -21,7 +21,7 @@ if sys.argv[-1] == 'publish':
21
21
  # This call to setup() does all the work
22
22
  setup(
23
23
  name=PKG,
24
- version="2.7.4",
24
+ version="2.8.1",
25
25
  description="Python library for the Preservica API",
26
26
  long_description=README,
27
27
  long_description_content_type="text/markdown",
@@ -0,0 +1,91 @@
1
+ import pytest
2
+ from pyPreservica import *
3
+
4
+
5
+ def test_cam_get_all_groups_as_objects():
6
+ client = MetadataGroupsAPI()
7
+ assert len(list(client.groups())) > 0
8
+ for g in client.groups():
9
+ assert isinstance(g, Group)
10
+ assert g.group_id is not None
11
+ assert g.name is not None
12
+ assert g.schemaUri is not None
13
+
14
+
15
+ def test_cam_get_all_groups_as_JSON():
16
+ client = MetadataGroupsAPI()
17
+ for g in client.groups_json():
18
+ if g['name'] == "digiteek":
19
+ assert g['schemaUri'] == 'http://www.preservica.com/metadata/group/digiteek'
20
+ if g['name'] == 'McD Metadata':
21
+ assert g['schemaUri'] == 'http://www.preservica.com/metadata/group/mcd_metadata'
22
+
23
+
24
+ def test_can_get_group():
25
+ client = MetadataGroupsAPI()
26
+ for g in client.groups():
27
+ if g.name == "digiteek":
28
+ full_group: Group = client.group(g.group_id)
29
+ assert full_group.name == "digiteek"
30
+ assert full_group.description == "digiteek"
31
+ assert len(full_group.fields) == 19
32
+ break
33
+
34
+
35
+ def test_can_add_group_by_object():
36
+ client = MetadataGroupsAPI()
37
+ group1: Group = Group("my_group_name1", "my_group_description1")
38
+ group1.fields.append(GroupField(field_id="attribute_1", name="Attribute 1", field_type=GroupFieldType.STRING))
39
+ group1.fields.append(GroupField(field_id="attribute_2", name="Attribute 2", field_type=GroupFieldType.NUMBER))
40
+ group1.fields.append(GroupField(field_id="attribute_3", name="Attribute 3", field_type=GroupFieldType.DATE))
41
+
42
+ g1: dict = client.add_group(group1.name, group1.description, group1.fields)
43
+
44
+ assert g1['name'] == group1.name
45
+ assert g1['description'] == group1.description
46
+
47
+ assert len(g1['fields']) == 3
48
+
49
+ client.delete_group(g1['id'])
50
+
51
+
52
+ def test_can_add_new_fields_to_group():
53
+ client = MetadataGroupsAPI()
54
+
55
+ group2: Group = Group("my_group_name11", "my_group_description11")
56
+
57
+ group2.fields.append(GroupField(field_id="attribute_11", name="Attribute 11", field_type=GroupFieldType.STRING))
58
+ group2.fields.append(GroupField(field_id="attribute_22", name="Attribute 22", field_type=GroupFieldType.NUMBER))
59
+ group2.fields.append(GroupField(field_id="attribute_33", name="Attribute 33", field_type=GroupFieldType.DATE))
60
+
61
+ g2: dict = client.add_group(group2.name, group2.description, group2.fields)
62
+
63
+ assert g2['name'] == group2.name
64
+ assert g2['description'] == group2.description
65
+
66
+ assert len(g2['fields']) == 3
67
+
68
+ group_id = g2['id']
69
+
70
+ group3: Group = client.group(group_id)
71
+
72
+ assert g2['name'] == group3.name
73
+ assert g2['description'] == group3.description
74
+
75
+ new_fields = []
76
+
77
+ new_fields.append(GroupField(field_id="attribute_4", name="Attribute 4", field_type=GroupFieldType.LONG_STRING))
78
+ new_fields.append(GroupField(field_id="attribute_5", name="Attribute 5", field_type=GroupFieldType.NUMBER))
79
+
80
+ client.add_fields(group_id, new_fields)
81
+
82
+ group4: Group = client.group(group_id)
83
+
84
+ assert len(group4.fields) == 5
85
+
86
+ client.delete_group(group_id)
87
+
88
+
89
+ def test_can_get_group_by_URI():
90
+ client = MetadataGroupsAPI()
91
+ uri = "http://www.preservica.com/metadata/group/mcd_metadata"
@@ -1,105 +0,0 @@
1
- """
2
- pyPreservica MDFormsAPI module definition
3
-
4
- A client library for the Preservica Repository web services Metadata API
5
- https://demo.preservica.com/api/metadata/documentation.html
6
-
7
- author: James Carr
8
- licence: Apache License 2.0
9
-
10
- """
11
- import json
12
- import xml.etree.ElementTree
13
- from typing import Callable
14
-
15
- from pyPreservica.common import *
16
-
17
-
18
- class MDFormsAPI(AuthenticatedAPI):
19
- def __init__(self, username: str = None, password: str = None, tenant: str = None, server: str = None,
20
- use_shared_secret: bool = False, two_fa_secret_key: str = None,
21
- protocol: str = "https", request_hook: Callable = None):
22
-
23
- super().__init__(username, password, tenant, server, use_shared_secret, two_fa_secret_key,
24
- protocol, request_hook)
25
-
26
- xml.etree.ElementTree.register_namespace("oai_dc", "http://www.openarchives.org/OAI/2.0/oai_dc/")
27
- xml.etree.ElementTree.register_namespace("ead", "urn:isbn:1-931666-22-9")
28
-
29
- def delete_group(self, id: str):
30
- """
31
- Delete a group
32
- :param id: Group ID
33
- :return:
34
- """
35
- headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
36
- url = f'{self.protocol}://{self.server}/api/metadata/groups/{id}'
37
- with self.session.delete(url, headers=headers) as request:
38
- if request.status_code == requests.codes.unauthorized:
39
- self.token = self.__token__()
40
- return self.delete_group(id)
41
- elif request.status_code == requests.codes.no_content:
42
- return None
43
- else:
44
- exception = HTTPException(None, request.status_code, request.url, "delete_group",
45
- request.content.decode('utf-8'))
46
- logger.error(exception)
47
- raise exception
48
-
49
- def add_group(self, document):
50
- """
51
- Add a new group
52
- :return:
53
- """
54
- headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
55
- url = f'{self.protocol}://{self.server}/api/metadata/groups/'
56
- with self.session.post(url, headers=headers, json=document) as request:
57
- if request.status_code == requests.codes.unauthorized:
58
- self.token = self.__token__()
59
- return self.add_group(document)
60
- elif request.status_code == requests.codes.created:
61
- return json.loads(str(request.content.decode('utf-8')))
62
- else:
63
- exception = HTTPException(None, request.status_code, request.url, "group",
64
- request.content.decode('utf-8'))
65
- logger.error(exception)
66
- raise exception
67
-
68
- def group(self, id: str):
69
- """
70
- Fetch a metadata Group by its id
71
- :param id: The group ID
72
- :return: JSON Document
73
- """
74
- headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
75
- url = f'{self.protocol}://{self.server}/api/metadata/groups/{id}'
76
- with self.session.get(url, headers=headers) as request:
77
- if request.status_code == requests.codes.unauthorized:
78
- self.token = self.__token__()
79
- return self.group(id)
80
- elif request.status_code == requests.codes.ok:
81
- return json.loads(str(request.content.decode('utf-8')))
82
- else:
83
- exception = HTTPException(None, request.status_code, request.url, "group",
84
- request.content.decode('utf-8'))
85
- logger.error(exception)
86
- raise exception
87
-
88
- def groups(self):
89
- """
90
- Fetch all the Metadata Groups as JSON
91
- :return: JSON Document
92
- """
93
- headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
94
- url = f'{self.protocol}://{self.server}/api/metadata/groups'
95
- with self.session.get(url, headers=headers) as request:
96
- if request.status_code == requests.codes.unauthorized:
97
- self.token = self.__token__()
98
- return self.groups()
99
- elif request.status_code == requests.codes.ok:
100
- return json.loads(str(request.content.decode('utf-8')))['groups']
101
- else:
102
- exception = HTTPException(None, request.status_code, request.url, "groups",
103
- request.content.decode('utf-8'))
104
- logger.error(exception)
105
- raise exception
File without changes
File without changes
File without changes