pyPreservica 3.0.6__tar.gz → 3.1.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.
- {pypreservica-3.0.6 → pypreservica-3.1.1}/PKG-INFO +3 -3
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/__init__.py +1 -1
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/common.py +3 -2
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/entityAPI.py +13 -4
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/uploadAPI.py +8 -3
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica.egg-info/PKG-INFO +3 -3
- {pypreservica-3.0.6 → pypreservica-3.1.1}/setup.py +1 -2
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_content_api.py +2 -2
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_metadata.py +43 -10
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_par.py +1 -1
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_schema.py +7 -7
- {pypreservica-3.0.6 → pypreservica-3.1.1}/LICENSE.txt +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/README.md +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/adminAPI.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/authorityAPI.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/contentAPI.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/mdformsAPI.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/monitorAPI.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/opex.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/parAPI.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/retentionAPI.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/webHooksAPI.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica/workflowAPI.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica.egg-info/SOURCES.txt +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica.egg-info/dependency_links.txt +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica.egg-info/requires.txt +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/pyPreservica.egg-info/top_level.txt +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/setup.cfg +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_authority_records.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_bitstream.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_children.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_crawl_fs.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_delete.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_download.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_entity.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_export_opex.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_groups.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_identifier.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_ingest.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_integrity_check.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_replace.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_retention.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_security.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_thumbnail.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_upload.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_users.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_workflow.py +0 -0
- {pypreservica-3.0.6 → pypreservica-3.1.1}/tests/test_xml_metadata.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pyPreservica
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.1.1
|
|
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
|
|
@@ -34,6 +34,6 @@ from .mdformsAPI import MetadataGroupsAPI, Group, GroupField, GroupFieldType
|
|
|
34
34
|
__author__ = "James Carr (drjamescarr@gmail.com)"
|
|
35
35
|
|
|
36
36
|
# Version of the pyPreservica package
|
|
37
|
-
__version__ = "3.
|
|
37
|
+
__version__ = "3.1.1"
|
|
38
38
|
|
|
39
39
|
__license__ = "Apache License Version 2.0"
|
|
@@ -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)
|
|
@@ -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:
|
|
@@ -2126,9 +2126,15 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
2126
2126
|
actions = entity_response.findall(f'.//{{{self.xip_ns}}}EventAction')
|
|
2127
2127
|
result_list = []
|
|
2128
2128
|
for action in actions:
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2129
|
+
item: dict = {}
|
|
2130
|
+
event = action.find(f'.//{{{self.xip_ns}}}Event')
|
|
2131
|
+
event_type = event.attrib["type"]
|
|
2132
|
+
item['EventType'] = event_type
|
|
2133
|
+
entity_date = action.find(f'.//{{{self.xip_ns}}}Date')
|
|
2134
|
+
item['Date'] = entity_date.text
|
|
2135
|
+
entity_ref = action.find(f'.//{{{self.xip_ns}}}Entity')
|
|
2136
|
+
item['Entity'] = entity_ref.text
|
|
2137
|
+
result_list.append(item)
|
|
2132
2138
|
next_url = entity_response.find(f'.//{{{self.entity_ns}}}Next')
|
|
2133
2139
|
total_hits = entity_response.find(f'.//{{{self.entity_ns}}}TotalResults')
|
|
2134
2140
|
has_more = True
|
|
@@ -2162,6 +2168,9 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
2162
2168
|
params["from"] = kwargs.get("from_date")
|
|
2163
2169
|
if "to_date" in kwargs:
|
|
2164
2170
|
params["to"] = kwargs.get("to_date")
|
|
2171
|
+
if "username" in kwargs:
|
|
2172
|
+
params["username"] = kwargs.get("username")
|
|
2173
|
+
|
|
2165
2174
|
|
|
2166
2175
|
if next_page is None:
|
|
2167
2176
|
request = self.session.get(f'{self.protocol}://{self.server}/api/entity/events', params=params,
|
|
@@ -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.
|
|
3
|
+
Version: 3.1.1
|
|
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
|
|
@@ -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="3.
|
|
24
|
+
version="3.1.1",
|
|
25
25
|
description="Python library for the Preservica API",
|
|
26
26
|
long_description=README,
|
|
27
27
|
long_description_content_type="text/markdown",
|
|
@@ -37,7 +37,6 @@ setup(
|
|
|
37
37
|
'Programming Language :: Python :: 3.10',
|
|
38
38
|
'Programming Language :: Python :: 3.11',
|
|
39
39
|
'Programming Language :: Python :: 3.12',
|
|
40
|
-
"License :: OSI Approved :: Apache Software License",
|
|
41
40
|
"Operating System :: OS Independent",
|
|
42
41
|
"Topic :: System :: Archiving",
|
|
43
42
|
],
|
|
@@ -84,7 +84,7 @@ def test_simple_search_list(setup_data):
|
|
|
84
84
|
client = ContentAPI()
|
|
85
85
|
results = list(client.simple_search_list(query="pyPreservica"))
|
|
86
86
|
assert len(results) == 5
|
|
87
|
-
assert results.pop()['xip.reference'] == '
|
|
87
|
+
assert results.pop()['xip.reference'] == '7fbeba9f-8067-46d9-bb00-8c8c7b3b0475'
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
def test_simple_search_list2(setup_data):
|
|
@@ -94,7 +94,7 @@ def test_simple_search_list2(setup_data):
|
|
|
94
94
|
|
|
95
95
|
results = list(client.simple_search_list("pyPreservica", 25, columns))
|
|
96
96
|
assert len(results) == 5
|
|
97
|
-
assert results.pop()['xip.reference'] == '
|
|
97
|
+
assert results.pop()['xip.reference'] == '7fbeba9f-8067-46d9-bb00-8c8c7b3b0475'
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
def test_field_search(setup_data):
|
|
@@ -9,14 +9,25 @@ from pyPreservica import *
|
|
|
9
9
|
|
|
10
10
|
FOLDER_ID = "ebd977f6-bebd-4ecf-99be-e054989f9af4"
|
|
11
11
|
ASSET_ID = "683f9db7-ff81-4859-9c03-f68cfa5d9c3d"
|
|
12
|
-
CO_ID =
|
|
13
|
-
|
|
14
|
-
XML_DOCUMENT = "
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
CO_ID = "0f2997f7-728c-4e55-9f92-381ed1260d70"
|
|
13
|
+
|
|
14
|
+
XML_DOCUMENT = """
|
|
15
|
+
<person:Person xmlns:person="https://www.person.com/person">
|
|
16
|
+
<person:Name>Name</person:Name>
|
|
17
|
+
<person:Phone>01234 100 100</person:Phone>
|
|
18
|
+
<person:Email>test@test.com</person:Email>
|
|
19
|
+
<person:Address>Abingdon, UK</person:Address>
|
|
20
|
+
</person:Person>
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
XML_DOCUMENT_NO_PREFIX = """
|
|
24
|
+
<Person xmlns="https://www.person.com/person">
|
|
25
|
+
<Name>Name</Name>
|
|
26
|
+
<Phone>01234 100 100</Phone>
|
|
27
|
+
<Email>test@test.com</Email>
|
|
28
|
+
<Address>Abingdon, UK</Address>
|
|
29
|
+
</Person>
|
|
30
|
+
"""
|
|
20
31
|
|
|
21
32
|
|
|
22
33
|
def test_get_folder_metadata():
|
|
@@ -50,6 +61,28 @@ def test_update_folder_metadata():
|
|
|
50
61
|
folder = client.update_metadata(entity, "http://purl.org/dc/elements/1.1/", xml_string)
|
|
51
62
|
|
|
52
63
|
|
|
64
|
+
def test_add_folder_metadata_no_prefix():
|
|
65
|
+
client = EntityAPI()
|
|
66
|
+
entity = client.entity(EntityType.FOLDER, FOLDER_ID)
|
|
67
|
+
folder = client.add_metadata(entity, "https://www.person.com/person", XML_DOCUMENT_NO_PREFIX)
|
|
68
|
+
|
|
69
|
+
def test_add_folder_metadata_with_ns():
|
|
70
|
+
client = EntityAPI()
|
|
71
|
+
entity = client.entity(EntityType.FOLDER, FOLDER_ID)
|
|
72
|
+
folder = client.add_metadata(entity, "https://www.person.com/person", XML_DOCUMENT)
|
|
73
|
+
|
|
74
|
+
def test_add_asset_metadata_no_prefix():
|
|
75
|
+
client = EntityAPI()
|
|
76
|
+
entity = client.entity(EntityType.ASSET, ASSET_ID)
|
|
77
|
+
folder = client.add_metadata(entity, "https://www.person.com/person", XML_DOCUMENT_NO_PREFIX)
|
|
78
|
+
|
|
79
|
+
def test_add_asset_metadata_with_ns():
|
|
80
|
+
client = EntityAPI()
|
|
81
|
+
entity = client.entity(EntityType.ASSET, ASSET_ID)
|
|
82
|
+
folder = client.add_metadata(entity, "https://www.person.com/person", XML_DOCUMENT)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
53
86
|
def test_add_folder_metadata_string():
|
|
54
87
|
client = EntityAPI()
|
|
55
88
|
entity = client.entity(EntityType.FOLDER, FOLDER_ID)
|
|
@@ -85,8 +118,8 @@ def test_get_all_asset_metadata():
|
|
|
85
118
|
|
|
86
119
|
def test_get_co_metadata():
|
|
87
120
|
client = EntityAPI()
|
|
88
|
-
|
|
89
|
-
entity = client.delete_metadata(
|
|
121
|
+
entity_object = client.entity(EntityType.CONTENT_OBJECT, CO_ID)
|
|
122
|
+
entity = client.delete_metadata(entity_object, "https://www.person.com/person")
|
|
90
123
|
xml_string = client.metadata_for_entity(entity, "https://www.person.com/person")
|
|
91
124
|
assert xml_string is None
|
|
92
125
|
co = client.add_metadata(entity, "https://www.person.com/person", XML_DOCUMENT)
|
|
@@ -6,7 +6,7 @@ from pyPreservica import *
|
|
|
6
6
|
def test_format_families():
|
|
7
7
|
par = PreservationActionRegistry()
|
|
8
8
|
document = par.format_families()
|
|
9
|
-
assert len(json.loads(document)['formatFamilies']) ==
|
|
9
|
+
assert len(json.loads(document)['formatFamilies']) == 192
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def test_format():
|
|
@@ -53,16 +53,16 @@ def test_get_xml_document_by_uri():
|
|
|
53
53
|
|
|
54
54
|
def test_add_xml_document():
|
|
55
55
|
client = AdminAPI()
|
|
56
|
-
client.delete_xml_document("http://www.crossref.org/schema/5.
|
|
57
|
-
|
|
56
|
+
client.delete_xml_document("http://www.crossref.org/schema/5.4.0")
|
|
57
|
+
xml_doc = requests.get(
|
|
58
58
|
"https://gitlab.com/crossref/schema/-/raw/master/best-practice-examples/book5.3.0.xml").content.decode("utf-8")
|
|
59
|
-
client.add_xml_document("book5.
|
|
60
|
-
xml_document = client.xml_document("http://www.crossref.org/schema/5.
|
|
61
|
-
assert len(xml_document) == len(
|
|
62
|
-
client.delete_xml_document("http://www.crossref.org/schema/5.
|
|
59
|
+
client.add_xml_document("book5.4.0", xml_doc)
|
|
60
|
+
xml_document = client.xml_document("http://www.crossref.org/schema/5.4.0")
|
|
61
|
+
assert len(xml_document) == len(xml_doc)
|
|
62
|
+
client.delete_xml_document("http://www.crossref.org/schema/5.4.0")
|
|
63
63
|
|
|
64
64
|
with open("test_data/mods.xml", mode="rb") as fd:
|
|
65
|
-
client.add_xml_document("mods31",
|
|
65
|
+
client.add_xml_document("mods31", xml_doc)
|
|
66
66
|
|
|
67
67
|
xml_document = client.xml_document("http://www.loc.gov/mods/v31")
|
|
68
68
|
client.delete_xml_document("http://www.loc.gov/mods/v31")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|