pyPreservica 2.9.3__tar.gz → 3.0.0__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-2.9.3 → pypreservica-3.0.0}/PKG-INFO +1 -1
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/__init__.py +1 -1
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/uploadAPI.py +69 -11
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica.egg-info/PKG-INFO +1 -1
- {pypreservica-2.9.3 → pypreservica-3.0.0}/setup.py +1 -1
- {pypreservica-2.9.3 → pypreservica-3.0.0}/LICENSE.txt +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/README.md +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/adminAPI.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/authorityAPI.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/common.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/contentAPI.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/entityAPI.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/mdformsAPI.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/monitorAPI.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/opex.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/parAPI.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/retentionAPI.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/webHooksAPI.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica/workflowAPI.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica.egg-info/SOURCES.txt +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica.egg-info/dependency_links.txt +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica.egg-info/requires.txt +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/pyPreservica.egg-info/top_level.txt +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/setup.cfg +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_authority_records.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_bitstream.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_children.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_content_api.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_crawl_fs.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_delete.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_download.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_entity.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_export_opex.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_groups.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_identifier.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_ingest.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_integrity_check.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_metadata.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_par.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_replace.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_retention.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_schema.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_security.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_thumbnail.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_upload.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_users.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_workflow.py +0 -0
- {pypreservica-2.9.3 → pypreservica-3.0.0}/tests/test_xml_metadata.py +0 -0
|
@@ -23,6 +23,6 @@ from .mdformsAPI import MetadataGroupsAPI, Group, GroupField, GroupFieldType
|
|
|
23
23
|
__author__ = "James Carr (drjamescarr@gmail.com)"
|
|
24
24
|
|
|
25
25
|
# Version of the pyPreservica package
|
|
26
|
-
__version__ = "
|
|
26
|
+
__version__ = "3.0.0"
|
|
27
27
|
|
|
28
28
|
__license__ = "Apache License Version 2.0"
|
|
@@ -13,20 +13,22 @@ import shutil
|
|
|
13
13
|
import tempfile
|
|
14
14
|
import uuid
|
|
15
15
|
import xml
|
|
16
|
-
from datetime import datetime, timedelta
|
|
16
|
+
from datetime import datetime, timedelta, timezone
|
|
17
17
|
from time import sleep
|
|
18
18
|
from xml.dom import minidom
|
|
19
19
|
from xml.etree import ElementTree
|
|
20
20
|
from xml.etree.ElementTree import Element, SubElement
|
|
21
21
|
|
|
22
22
|
import boto3
|
|
23
|
+
import botocore
|
|
23
24
|
import s3transfer.tasks
|
|
24
25
|
import s3transfer.upload
|
|
25
|
-
|
|
26
|
+
from botocore.session import get_session
|
|
26
27
|
from boto3.s3.transfer import TransferConfig, S3Transfer
|
|
27
28
|
from botocore.config import Config
|
|
28
29
|
from botocore.credentials import RefreshableCredentials
|
|
29
|
-
from botocore.exceptions import ClientError
|
|
30
|
+
from botocore.exceptions import ClientError, NoCredentialsError, PartialCredentialsError
|
|
31
|
+
from dateutil.tz import tzlocal
|
|
30
32
|
from s3transfer import S3UploadFailedError
|
|
31
33
|
from tqdm import tqdm
|
|
32
34
|
|
|
@@ -37,7 +39,7 @@ logger = logging.getLogger(__name__)
|
|
|
37
39
|
|
|
38
40
|
MB = 1024 * 1024
|
|
39
41
|
GB = 1024 ** 3
|
|
40
|
-
transfer_config = TransferConfig(multipart_threshold=int(
|
|
42
|
+
transfer_config = TransferConfig(multipart_threshold=int(32 * MB))
|
|
41
43
|
|
|
42
44
|
CONTENT_FOLDER = "content"
|
|
43
45
|
PRESERVATION_CONTENT_FOLDER = "p1"
|
|
@@ -1910,9 +1912,38 @@ class UploadAPI(AuthenticatedAPI):
|
|
|
1910
1912
|
endpoint = f'{self.protocol}://{self.server}/api/s3/buckets'
|
|
1911
1913
|
self.token = self.__token__()
|
|
1912
1914
|
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1915
|
+
|
|
1916
|
+
retries= {
|
|
1917
|
+
'max_attempts': 10,
|
|
1918
|
+
'mode': 'adaptive'
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
def new_credentials():
|
|
1922
|
+
metadata: dict = {}
|
|
1923
|
+
metadata['access_key'] = self.__token__()
|
|
1924
|
+
metadata['secret_key'] = "NOT_USED"
|
|
1925
|
+
metadata['token'] = ""
|
|
1926
|
+
metadata["expiry_time"] = (datetime.now(tzlocal()) + timedelta(minutes=12)).isoformat()
|
|
1927
|
+
logger.info("Refreshing credentials at: " + str(datetime.now(tzlocal())))
|
|
1928
|
+
return metadata
|
|
1929
|
+
|
|
1930
|
+
session = get_session()
|
|
1931
|
+
|
|
1932
|
+
session_credentials = RefreshableCredentials.create_from_metadata(
|
|
1933
|
+
metadata=new_credentials(),
|
|
1934
|
+
refresh_using=new_credentials,
|
|
1935
|
+
advisory_timeout = 4 * 60,
|
|
1936
|
+
mandatory_timeout = 12 * 60,
|
|
1937
|
+
method = 'Preservica'
|
|
1938
|
+
)
|
|
1939
|
+
|
|
1940
|
+
autorefresh_session = boto3.Session(botocore_session=session)
|
|
1941
|
+
|
|
1942
|
+
session._credentials = session_credentials
|
|
1943
|
+
|
|
1944
|
+
s3_client = autorefresh_session.client('s3', endpoint_url=endpoint,
|
|
1945
|
+
config=Config(s3={'addressing_style': 'path'}, read_timeout=120, connect_timeout=120,
|
|
1946
|
+
retries=retries, tcp_keepalive=True))
|
|
1916
1947
|
|
|
1917
1948
|
metadata = {}
|
|
1918
1949
|
if folder is not None:
|
|
@@ -1925,21 +1956,48 @@ class UploadAPI(AuthenticatedAPI):
|
|
|
1925
1956
|
try:
|
|
1926
1957
|
key_id = str(uuid.uuid4()) + ".zip"
|
|
1927
1958
|
|
|
1959
|
+
|
|
1960
|
+
# how big is the package
|
|
1961
|
+
package_size = os.path.getsize(path_to_zip_package)
|
|
1962
|
+
if package_size > 1 * GB:
|
|
1963
|
+
transfer_config.multipart_chunksize = 16 * MB ## Min 64 Chunks
|
|
1964
|
+
if package_size > 8 * GB:
|
|
1965
|
+
transfer_config.multipart_chunksize = 32 * MB ## Min 256 Chunks
|
|
1966
|
+
if package_size > 24 * GB:
|
|
1967
|
+
transfer_config.multipart_chunksize = 48 * MB ## Min 512 Chunks
|
|
1968
|
+
if package_size > 48 * GB:
|
|
1969
|
+
transfer_config.multipart_chunksize = 64 * MB
|
|
1970
|
+
|
|
1971
|
+
logger.info("Using Multipart Chunk Size: " + str(transfer_config.multipart_chunksize))
|
|
1972
|
+
|
|
1928
1973
|
transfer = S3Transfer(client=s3_client, config=transfer_config)
|
|
1929
1974
|
|
|
1930
1975
|
transfer.PutObjectTask = PutObjectTask
|
|
1931
1976
|
transfer.CompleteMultipartUploadTask = CompleteMultipartUploadTask
|
|
1932
1977
|
transfer.upload_file = upload_file
|
|
1933
1978
|
|
|
1934
|
-
|
|
1979
|
+
|
|
1980
|
+
response = transfer.upload_file(self=transfer, filename=path_to_zip_package, bucket=bucket,
|
|
1981
|
+
key=key_id,
|
|
1935
1982
|
extra_args=metadata,
|
|
1936
1983
|
callback=callback)
|
|
1937
1984
|
|
|
1985
|
+
|
|
1938
1986
|
if delete_after_upload:
|
|
1939
1987
|
os.remove(path_to_zip_package)
|
|
1940
1988
|
|
|
1941
1989
|
return response['ResponseMetadata']['HTTPHeaders']['preservica-progress-token']
|
|
1942
1990
|
|
|
1943
|
-
except
|
|
1944
|
-
logger.error(
|
|
1945
|
-
raise
|
|
1991
|
+
except (NoCredentialsError, PartialCredentialsError) as ex:
|
|
1992
|
+
logger.error(ex)
|
|
1993
|
+
raise ex
|
|
1994
|
+
|
|
1995
|
+
except ClientError as ex:
|
|
1996
|
+
logger.error(ex)
|
|
1997
|
+
raise ex
|
|
1998
|
+
|
|
1999
|
+
|
|
2000
|
+
|
|
2001
|
+
|
|
2002
|
+
|
|
2003
|
+
|
|
@@ -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="
|
|
24
|
+
version="3.0.0",
|
|
25
25
|
description="Python library for the Preservica API",
|
|
26
26
|
long_description=README,
|
|
27
27
|
long_description_content_type="text/markdown",
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|