pyPreservica 3.0.6__py3-none-any.whl → 3.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyPreservica/__init__.py +2 -1
- pyPreservica/common.py +3 -2
- pyPreservica/contentAPI.py +5 -0
- pyPreservica/entityAPI.py +51 -4
- pyPreservica/settingsAPI.py +295 -0
- pyPreservica/uploadAPI.py +8 -3
- {pyPreservica-3.0.6.dist-info → pypreservica-3.2.0.dist-info}/METADATA +3 -3
- pypreservica-3.2.0.dist-info/RECORD +20 -0
- {pyPreservica-3.0.6.dist-info → pypreservica-3.2.0.dist-info}/WHEEL +1 -1
- pyPreservica-3.0.6.dist-info/RECORD +0 -19
- {pyPreservica-3.0.6.dist-info → pypreservica-3.2.0.dist-info/licenses}/LICENSE.txt +0 -0
- {pyPreservica-3.0.6.dist-info → pypreservica-3.2.0.dist-info}/top_level.txt +0 -0
pyPreservica/__init__.py
CHANGED
|
@@ -30,10 +30,11 @@ from .monitorAPI import MonitorAPI, MonitorCategory, MonitorStatus, MessageStatu
|
|
|
30
30
|
from .webHooksAPI import WebHooksAPI, TriggerType, WebHookHandler
|
|
31
31
|
from .authorityAPI import AuthorityAPI, Table
|
|
32
32
|
from .mdformsAPI import MetadataGroupsAPI, Group, GroupField, GroupFieldType
|
|
33
|
+
from .settingsAPI import SettingsAPI
|
|
33
34
|
|
|
34
35
|
__author__ = "James Carr (drjamescarr@gmail.com)"
|
|
35
36
|
|
|
36
37
|
# Version of the pyPreservica package
|
|
37
|
-
__version__ = "3.0
|
|
38
|
+
__version__ = "3.2.0"
|
|
38
39
|
|
|
39
40
|
__license__ = "Apache License Version 2.0"
|
pyPreservica/common.py
CHANGED
|
@@ -853,6 +853,7 @@ class AuthenticatedAPI:
|
|
|
853
853
|
if self.tenant is None:
|
|
854
854
|
self.tenant = response.json()['tenant']
|
|
855
855
|
if self.two_fa_secret_key:
|
|
856
|
+
logger.debug("Found Two Factor Token")
|
|
856
857
|
totp = pyotp.TOTP(self.two_fa_secret_key)
|
|
857
858
|
data = {'username': self.username,
|
|
858
859
|
'continuationToken': response.json()['continuationToken'],
|
|
@@ -865,8 +866,8 @@ class AuthenticatedAPI:
|
|
|
865
866
|
else:
|
|
866
867
|
msg = "Failed to create a 2FA authentication token. Check your credentials are correct"
|
|
867
868
|
logger.error(msg)
|
|
868
|
-
logger.error(str(
|
|
869
|
-
raise RuntimeError(
|
|
869
|
+
logger.error(str(response_2fa.content))
|
|
870
|
+
raise RuntimeError(response_2fa.status_code, msg)
|
|
870
871
|
else:
|
|
871
872
|
msg = "2FA twoFactorToken required to authenticate against this account using 2FA"
|
|
872
873
|
logger.error(msg)
|
pyPreservica/contentAPI.py
CHANGED
|
@@ -34,6 +34,11 @@ class Field:
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
class ContentAPI(AuthenticatedAPI):
|
|
37
|
+
"""
|
|
38
|
+
The ContentAPI class provides the search interface to the Preservica repository.
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
|
|
37
42
|
|
|
38
43
|
def __init__(self, username: str = None, password: str = None, tenant: str = None, server: str = None,
|
|
39
44
|
use_shared_secret: bool = False, two_fa_secret_key: str = None,
|
pyPreservica/entityAPI.py
CHANGED
|
@@ -918,7 +918,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
918
918
|
content.append(tree.getroot())
|
|
919
919
|
else:
|
|
920
920
|
raise RuntimeError("Unknown data type")
|
|
921
|
-
xml_request = xml.etree.ElementTree.tostring(xml_object, encoding='utf-8')
|
|
921
|
+
xml_request = xml.etree.ElementTree.tostring(xml_object, encoding='utf-8').decode("utf-8")
|
|
922
922
|
logger.debug(xml_request)
|
|
923
923
|
request = self.session.put(url, data=xml_request, headers=headers)
|
|
924
924
|
if request.status_code == requests.codes.ok:
|
|
@@ -933,6 +933,43 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
933
933
|
raise exception
|
|
934
934
|
return self.entity(entity.entity_type, entity.reference)
|
|
935
935
|
|
|
936
|
+
def add_metadata_as_fragment(self, entity: Entity, schema: str, xml_fragment: str) -> Entity:
|
|
937
|
+
"""
|
|
938
|
+
Add a metadata fragment with a given namespace URI to an Entity
|
|
939
|
+
|
|
940
|
+
Don't parse the xml fragment which may add extra namespaces etc
|
|
941
|
+
|
|
942
|
+
Returns The updated Entity
|
|
943
|
+
|
|
944
|
+
:param xml_fragment: The new XML as a string
|
|
945
|
+
:param entity: The Entity to update
|
|
946
|
+
:param schema: The schema URI of the XML document
|
|
947
|
+
"""
|
|
948
|
+
headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/xml;charset=UTF-8'}
|
|
949
|
+
|
|
950
|
+
xml_doc = f"""<xip:MetadataContainer xmlns="{schema}" schemaUri="{schema}" xmlns:xip="{self.xip_ns}">
|
|
951
|
+
<xip:Entity>{entity.reference}</xip:Entity>
|
|
952
|
+
<xip:Content>
|
|
953
|
+
{xml_fragment}
|
|
954
|
+
</xip:Content>
|
|
955
|
+
</xip:MetadataContainer>"""
|
|
956
|
+
|
|
957
|
+
end_point = f"/{entity.path}/{entity.reference}/metadata"
|
|
958
|
+
logger.debug(xml_doc)
|
|
959
|
+
request = self.session.post(f'{self.protocol}://{self.server}/api/entity{end_point}', data=xml_doc,
|
|
960
|
+
headers=headers)
|
|
961
|
+
if request.status_code == requests.codes.ok:
|
|
962
|
+
return self.entity(entity_type=entity.entity_type, reference=entity.reference)
|
|
963
|
+
elif request.status_code == requests.codes.unauthorized:
|
|
964
|
+
self.token = self.__token__()
|
|
965
|
+
return self.add_metadata(entity, schema, xml_fragment)
|
|
966
|
+
else:
|
|
967
|
+
exception = HTTPException(entity.reference, request.status_code, request.url, "add_metadata",
|
|
968
|
+
request.content.decode('utf-8'))
|
|
969
|
+
logger.error(exception)
|
|
970
|
+
raise exception
|
|
971
|
+
|
|
972
|
+
|
|
936
973
|
def add_metadata(self, entity: Entity, schema: str, data) -> Entity:
|
|
937
974
|
"""
|
|
938
975
|
Add a metadata fragment with a given namespace URI
|
|
@@ -960,6 +997,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
960
997
|
xml_request = xml.etree.ElementTree.tostring(xml_object, encoding='utf-8')
|
|
961
998
|
end_point = f"/{entity.path}/{entity.reference}/metadata"
|
|
962
999
|
logger.debug(xml_request)
|
|
1000
|
+
print(xml_request)
|
|
963
1001
|
request = self.session.post(f'{self.protocol}://{self.server}/api/entity{end_point}', data=xml_request,
|
|
964
1002
|
headers=headers)
|
|
965
1003
|
if request.status_code == requests.codes.ok:
|
|
@@ -2126,9 +2164,15 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
2126
2164
|
actions = entity_response.findall(f'.//{{{self.xip_ns}}}EventAction')
|
|
2127
2165
|
result_list = []
|
|
2128
2166
|
for action in actions:
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2167
|
+
item: dict = {}
|
|
2168
|
+
event = action.find(f'.//{{{self.xip_ns}}}Event')
|
|
2169
|
+
event_type = event.attrib["type"]
|
|
2170
|
+
item['EventType'] = event_type
|
|
2171
|
+
entity_date = action.find(f'.//{{{self.xip_ns}}}Date')
|
|
2172
|
+
item['Date'] = entity_date.text
|
|
2173
|
+
entity_ref = action.find(f'.//{{{self.xip_ns}}}Entity')
|
|
2174
|
+
item['Entity'] = entity_ref.text
|
|
2175
|
+
result_list.append(item)
|
|
2132
2176
|
next_url = entity_response.find(f'.//{{{self.entity_ns}}}Next')
|
|
2133
2177
|
total_hits = entity_response.find(f'.//{{{self.entity_ns}}}TotalResults')
|
|
2134
2178
|
has_more = True
|
|
@@ -2162,6 +2206,9 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
2162
2206
|
params["from"] = kwargs.get("from_date")
|
|
2163
2207
|
if "to_date" in kwargs:
|
|
2164
2208
|
params["to"] = kwargs.get("to_date")
|
|
2209
|
+
if "username" in kwargs:
|
|
2210
|
+
params["username"] = kwargs.get("username")
|
|
2211
|
+
|
|
2165
2212
|
|
|
2166
2213
|
if next_page is None:
|
|
2167
2214
|
request = self.session.get(f'{self.protocol}://{self.server}/api/entity/events', params=params,
|
|
@@ -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")
|
pyPreservica/uploadAPI.py
CHANGED
|
@@ -911,17 +911,22 @@ def complex_asset_package(preservation_files_list=None, access_files_list=None,
|
|
|
911
911
|
if has_preservation_files:
|
|
912
912
|
if default_asset_title is None:
|
|
913
913
|
default_asset_title = os.path.splitext(os.path.basename(preservation_files_list[0]))[0]
|
|
914
|
-
|
|
915
914
|
# create the asset
|
|
916
|
-
|
|
915
|
+
if io_ref is None:
|
|
916
|
+
xip, io_ref = __create_io__(file_name=default_asset_title, parent_folder=parent_folder, **kwargs)
|
|
917
917
|
|
|
918
918
|
if has_access_files:
|
|
919
919
|
if default_asset_title is None:
|
|
920
920
|
default_asset_title = os.path.splitext(os.path.basename(access_files_list[0]))[0]
|
|
921
|
-
|
|
922
921
|
if io_ref is None:
|
|
923
922
|
xip, io_ref = __create_io__(file_name=default_asset_title, parent_folder=parent_folder, **kwargs)
|
|
924
923
|
|
|
924
|
+
if io_ref is None:
|
|
925
|
+
default_asset_title = kwargs.get('Title', None)
|
|
926
|
+
if default_asset_title is None:
|
|
927
|
+
default_asset_title = "New Asset"
|
|
928
|
+
xip, io_ref = __create_io__(file_name=default_asset_title, parent_folder=parent_folder, **kwargs)
|
|
929
|
+
|
|
925
930
|
if has_preservation_files:
|
|
926
931
|
# add the content objects
|
|
927
932
|
representation_name = kwargs.get('Preservation_Representation_Name', "Preservation")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pyPreservica
|
|
3
|
-
Version: 3.0
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: Python library for the Preservica API
|
|
5
5
|
Home-page: https://pypreservica.readthedocs.io/
|
|
6
6
|
Author: James Carr
|
|
@@ -16,7 +16,6 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
20
19
|
Classifier: Operating System :: OS Independent
|
|
21
20
|
Classifier: Topic :: System :: Archiving
|
|
22
21
|
Description-Content-Type: text/markdown
|
|
@@ -39,6 +38,7 @@ Dynamic: description-content-type
|
|
|
39
38
|
Dynamic: home-page
|
|
40
39
|
Dynamic: keywords
|
|
41
40
|
Dynamic: license
|
|
41
|
+
Dynamic: license-file
|
|
42
42
|
Dynamic: project-url
|
|
43
43
|
Dynamic: requires-dist
|
|
44
44
|
Dynamic: summary
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
pyPreservica/__init__.py,sha256=erL11_X3f9F3yfHhgtVxRdAH1m2LIOsYkTvReMS3em4,1250
|
|
2
|
+
pyPreservica/adminAPI.py,sha256=aMN2twcUZOFoGx2yapC6GVtBTdYHUJFA-5bdWVkCwS8,37773
|
|
3
|
+
pyPreservica/authorityAPI.py,sha256=jpf_m9i-IakyNVooi2yELuKt4yhX73hWqQNbPRHZx2g,9206
|
|
4
|
+
pyPreservica/common.py,sha256=iEeF4Kg51d4Vug-Dv8TeqS1lP2zcfM7YtBO8oANEcCU,38273
|
|
5
|
+
pyPreservica/contentAPI.py,sha256=ZvX2aGQEaksmw-m-oEUI6daVSqFe_IcE1cGwCNbSCDQ,22286
|
|
6
|
+
pyPreservica/entityAPI.py,sha256=cIuipvOlFUNgaLBOXtevTYQrT0zh1NG2y5gXz5sr_k0,125673
|
|
7
|
+
pyPreservica/mdformsAPI.py,sha256=_hBjT4-OzgLQGDfYX7b_01P27wc-RmsCEu57VtyAdh8,19173
|
|
8
|
+
pyPreservica/monitorAPI.py,sha256=LJOUrynBOWKlNiYpZ1iH8qB1oIIuKX1Ms1SRBcuXohA,6274
|
|
9
|
+
pyPreservica/opex.py,sha256=ccra1S4ojUXS3PlbU8WfxajOkJrwG4OykBnNrYP_jus,4875
|
|
10
|
+
pyPreservica/parAPI.py,sha256=f0ZUxLd0U-BW6kBx5K7W2Pv7NjG3MkTNydmxQ3U1ZVE,9296
|
|
11
|
+
pyPreservica/retentionAPI.py,sha256=QUTCbN4P3IpqmrebU_wd3n5ZVcyxVLTFAli8Y_GxOW4,24843
|
|
12
|
+
pyPreservica/settingsAPI.py,sha256=jXnMOCq3mimta6E-Os3J1I1if2pYsjLpOazAx8L-ZQI,10721
|
|
13
|
+
pyPreservica/uploadAPI.py,sha256=uX67mW-2q7FmjtXQ759GwHPL6Zs7R-iE8-86PBApvbY,99823
|
|
14
|
+
pyPreservica/webHooksAPI.py,sha256=B3C6PV_3JLlJrr9PtsTzL-21M0msx8Mnj18Xb3Bv4RE,6814
|
|
15
|
+
pyPreservica/workflowAPI.py,sha256=OcOiiUdrQerbPllrkj1lWpmuW0jTuyyV0urwPSYcd_U,17561
|
|
16
|
+
pypreservica-3.2.0.dist-info/licenses/LICENSE.txt,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
17
|
+
pypreservica-3.2.0.dist-info/METADATA,sha256=x3FR1zZKihN0pfSN_JdvM10pfP_IsfY1GWV8t3Yd_bo,3009
|
|
18
|
+
pypreservica-3.2.0.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
|
19
|
+
pypreservica-3.2.0.dist-info/top_level.txt,sha256=iIBh6NAznYQHOV8mv_y_kGKSDITek9rANyFDwJsbU-c,13
|
|
20
|
+
pypreservica-3.2.0.dist-info/RECORD,,
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
pyPreservica/__init__.py,sha256=b2cWepSUrTlRg-YBHg2Nue8zJHse-RXN7__aUmo9lLs,1212
|
|
2
|
-
pyPreservica/adminAPI.py,sha256=aMN2twcUZOFoGx2yapC6GVtBTdYHUJFA-5bdWVkCwS8,37773
|
|
3
|
-
pyPreservica/authorityAPI.py,sha256=jpf_m9i-IakyNVooi2yELuKt4yhX73hWqQNbPRHZx2g,9206
|
|
4
|
-
pyPreservica/common.py,sha256=4V9cwtb5LGIaKvm6hYVk-u4QltM7BDg4qXyz2gXR9X4,38197
|
|
5
|
-
pyPreservica/contentAPI.py,sha256=nOj7WciYARhLQWW65215Ghwz3CG61AVvikETPdtN4r0,22174
|
|
6
|
-
pyPreservica/entityAPI.py,sha256=-XZCys4nZRFEL6w0EpCQBUwADbMTi7BzDwrRzIG5PZQ,123493
|
|
7
|
-
pyPreservica/mdformsAPI.py,sha256=_hBjT4-OzgLQGDfYX7b_01P27wc-RmsCEu57VtyAdh8,19173
|
|
8
|
-
pyPreservica/monitorAPI.py,sha256=LJOUrynBOWKlNiYpZ1iH8qB1oIIuKX1Ms1SRBcuXohA,6274
|
|
9
|
-
pyPreservica/opex.py,sha256=ccra1S4ojUXS3PlbU8WfxajOkJrwG4OykBnNrYP_jus,4875
|
|
10
|
-
pyPreservica/parAPI.py,sha256=f0ZUxLd0U-BW6kBx5K7W2Pv7NjG3MkTNydmxQ3U1ZVE,9296
|
|
11
|
-
pyPreservica/retentionAPI.py,sha256=QUTCbN4P3IpqmrebU_wd3n5ZVcyxVLTFAli8Y_GxOW4,24843
|
|
12
|
-
pyPreservica/uploadAPI.py,sha256=icEwzu4-dDdMJ7tlnWKDGxMbqIcLqfj7DVw2QSFrSBY,99517
|
|
13
|
-
pyPreservica/webHooksAPI.py,sha256=B3C6PV_3JLlJrr9PtsTzL-21M0msx8Mnj18Xb3Bv4RE,6814
|
|
14
|
-
pyPreservica/workflowAPI.py,sha256=OcOiiUdrQerbPllrkj1lWpmuW0jTuyyV0urwPSYcd_U,17561
|
|
15
|
-
pyPreservica-3.0.6.dist-info/LICENSE.txt,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
16
|
-
pyPreservica-3.0.6.dist-info/METADATA,sha256=NI2dhIZ1issZztZyrDnXWD1W4ZzPOGWwHk1CNxxrP_A,3050
|
|
17
|
-
pyPreservica-3.0.6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
18
|
-
pyPreservica-3.0.6.dist-info/top_level.txt,sha256=iIBh6NAznYQHOV8mv_y_kGKSDITek9rANyFDwJsbU-c,13
|
|
19
|
-
pyPreservica-3.0.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|