pyPreservica 3.2.0__py3-none-any.whl → 3.2.1__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 +1 -1
- pyPreservica/common.py +27 -2
- pyPreservica/entityAPI.py +64 -15
- {pypreservica-3.2.0.dist-info → pypreservica-3.2.1.dist-info}/METADATA +3 -3
- {pypreservica-3.2.0.dist-info → pypreservica-3.2.1.dist-info}/RECORD +8 -8
- {pypreservica-3.2.0.dist-info → pypreservica-3.2.1.dist-info}/WHEEL +1 -1
- {pypreservica-3.2.0.dist-info → pypreservica-3.2.1.dist-info}/licenses/LICENSE.txt +0 -0
- {pypreservica-3.2.0.dist-info → pypreservica-3.2.1.dist-info}/top_level.txt +0 -0
pyPreservica/__init__.py
CHANGED
pyPreservica/common.py
CHANGED
|
@@ -27,6 +27,7 @@ from requests import Session
|
|
|
27
27
|
from urllib3.util import Retry
|
|
28
28
|
import requests
|
|
29
29
|
from requests.adapters import HTTPAdapter
|
|
30
|
+
from typing import TypeVar
|
|
30
31
|
|
|
31
32
|
import pyPreservica
|
|
32
33
|
|
|
@@ -420,6 +421,26 @@ class Bitstream:
|
|
|
420
421
|
return self.__str__()
|
|
421
422
|
|
|
422
423
|
|
|
424
|
+
class ExternIdentifier:
|
|
425
|
+
"""
|
|
426
|
+
Class to represent the External Identifier Object in the Preservica data model
|
|
427
|
+
"""
|
|
428
|
+
|
|
429
|
+
def __init__(self, identifier_type: str, identifier_value: str):
|
|
430
|
+
self.type = identifier_type
|
|
431
|
+
self.value = identifier_value
|
|
432
|
+
self.id = None
|
|
433
|
+
|
|
434
|
+
def __str__(self):
|
|
435
|
+
return f"""
|
|
436
|
+
Identifier: {self.id}
|
|
437
|
+
Identifier Type: {self.type}
|
|
438
|
+
Identifier Value: {self.value}
|
|
439
|
+
"""
|
|
440
|
+
|
|
441
|
+
def __repr__(self):
|
|
442
|
+
return self.__str__()
|
|
443
|
+
|
|
423
444
|
class Generation:
|
|
424
445
|
"""
|
|
425
446
|
Class to represent the Generation Object in the Preservica data model
|
|
@@ -528,6 +549,9 @@ class ContentObject(Entity):
|
|
|
528
549
|
self.tag = "ContentObject"
|
|
529
550
|
|
|
530
551
|
|
|
552
|
+
EntityT = TypeVar("EntityT", Folder, Asset, ContentObject, None)
|
|
553
|
+
|
|
554
|
+
|
|
531
555
|
class Representation:
|
|
532
556
|
"""
|
|
533
557
|
Class to represent the Representation Object in the Preservica data model
|
|
@@ -738,7 +762,7 @@ class AuthenticatedAPI:
|
|
|
738
762
|
Return the edition of this tenancy
|
|
739
763
|
"""
|
|
740
764
|
if self.major_version < 8 and self.minor_version < 3:
|
|
741
|
-
raise RuntimeError("Entitlement
|
|
765
|
+
raise RuntimeError("Entitlement API is only available when connected to a v7.3 System")
|
|
742
766
|
|
|
743
767
|
headers = {HEADER_TOKEN: self.token, 'Content-Type': 'application/json'}
|
|
744
768
|
|
|
@@ -777,6 +801,7 @@ class AuthenticatedAPI:
|
|
|
777
801
|
self.sec_ns = f"{NS_SEC_ROOT}/v{self.major_version}.{self.minor_version}"
|
|
778
802
|
self.admin_ns = f"{NS_ADMIN}/v{self.major_version}.{self.minor_version}"
|
|
779
803
|
|
|
804
|
+
|
|
780
805
|
def __version_number__(self):
|
|
781
806
|
"""
|
|
782
807
|
Determine the version number of the server
|
|
@@ -801,7 +826,7 @@ class AuthenticatedAPI:
|
|
|
801
826
|
RuntimeError(request.status_code, "version number failed")
|
|
802
827
|
|
|
803
828
|
def __str__(self):
|
|
804
|
-
return f"pyPreservica version: {pyPreservica.__version__} (Preservica
|
|
829
|
+
return f"pyPreservica version: {pyPreservica.__version__} (Preservica 8.0 Compatible) " \
|
|
805
830
|
f"Connected to: {self.server} Preservica version: {self.version} as {self.username} " \
|
|
806
831
|
f"in tenancy {self.tenant}"
|
|
807
832
|
|
pyPreservica/entityAPI.py
CHANGED
|
@@ -486,6 +486,54 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
486
486
|
logger.error(request)
|
|
487
487
|
raise RuntimeError(request.status_code, "delete_identifier failed")
|
|
488
488
|
|
|
489
|
+
def entity_identifiers(self, entity: Entity, external_identifier_type = None) -> set[ExternIdentifier]:
|
|
490
|
+
"""
|
|
491
|
+
Get all external identifiers on an entity
|
|
492
|
+
|
|
493
|
+
Returns the set of external identifiers on the entity
|
|
494
|
+
|
|
495
|
+
:param entity: The Entity (Asset or Folder)
|
|
496
|
+
:param external_identifier_type: Optional identifier type to filter the results
|
|
497
|
+
:type entity: Entity
|
|
498
|
+
"""
|
|
499
|
+
headers = {HEADER_TOKEN: self.token}
|
|
500
|
+
request = self.session.get(
|
|
501
|
+
f'{self.protocol}://{self.server}/api/entity/{entity.path}/{entity.reference}/identifiers',
|
|
502
|
+
headers=headers)
|
|
503
|
+
if request.status_code == requests.codes.ok:
|
|
504
|
+
xml_response = str(request.content.decode('utf-8'))
|
|
505
|
+
logger.debug(xml_response)
|
|
506
|
+
entity_response = xml.etree.ElementTree.fromstring(xml_response)
|
|
507
|
+
identifier_list = entity_response.findall(f'.//{{{self.xip_ns}}}Identifier')
|
|
508
|
+
result = set()
|
|
509
|
+
for identifier in identifier_list:
|
|
510
|
+
identifier_value = identifier_type = identifier_id = ""
|
|
511
|
+
for child in identifier:
|
|
512
|
+
if child.tag.endswith("Type"):
|
|
513
|
+
identifier_type = child.text
|
|
514
|
+
if child.tag.endswith("Value"):
|
|
515
|
+
identifier_value = child.text
|
|
516
|
+
if child.tag.endswith("ApiId"):
|
|
517
|
+
identifier_id = child.text
|
|
518
|
+
if external_identifier_type is None:
|
|
519
|
+
external_id: ExternIdentifier = ExternIdentifier(identifier_type, identifier_value)
|
|
520
|
+
external_id.identifier_id = identifier_id
|
|
521
|
+
result.add(external_id)
|
|
522
|
+
else:
|
|
523
|
+
if identifier_type == external_identifier_type:
|
|
524
|
+
external_id: ExternIdentifier = ExternIdentifier(identifier_type, identifier_value)
|
|
525
|
+
external_id.identifier_id = identifier_id
|
|
526
|
+
result.add(external_id)
|
|
527
|
+
return result
|
|
528
|
+
elif request.status_code == requests.codes.unauthorized:
|
|
529
|
+
self.token = self.__token__()
|
|
530
|
+
return self.entity_identifiers(entity)
|
|
531
|
+
else:
|
|
532
|
+
exception = HTTPException(entity.reference, request.status_code, request.url, "identifiers_for_entity",
|
|
533
|
+
request.content.decode('utf-8'))
|
|
534
|
+
logger.error(exception)
|
|
535
|
+
raise exception
|
|
536
|
+
|
|
489
537
|
|
|
490
538
|
def identifiers_for_entity(self, entity: Entity) -> set[Tuple]:
|
|
491
539
|
"""
|
|
@@ -526,14 +574,14 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
526
574
|
|
|
527
575
|
|
|
528
576
|
|
|
529
|
-
def identifier(self, identifier_type: str, identifier_value: str) -> set[
|
|
577
|
+
def identifier(self, identifier_type: str, identifier_value: str) -> set[EntityT]:
|
|
530
578
|
"""
|
|
531
|
-
|
|
579
|
+
Get all entities which have the external identifier
|
|
532
580
|
|
|
533
|
-
|
|
581
|
+
Returns the set of entities which have the external identifier
|
|
534
582
|
|
|
535
|
-
|
|
536
|
-
|
|
583
|
+
:param identifier_type: The identifier type
|
|
584
|
+
:param identifier_value: The identifier value
|
|
537
585
|
"""
|
|
538
586
|
headers = {HEADER_TOKEN: self.token}
|
|
539
587
|
payload = {'type': identifier_type, 'value': identifier_value}
|
|
@@ -861,7 +909,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
861
909
|
logger.error(exception)
|
|
862
910
|
raise exception
|
|
863
911
|
|
|
864
|
-
def delete_metadata(self, entity:
|
|
912
|
+
def delete_metadata(self, entity: EntityT, schema: str) -> EntityT:
|
|
865
913
|
"""
|
|
866
914
|
Deletes all the metadata fragments on an entity which match the schema URI
|
|
867
915
|
|
|
@@ -887,7 +935,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
887
935
|
|
|
888
936
|
return self.entity(entity.entity_type, entity.reference)
|
|
889
937
|
|
|
890
|
-
def update_metadata(self, entity:
|
|
938
|
+
def update_metadata(self, entity: EntityT, schema: str, data: Any) -> EntityT:
|
|
891
939
|
"""
|
|
892
940
|
Update all existing metadata fragments which match the schema
|
|
893
941
|
|
|
@@ -933,7 +981,9 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
933
981
|
raise exception
|
|
934
982
|
return self.entity(entity.entity_type, entity.reference)
|
|
935
983
|
|
|
936
|
-
def add_metadata_as_fragment(
|
|
984
|
+
def add_metadata_as_fragment(
|
|
985
|
+
self, entity: EntityT, schema: str, xml_fragment: str
|
|
986
|
+
) -> EntityT:
|
|
937
987
|
"""
|
|
938
988
|
Add a metadata fragment with a given namespace URI to an Entity
|
|
939
989
|
|
|
@@ -969,8 +1019,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
969
1019
|
logger.error(exception)
|
|
970
1020
|
raise exception
|
|
971
1021
|
|
|
972
|
-
|
|
973
|
-
def add_metadata(self, entity: Entity, schema: str, data) -> Entity:
|
|
1022
|
+
def add_metadata(self, entity: EntityT, schema: str, data) -> EntityT:
|
|
974
1023
|
"""
|
|
975
1024
|
Add a metadata fragment with a given namespace URI
|
|
976
1025
|
|
|
@@ -1011,7 +1060,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
1011
1060
|
logger.error(exception)
|
|
1012
1061
|
raise exception
|
|
1013
1062
|
|
|
1014
|
-
def save(self, entity:
|
|
1063
|
+
def save(self, entity: EntityT) -> EntityT:
|
|
1015
1064
|
"""
|
|
1016
1065
|
Save the title and description of an entity
|
|
1017
1066
|
|
|
@@ -1129,7 +1178,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
1129
1178
|
logger.error(exception)
|
|
1130
1179
|
raise exception
|
|
1131
1180
|
|
|
1132
|
-
def move_sync(self, entity:
|
|
1181
|
+
def move_sync(self, entity: EntityT, dest_folder: Folder) -> EntityT:
|
|
1133
1182
|
"""
|
|
1134
1183
|
Move an Entity (Asset or Folder) to a new Folder
|
|
1135
1184
|
If dest_folder is None then the entity must be a Folder and will be moved to the root of the repository
|
|
@@ -1169,7 +1218,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
1169
1218
|
logger.error(exception)
|
|
1170
1219
|
raise exception
|
|
1171
1220
|
|
|
1172
|
-
def move(self, entity:
|
|
1221
|
+
def move(self, entity: EntityT, dest_folder: Folder) -> EntityT:
|
|
1173
1222
|
"""
|
|
1174
1223
|
Move an Entity (Asset or Folder) to a new Folder
|
|
1175
1224
|
If dest_folder is None then the entity must be a Folder and will be moved to the root of the repository
|
|
@@ -1274,7 +1323,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
1274
1323
|
else:
|
|
1275
1324
|
return xml_object.find(tag).text
|
|
1276
1325
|
|
|
1277
|
-
def security_tag_sync(self, entity:
|
|
1326
|
+
def security_tag_sync(self, entity: EntityT, new_tag: str) -> EntityT:
|
|
1278
1327
|
"""
|
|
1279
1328
|
Change the security tag for a folder or asset
|
|
1280
1329
|
|
|
@@ -1354,7 +1403,7 @@ class EntityAPI(AuthenticatedAPI):
|
|
|
1354
1403
|
logger.error(exception)
|
|
1355
1404
|
raise exception
|
|
1356
1405
|
|
|
1357
|
-
def entity(self, entity_type: EntityType, reference: str) ->
|
|
1406
|
+
def entity(self, entity_type: EntityType, reference: str) -> EntityT:
|
|
1358
1407
|
"""
|
|
1359
1408
|
Retrieve an entity by its type and reference
|
|
1360
1409
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyPreservica
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.1
|
|
4
4
|
Summary: Python library for the Preservica API
|
|
5
5
|
Home-page: https://pypreservica.readthedocs.io/
|
|
6
6
|
Author: James Carr
|
|
@@ -23,8 +23,8 @@ License-File: LICENSE.txt
|
|
|
23
23
|
Requires-Dist: requests
|
|
24
24
|
Requires-Dist: urllib3
|
|
25
25
|
Requires-Dist: certifi
|
|
26
|
-
Requires-Dist: boto3
|
|
27
|
-
Requires-Dist: botocore
|
|
26
|
+
Requires-Dist: boto3>=1.36.0
|
|
27
|
+
Requires-Dist: botocore>=1.36.0
|
|
28
28
|
Requires-Dist: s3transfer
|
|
29
29
|
Requires-Dist: azure-storage-blob
|
|
30
30
|
Requires-Dist: tqdm
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
pyPreservica/__init__.py,sha256=
|
|
1
|
+
pyPreservica/__init__.py,sha256=IDGY2--79x65wptaP8fj5cWTaDT_a2_2TaSrYJF1UfY,1250
|
|
2
2
|
pyPreservica/adminAPI.py,sha256=aMN2twcUZOFoGx2yapC6GVtBTdYHUJFA-5bdWVkCwS8,37773
|
|
3
3
|
pyPreservica/authorityAPI.py,sha256=jpf_m9i-IakyNVooi2yELuKt4yhX73hWqQNbPRHZx2g,9206
|
|
4
|
-
pyPreservica/common.py,sha256=
|
|
4
|
+
pyPreservica/common.py,sha256=pPg29dQYa3SeKvRIci7Q4AwAY9CjCe0ENDaElWYqCxk,38929
|
|
5
5
|
pyPreservica/contentAPI.py,sha256=ZvX2aGQEaksmw-m-oEUI6daVSqFe_IcE1cGwCNbSCDQ,22286
|
|
6
|
-
pyPreservica/entityAPI.py,sha256=
|
|
6
|
+
pyPreservica/entityAPI.py,sha256=0ATOcwhBF8Cu6R-BnsV0I4EtXmkLW9jeWbXQaqYyMmo,128230
|
|
7
7
|
pyPreservica/mdformsAPI.py,sha256=_hBjT4-OzgLQGDfYX7b_01P27wc-RmsCEu57VtyAdh8,19173
|
|
8
8
|
pyPreservica/monitorAPI.py,sha256=LJOUrynBOWKlNiYpZ1iH8qB1oIIuKX1Ms1SRBcuXohA,6274
|
|
9
9
|
pyPreservica/opex.py,sha256=ccra1S4ojUXS3PlbU8WfxajOkJrwG4OykBnNrYP_jus,4875
|
|
@@ -13,8 +13,8 @@ pyPreservica/settingsAPI.py,sha256=jXnMOCq3mimta6E-Os3J1I1if2pYsjLpOazAx8L-ZQI,1
|
|
|
13
13
|
pyPreservica/uploadAPI.py,sha256=uX67mW-2q7FmjtXQ759GwHPL6Zs7R-iE8-86PBApvbY,99823
|
|
14
14
|
pyPreservica/webHooksAPI.py,sha256=B3C6PV_3JLlJrr9PtsTzL-21M0msx8Mnj18Xb3Bv4RE,6814
|
|
15
15
|
pyPreservica/workflowAPI.py,sha256=OcOiiUdrQerbPllrkj1lWpmuW0jTuyyV0urwPSYcd_U,17561
|
|
16
|
-
pypreservica-3.2.
|
|
17
|
-
pypreservica-3.2.
|
|
18
|
-
pypreservica-3.2.
|
|
19
|
-
pypreservica-3.2.
|
|
20
|
-
pypreservica-3.2.
|
|
16
|
+
pypreservica-3.2.1.dist-info/licenses/LICENSE.txt,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
17
|
+
pypreservica-3.2.1.dist-info/METADATA,sha256=rrmuhukqFCtJTb5_Q-oM6HX5Q2sUlSgO0AcC0ciPvSg,3025
|
|
18
|
+
pypreservica-3.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
19
|
+
pypreservica-3.2.1.dist-info/top_level.txt,sha256=iIBh6NAznYQHOV8mv_y_kGKSDITek9rANyFDwJsbU-c,13
|
|
20
|
+
pypreservica-3.2.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|