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.
- pyPreservica/__init__.py +26 -8
- pyPreservica/adminAPI.py +877 -0
- pyPreservica/authorityAPI.py +229 -0
- pyPreservica/common.py +553 -94
- pyPreservica/contentAPI.py +331 -65
- pyPreservica/entityAPI.py +1805 -446
- pyPreservica/mdformsAPI.py +572 -0
- pyPreservica/monitorAPI.py +153 -0
- pyPreservica/opex.py +98 -0
- pyPreservica/parAPI.py +226 -0
- pyPreservica/retentionAPI.py +155 -44
- pyPreservica/settingsAPI.py +295 -0
- pyPreservica/uploadAPI.py +1120 -321
- pyPreservica/webHooksAPI.py +211 -0
- pyPreservica/workflowAPI.py +99 -47
- {pyPreservica-0.9.9.dist-info → pypreservica-3.3.4.dist-info}/METADATA +93 -66
- pypreservica-3.3.4.dist-info/RECORD +20 -0
- {pyPreservica-0.9.9.dist-info → pypreservica-3.3.4.dist-info}/WHEEL +5 -5
- pyPreservica-0.9.9.dist-info/RECORD +0 -12
- {pyPreservica-0.9.9.dist-info → pypreservica-3.3.4.dist-info/licenses}/LICENSE.txt +0 -0
- {pyPreservica-0.9.9.dist-info → pypreservica-3.3.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""
|
|
2
|
+
pyPreservica MonitorAPI module definition
|
|
3
|
+
|
|
4
|
+
A client library for the Preservica Repository Monitor API
|
|
5
|
+
https://us.preservica.com/api/processmonitor/documentation.html
|
|
6
|
+
|
|
7
|
+
author: James Carr
|
|
8
|
+
licence: Apache License 2.0
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from typing import Generator
|
|
13
|
+
|
|
14
|
+
from pyPreservica.common import *
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MonitorCategory(Enum):
|
|
18
|
+
INGEST = 'Ingest'
|
|
19
|
+
EXPORT = 'Export'
|
|
20
|
+
DATA_MANAGEMENT = 'DataManagement'
|
|
21
|
+
AUTOMATED = 'Automated'
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class MonitorStatus(Enum):
|
|
25
|
+
PENDING = 'Pending'
|
|
26
|
+
RUNNING = 'Running'
|
|
27
|
+
SUCCEEDED = 'Succeeded'
|
|
28
|
+
FAILED = 'Failed'
|
|
29
|
+
SUSPENDED = 'Suspended'
|
|
30
|
+
RECOVERABLE = 'Recoverable'
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class MessageStatus(Enum):
|
|
34
|
+
INFO = 'Info'
|
|
35
|
+
WARNING = 'Warning'
|
|
36
|
+
ERROR = 'Error'
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class MonitorAPI(AuthenticatedAPI):
|
|
40
|
+
"""
|
|
41
|
+
A class for the Preservica Repository Process Monitor API
|
|
42
|
+
|
|
43
|
+
https://us.preservica.com/api/processmonitor/documentation.html
|
|
44
|
+
|
|
45
|
+
API for retrieving and updating monitoring information about processes.
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def _messages_page_(self, monitor_id, maximum: int = 50, next_page: str = None, status: MessageStatus = None) -> PagedSet:
|
|
50
|
+
headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
|
|
51
|
+
|
|
52
|
+
if next_page is None:
|
|
53
|
+
params = {'monitor': monitor_id, 'start': int(0), 'max': maximum}
|
|
54
|
+
if status:
|
|
55
|
+
params['status'] = status.value
|
|
56
|
+
request = self.session.get(f'{self.protocol}://{self.server}/api/processmonitor/messages', headers=headers,
|
|
57
|
+
params=params)
|
|
58
|
+
else:
|
|
59
|
+
params = {'monitor': monitor_id}
|
|
60
|
+
if status:
|
|
61
|
+
params['status'] = status.value
|
|
62
|
+
request = self.session.get(next_page, headers=headers, params=params)
|
|
63
|
+
if request.status_code == requests.codes.ok:
|
|
64
|
+
response = json.loads(str(request.content.decode('utf-8')))
|
|
65
|
+
value = response['value']
|
|
66
|
+
if 'next' in value['paging']:
|
|
67
|
+
url = value['paging']['next']
|
|
68
|
+
else:
|
|
69
|
+
url = None
|
|
70
|
+
total_hits = int(value['paging']['totalResults'])
|
|
71
|
+
has_more = False
|
|
72
|
+
if url:
|
|
73
|
+
has_more = True
|
|
74
|
+
messages = value['messages']
|
|
75
|
+
for m in messages:
|
|
76
|
+
m['MonitorId'] = m.pop('mappedMonitorId')
|
|
77
|
+
m['MessageId'] = m.pop('mappedId')
|
|
78
|
+
return PagedSet(messages, has_more, int(total_hits), url)
|
|
79
|
+
elif request.status_code == requests.codes.unauthorized:
|
|
80
|
+
self.token = self.__token__()
|
|
81
|
+
return self._messages_page_(monitor_id, maximum, next_page, status)
|
|
82
|
+
else:
|
|
83
|
+
logger.error(request.content.decode('utf-8'))
|
|
84
|
+
raise RuntimeError(request.status_code, "messages failed")
|
|
85
|
+
|
|
86
|
+
def messages(self, monitor_id, status: MessageStatus = None) -> Generator:
|
|
87
|
+
"""
|
|
88
|
+
List of messages for a process
|
|
89
|
+
|
|
90
|
+
:param monitor_id: The Process ID
|
|
91
|
+
:type monitor_id: str
|
|
92
|
+
:param status: The message status, info, warning, error etc.
|
|
93
|
+
:type status: MessageStatus
|
|
94
|
+
:return: Generator for each message, each message is a dict object
|
|
95
|
+
"""
|
|
96
|
+
page_size = 25
|
|
97
|
+
paged_set = self._messages_page_(monitor_id, maximum=page_size, next_page=None, status=status)
|
|
98
|
+
for e in paged_set.results:
|
|
99
|
+
yield e
|
|
100
|
+
while paged_set.has_more:
|
|
101
|
+
paged_set = self._messages_page_(monitor_id, maximum=page_size, next_page=paged_set.next_page, status=status)
|
|
102
|
+
for e in paged_set.results:
|
|
103
|
+
yield e
|
|
104
|
+
|
|
105
|
+
def timeseries(self, monitor_id):
|
|
106
|
+
"""
|
|
107
|
+
Get the historical record of progress for a single monitor
|
|
108
|
+
|
|
109
|
+
:param monitor_id: The Process ID
|
|
110
|
+
:type monitor_id: str
|
|
111
|
+
:return: List of timeseries information
|
|
112
|
+
"""
|
|
113
|
+
headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
|
|
114
|
+
request = self.session.get(f'{self.protocol}://{self.server}/api/processmonitor/monitors/{monitor_id}/timeseries',
|
|
115
|
+
headers=headers)
|
|
116
|
+
if request.status_code == requests.codes.ok:
|
|
117
|
+
response = json.loads(str(request.content.decode('utf-8')))
|
|
118
|
+
return response['value']['timeseries']
|
|
119
|
+
elif request.status_code == requests.codes.unauthorized:
|
|
120
|
+
self.token = self.__token__()
|
|
121
|
+
return self.timeseries(monitor_id)
|
|
122
|
+
else:
|
|
123
|
+
logger.error(request.content.decode('utf-8'))
|
|
124
|
+
raise RuntimeError(request.status_code, "timeseries failed")
|
|
125
|
+
|
|
126
|
+
def monitors(self, status: MonitorStatus = None, category: MonitorCategory = None) -> Generator:
|
|
127
|
+
"""
|
|
128
|
+
Get a filtered list of non-abandoned process monitors
|
|
129
|
+
|
|
130
|
+
:param status: process status values (Pending, Running, Succeeded, Failed, Suspended, Recoverable)
|
|
131
|
+
:type status: MonitorStatus
|
|
132
|
+
:param category: process categories (Ingest, Export, DataManagement, Automated)
|
|
133
|
+
:type category: MonitorCategory
|
|
134
|
+
:return: Generator for each monitor
|
|
135
|
+
"""
|
|
136
|
+
headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json;charset=UTF-8'}
|
|
137
|
+
params = {}
|
|
138
|
+
if status:
|
|
139
|
+
params['status'] = status.value
|
|
140
|
+
if category:
|
|
141
|
+
params['category'] = category.value
|
|
142
|
+
request = self.session.get(f'{self.protocol}://{self.server}/api/processmonitor/monitors', headers=headers, params=params)
|
|
143
|
+
if request.status_code == requests.codes.ok:
|
|
144
|
+
monitors = json.loads(str(request.content.decode('utf-8')))
|
|
145
|
+
for monitor in monitors['value']['monitors']:
|
|
146
|
+
monitor['MonitorId'] = monitor.pop('mappedId')
|
|
147
|
+
yield monitor
|
|
148
|
+
elif request.status_code == requests.codes.unauthorized:
|
|
149
|
+
self.token = self.__token__()
|
|
150
|
+
yield from self.monitors(status, category)
|
|
151
|
+
else:
|
|
152
|
+
logger.error(request.content.decode('utf-8'))
|
|
153
|
+
raise RuntimeError(request.status_code, "monitors failed")
|
pyPreservica/opex.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""
|
|
2
|
+
pyPreservica OpexAPI module definition
|
|
3
|
+
|
|
4
|
+
A Utility class to work with Opex Objects
|
|
5
|
+
|
|
6
|
+
author: James Carr
|
|
7
|
+
licence: Apache License 2.0
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
import xml.etree.ElementTree
|
|
11
|
+
from typing import Generator
|
|
12
|
+
from zipfile import ZipFile
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class OpexAPI(object):
|
|
16
|
+
class OPEXMetadata(object):
|
|
17
|
+
def __init__(self, source: str, title: str, description: str, SecurityDescriptor: str):
|
|
18
|
+
self.pax_file = None
|
|
19
|
+
self.source = source
|
|
20
|
+
self.title = title
|
|
21
|
+
self.description = description
|
|
22
|
+
self.SecurityDescriptor = SecurityDescriptor
|
|
23
|
+
|
|
24
|
+
def __str__(self):
|
|
25
|
+
return self.__repr__()
|
|
26
|
+
|
|
27
|
+
def __repr__(self):
|
|
28
|
+
return {"SourceID": self.source, "Title": self.title, "Description": self.description,
|
|
29
|
+
"SecurityDescriptor": self.SecurityDescriptor}.__str__()
|
|
30
|
+
|
|
31
|
+
def __init__(self, opex_file: str):
|
|
32
|
+
self.opex = opex_file
|
|
33
|
+
|
|
34
|
+
def bitstream_bytes(self, opex_metadata: OPEXMetadata, bitstream_name: dict):
|
|
35
|
+
with ZipFile(self.opex) as zip_opex_file:
|
|
36
|
+
for o in zip_opex_file.namelist():
|
|
37
|
+
if o == opex_metadata.pax_file:
|
|
38
|
+
with zip_opex_file.open(opex_metadata.pax_file) as zip_pax_file:
|
|
39
|
+
with ZipFile(zip_pax_file) as pax_file:
|
|
40
|
+
name = "/".join(bitstream_name.values())
|
|
41
|
+
with pax_file.open(name, mode="r") as myfile:
|
|
42
|
+
return myfile.read()
|
|
43
|
+
|
|
44
|
+
def xip_metadata(self, opex_metadata: OPEXMetadata):
|
|
45
|
+
with ZipFile(self.opex) as zip_opex_file:
|
|
46
|
+
for o in zip_opex_file.namelist():
|
|
47
|
+
if o == opex_metadata.pax_file:
|
|
48
|
+
with zip_opex_file.open(opex_metadata.pax_file) as zip_pax_file:
|
|
49
|
+
with ZipFile(zip_pax_file) as pax_file:
|
|
50
|
+
for name in pax_file.namelist():
|
|
51
|
+
if name.endswith(".xip") is True:
|
|
52
|
+
return name
|
|
53
|
+
|
|
54
|
+
def xip_metadata(self, opex_metadata: OPEXMetadata):
|
|
55
|
+
with ZipFile(self.opex) as zip_opex_file:
|
|
56
|
+
for o in zip_opex_file.namelist():
|
|
57
|
+
if o == opex_metadata.pax_file:
|
|
58
|
+
with zip_opex_file.open(opex_metadata.pax_file) as zip_pax_file:
|
|
59
|
+
with ZipFile(zip_pax_file) as pax_file:
|
|
60
|
+
for name in pax_file.namelist():
|
|
61
|
+
if (name.endswith("/") is False) and (name.endswith(".xip") is True):
|
|
62
|
+
with pax_file.open(name, mode="r") as myfile:
|
|
63
|
+
return myfile.read()
|
|
64
|
+
|
|
65
|
+
def bitstream(self, opex_metadata: OPEXMetadata) -> Generator:
|
|
66
|
+
with ZipFile(self.opex) as zip_opex_file:
|
|
67
|
+
for o in zip_opex_file.namelist():
|
|
68
|
+
if o == opex_metadata.pax_file:
|
|
69
|
+
with zip_opex_file.open(opex_metadata.pax_file) as zip_pax_file:
|
|
70
|
+
with ZipFile(zip_pax_file) as pax_file:
|
|
71
|
+
for name in pax_file.namelist():
|
|
72
|
+
if (name.endswith("/") is False) and (name.endswith(".xip") is False):
|
|
73
|
+
parts = name.split("/")
|
|
74
|
+
assert len(parts) == 4
|
|
75
|
+
yield {"Representation": parts[0], "Content Object": parts[1],
|
|
76
|
+
"Generation": parts[2], "Bitstream": parts[3]}
|
|
77
|
+
|
|
78
|
+
def properties(self) -> Generator:
|
|
79
|
+
with ZipFile(self.opex) as myzip:
|
|
80
|
+
for o in myzip.namelist():
|
|
81
|
+
if o.endswith(".pax.zip.opex"):
|
|
82
|
+
pax_file = o.replace(".pax.zip.opex", ".pax.zip")
|
|
83
|
+
with myzip.open(o) as myfile:
|
|
84
|
+
xml_response = str(myfile.read().decode('utf-8'))
|
|
85
|
+
entity_response = xml.etree.ElementTree.fromstring(xml_response)
|
|
86
|
+
source_id = entity_response.find(f'.//{{*}}SourceID')
|
|
87
|
+
title_node = entity_response.find(f'.//{{*}}Title')
|
|
88
|
+
description_node = entity_response.find(f'.//{{*}}Description')
|
|
89
|
+
tag_node = entity_response.find(f'.//{{*}}SecurityDescriptor')
|
|
90
|
+
|
|
91
|
+
title = title_node.text if hasattr(title_node, 'text') else None
|
|
92
|
+
description = description_node.text if hasattr(description_node, 'text') else None
|
|
93
|
+
tag = tag_node.text if hasattr(tag_node, 'text') else None
|
|
94
|
+
|
|
95
|
+
opex_metadata = self.OPEXMetadata(source_id.text, title, description, tag)
|
|
96
|
+
opex_metadata.pax_file = pax_file
|
|
97
|
+
|
|
98
|
+
yield opex_metadata
|
pyPreservica/parAPI.py
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"""
|
|
2
|
+
pyPreservica Preservation Action Registry module definition
|
|
3
|
+
|
|
4
|
+
A client library for the Preservica PAR API
|
|
5
|
+
https://us.preservica.com/Registry/par/documentation.html
|
|
6
|
+
|
|
7
|
+
author: James Carr
|
|
8
|
+
licence: Apache License 2.0
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
from typing import AnyStr
|
|
12
|
+
|
|
13
|
+
from requests.auth import HTTPBasicAuth
|
|
14
|
+
|
|
15
|
+
from pyPreservica.common import *
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def __get_contents__(document) -> AnyStr:
|
|
19
|
+
try:
|
|
20
|
+
with open(document, "rb") as f:
|
|
21
|
+
return f.read()
|
|
22
|
+
except (OSError, TypeError):
|
|
23
|
+
return json.dumps(json.loads(document))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class PreservationActionRegistry(AuthenticatedAPI):
|
|
27
|
+
|
|
28
|
+
def format_family(self, guid: str) -> str:
|
|
29
|
+
return self.__guid__(guid, "format-families")
|
|
30
|
+
|
|
31
|
+
def format_families(self) -> str:
|
|
32
|
+
return self.__all_("format-families")
|
|
33
|
+
|
|
34
|
+
def add_format_family(self, document) -> str:
|
|
35
|
+
return self.__add__("format-families", document)
|
|
36
|
+
|
|
37
|
+
def update_format_family(self, guid: str, document) -> str:
|
|
38
|
+
return self.__update__(guid, "format-families", document)
|
|
39
|
+
|
|
40
|
+
def delete_format_family(self, guid) -> str:
|
|
41
|
+
return self.__delete__(guid, "format-families")
|
|
42
|
+
|
|
43
|
+
def preservation_action_type(self, guid: str) -> str:
|
|
44
|
+
return self.__guid__(guid, "preservation-action-types")
|
|
45
|
+
|
|
46
|
+
def preservation_action_types(self) -> str:
|
|
47
|
+
return self.__all_("preservation-action-types")
|
|
48
|
+
|
|
49
|
+
def add_preservation_action_type(self, document) -> str:
|
|
50
|
+
return self.__add__("preservation-action-types", document)
|
|
51
|
+
|
|
52
|
+
def update_preservation_action_type(self, guid: str, document) -> str:
|
|
53
|
+
return self.__update__(guid, "preservation-action-types", document)
|
|
54
|
+
|
|
55
|
+
def delete_preservation_action_type(self, guid) -> str:
|
|
56
|
+
return self.__delete__(guid, "preservation-action-types")
|
|
57
|
+
|
|
58
|
+
def property(self, guid: str) -> str:
|
|
59
|
+
return self.__guid__(guid, "properties")
|
|
60
|
+
|
|
61
|
+
def properties(self) -> str:
|
|
62
|
+
return self.__all_("properties")
|
|
63
|
+
|
|
64
|
+
def add_property(self, document) -> str:
|
|
65
|
+
return self.__add__("properties", document)
|
|
66
|
+
|
|
67
|
+
def update_property(self, guid: str, document) -> str:
|
|
68
|
+
return self.__update__(guid, "properties", document)
|
|
69
|
+
|
|
70
|
+
def delete_property(self, guid) -> str:
|
|
71
|
+
return self.__delete__(guid, "properties")
|
|
72
|
+
|
|
73
|
+
def representation_format(self, guid: str) -> str:
|
|
74
|
+
return self.__guid__(guid, "representation-formats")
|
|
75
|
+
|
|
76
|
+
def representation_formats(self) -> str:
|
|
77
|
+
return self.__all_("representation-formats")
|
|
78
|
+
|
|
79
|
+
def add_representation_format(self, document) -> str:
|
|
80
|
+
return self.__add__("representation-formats", document)
|
|
81
|
+
|
|
82
|
+
def update_representation_format(self, guid: str, document) -> str:
|
|
83
|
+
return self.__update__(guid, "representation-formats", document)
|
|
84
|
+
|
|
85
|
+
def delete_representation_format(self, guid) -> str:
|
|
86
|
+
return self.__delete__(guid, "representation-formats")
|
|
87
|
+
|
|
88
|
+
def file_format(self, puid: str) -> str:
|
|
89
|
+
return self.__guid__(puid, "file-formats")
|
|
90
|
+
|
|
91
|
+
def file_formats(self) -> str:
|
|
92
|
+
return self.__all_("file-formats")
|
|
93
|
+
|
|
94
|
+
def add_file_format(self, document) -> str:
|
|
95
|
+
return self.__add__("file-formats", document)
|
|
96
|
+
|
|
97
|
+
def update_file_format(self, guid: str, document) -> str:
|
|
98
|
+
return self.__update__(guid, "file-formats", document)
|
|
99
|
+
|
|
100
|
+
def delete_file_format(self, guid) -> str:
|
|
101
|
+
return self.__delete__(guid, "file-formats")
|
|
102
|
+
|
|
103
|
+
def tool(self, guid: str) -> str:
|
|
104
|
+
return self.__guid__(guid, "tools")
|
|
105
|
+
|
|
106
|
+
def tools(self) -> str:
|
|
107
|
+
return self.__all_("tools")
|
|
108
|
+
|
|
109
|
+
def add_tool(self, document) -> str:
|
|
110
|
+
return self.__add__("tools", document)
|
|
111
|
+
|
|
112
|
+
def update_tool(self, guid: str, document) -> str:
|
|
113
|
+
return self.__update__(guid, "tools", document)
|
|
114
|
+
|
|
115
|
+
def delete_tool(self, guid) -> str:
|
|
116
|
+
return self.__delete__(guid, "tools")
|
|
117
|
+
|
|
118
|
+
def preservation_action(self, guid: str) -> str:
|
|
119
|
+
return self.__guid__(guid, "preservation-actions")
|
|
120
|
+
|
|
121
|
+
def preservation_actions(self) -> str:
|
|
122
|
+
return self.__all_("preservation-actions")
|
|
123
|
+
|
|
124
|
+
def add_preservation_action(self, document) -> str:
|
|
125
|
+
return self.__add__("preservation-actions", document)
|
|
126
|
+
|
|
127
|
+
def update_preservation_action(self, guid: str, document) -> str:
|
|
128
|
+
return self.__update__(guid, "preservation-actions", document)
|
|
129
|
+
|
|
130
|
+
def delete_preservation_action(self, guid) -> str:
|
|
131
|
+
return self.__delete__(guid, "preservation-actions")
|
|
132
|
+
|
|
133
|
+
def business_rule(self, guid: str) -> str:
|
|
134
|
+
return self.__guid__(guid, "business-rules")
|
|
135
|
+
|
|
136
|
+
def business_rules(self, action_type: str = None) -> str:
|
|
137
|
+
return self.__all_("business-rules", action_type)
|
|
138
|
+
|
|
139
|
+
def add_business_rule(self, document) -> str:
|
|
140
|
+
return self.__add__("business-rules", document)
|
|
141
|
+
|
|
142
|
+
def update_business_rule(self, guid: str, document) -> str:
|
|
143
|
+
return self.__update__(guid, "business-rules", document)
|
|
144
|
+
|
|
145
|
+
def delete_business_rule(self, guid) -> str:
|
|
146
|
+
return self.__delete__(guid, "business-rules")
|
|
147
|
+
|
|
148
|
+
def rule_set(self, guid: str) -> str:
|
|
149
|
+
return self.__guid__(guid, "rulesets")
|
|
150
|
+
|
|
151
|
+
def rule_sets(self) -> str:
|
|
152
|
+
return self.__all_("rulesets")
|
|
153
|
+
|
|
154
|
+
def add_rule_set(self, document) -> str:
|
|
155
|
+
return self.__add__("rulesets", document)
|
|
156
|
+
|
|
157
|
+
def update_rule_set(self, guid: str, document) -> str:
|
|
158
|
+
return self.__update__(guid, "rulesets", document)
|
|
159
|
+
|
|
160
|
+
def delete_rule_set(self, guid) -> str:
|
|
161
|
+
return self.__delete__(guid, "rulesets")
|
|
162
|
+
|
|
163
|
+
def __guid__(self, guid: str, endpoint: str) -> str:
|
|
164
|
+
request = self.session.get(f'{self.protocol}://{self.server}/Registry/par/{endpoint}/{guid}')
|
|
165
|
+
if request.status_code == requests.codes.ok:
|
|
166
|
+
return request.content.decode('utf-8')
|
|
167
|
+
else:
|
|
168
|
+
logger.debug(request.content.decode('utf-8'))
|
|
169
|
+
raise RuntimeError(request.status_code, f"{endpoint} failed")
|
|
170
|
+
|
|
171
|
+
def __all_(self, endpoint: str, action_type: str = None) -> str:
|
|
172
|
+
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
|
|
173
|
+
if action_type is not None:
|
|
174
|
+
headers['preservation-action-type'] = action_type
|
|
175
|
+
request = self.session.get(f'{self.protocol}://{self.server}/Registry/par/{endpoint}')
|
|
176
|
+
if request.status_code == requests.codes.ok:
|
|
177
|
+
return request.content.decode('utf-8')
|
|
178
|
+
else:
|
|
179
|
+
logger.debug(request.content.decode('utf-8'))
|
|
180
|
+
raise RuntimeError(request.status_code, f"{endpoint} failed")
|
|
181
|
+
|
|
182
|
+
def __add__(self, endpoint: str, document) -> str:
|
|
183
|
+
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
|
|
184
|
+
if self.username is None or self.password is None:
|
|
185
|
+
logger.error(f"add {endpoint} is an authenticated call, please provide credentials")
|
|
186
|
+
raise RuntimeError(f"add {endpoint} is an authenticated call, please provide credentials")
|
|
187
|
+
|
|
188
|
+
contents = __get_contents__(document)
|
|
189
|
+
request = self.session.post(f'{self.protocol}://{self.server}/Registry/par/{endpoint}',
|
|
190
|
+
auth=HTTPBasicAuth(self.username, self.password), headers=headers, data=contents)
|
|
191
|
+
|
|
192
|
+
if request.status_code == requests.codes.created:
|
|
193
|
+
return request.content.decode('utf-8')
|
|
194
|
+
else:
|
|
195
|
+
logger.debug(request.content.decode('utf-8'))
|
|
196
|
+
raise RuntimeError(request.status_code, f"add {endpoint} failed")
|
|
197
|
+
|
|
198
|
+
def __update__(self, guid: str, endpoint: str, document) -> str:
|
|
199
|
+
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
|
|
200
|
+
if self.username is None or self.password is None:
|
|
201
|
+
logger.error(f"update {endpoint} is an authenticated call, please provide credentials")
|
|
202
|
+
raise RuntimeError(f"update {endpoint} is an authenticated call, please provide credentials")
|
|
203
|
+
|
|
204
|
+
contents = __get_contents__(document)
|
|
205
|
+
|
|
206
|
+
request = self.session.put(f'{self.protocol}://{self.server}/Registry/par/{endpoint}/{guid}',
|
|
207
|
+
auth=HTTPBasicAuth(self.username, self.password), headers=headers, data=contents)
|
|
208
|
+
|
|
209
|
+
if request.status_code == requests.codes.created:
|
|
210
|
+
return request.content.decode('utf-8')
|
|
211
|
+
else:
|
|
212
|
+
logger.debug(request.content.decode('utf-8'))
|
|
213
|
+
raise RuntimeError(request.status_code, f"update {endpoint} failed")
|
|
214
|
+
|
|
215
|
+
def __delete__(self, guid: str, endpoint: str) -> str:
|
|
216
|
+
if self.username is None or self.password is None:
|
|
217
|
+
logger.error(f"delete {endpoint} is an authenticated call, please provide credentials")
|
|
218
|
+
raise RuntimeError(f"delete {endpoint} is an authenticated call, please provide credentials")
|
|
219
|
+
|
|
220
|
+
request = self.session.delete(f'{self.protocol}://{self.server}/Registry/par/{endpoint}/{guid}',
|
|
221
|
+
auth=HTTPBasicAuth(self.username, self.password))
|
|
222
|
+
if request.status_code == requests.codes.no_content:
|
|
223
|
+
return request.content.decode('utf-8')
|
|
224
|
+
else:
|
|
225
|
+
logger.debug(request.content.decode('utf-8'))
|
|
226
|
+
raise RuntimeError(request.status_code, f"delete {endpoint} failed")
|