NGPIris 5.4.0__tar.gz → 5.4.2__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.
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/cli/__init__.py +46 -8
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/hcp/hcp.py +75 -17
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris.egg-info/PKG-INFO +3 -2
- {ngpiris-5.4.0 → ngpiris-5.4.2}/PKG-INFO +3 -2
- {ngpiris-5.4.0 → ngpiris-5.4.2}/pyproject.toml +1 -1
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/test_hcp.py +12 -5
- {ngpiris-5.4.0 → ngpiris-5.4.2}/LICENSE +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/MANIFEST.in +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/__init__.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/hci/__init__.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/hci/exceptions.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/hci/hci.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/hci/helpers.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/hcp/__init__.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/hcp/exceptions.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/hcp/helpers.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/hcp/statistics.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/parse_credentials/__init__.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/parse_credentials/parse_credentials.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/utils/__init__.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris/utils/utils.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris.egg-info/SOURCES.txt +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris.egg-info/dependency_links.txt +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris.egg-info/entry_points.txt +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris.egg-info/requires.txt +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/NGPIris.egg-info/top_level.txt +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/README.md +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/IRIS_5_changelog.md +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/Makefile +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/NGPIris.cli.rst +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/NGPIris.hci.rst +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/NGPIris.hcp.rst +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/NGPIris.parse_credentials.rst +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/NGPIris.rst +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/NGPIris.utils.rst +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/Tutorial.md +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/conf.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/index.rst +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/make.bat +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/docs/modules.rst +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/setup.cfg +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/data/80MB_test_file +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/data/a folder of data/80MB_test_file_0 +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/data/a folder of data/80MB_test_file_1 +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/data/complete_creds_0.json +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/data/complete_creds_1.json +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/data/complete_creds_2.json +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/data/incomplete_creds_0.json +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/data/incomplete_creds_1.json +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/data/incomplete_creds_2.json +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/data/incomplete_creds_3.json +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/data/incomplete_creds_4.json +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/test_hci.py +0 -0
- {ngpiris-5.4.0 → ngpiris-5.4.2}/tests/test_parse_credentials.py +0 -0
|
@@ -6,6 +6,7 @@ from pathlib import Path
|
|
|
6
6
|
from boto3 import set_stream_logger
|
|
7
7
|
from typing import Any, Generator
|
|
8
8
|
from bitmath import Byte, TiB
|
|
9
|
+
import sys
|
|
9
10
|
|
|
10
11
|
from NGPIris.hcp import HCPHandler
|
|
11
12
|
|
|
@@ -41,19 +42,32 @@ def add_trailing_slash(path : str) -> str:
|
|
|
41
42
|
help = "Get the debug log for running a command",
|
|
42
43
|
is_flag = True
|
|
43
44
|
)
|
|
45
|
+
@click.option(
|
|
46
|
+
"-tc",
|
|
47
|
+
"--transfer_config",
|
|
48
|
+
help = "Use a custom transfer config for uploads or downloads",
|
|
49
|
+
)
|
|
44
50
|
@click.version_option(package_name = "NGPIris")
|
|
45
51
|
@click.pass_context
|
|
46
|
-
def cli(context : Context, credentials : str, debug : bool):
|
|
52
|
+
def cli(context : Context, credentials : str, debug : bool, transfer_config : str):
|
|
47
53
|
"""
|
|
48
54
|
NGP Intelligence and Repository Interface Software, IRIS.
|
|
49
55
|
|
|
50
56
|
CREDENTIALS refers to the path to the JSON credentials file.
|
|
51
57
|
"""
|
|
58
|
+
|
|
59
|
+
if transfer_config:
|
|
60
|
+
context.ensure_object(dict)
|
|
61
|
+
context.obj["hcph"] = HCPHandler(credentials, custom_config_path = transfer_config)
|
|
62
|
+
else:
|
|
63
|
+
context.ensure_object(dict)
|
|
64
|
+
context.obj["hcph"] = HCPHandler(credentials)
|
|
65
|
+
|
|
52
66
|
if debug:
|
|
53
67
|
set_stream_logger(name="")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
68
|
+
click.echo(
|
|
69
|
+
context.obj["hcph"].transfer_config.__dict__
|
|
70
|
+
)
|
|
57
71
|
|
|
58
72
|
@cli.command()
|
|
59
73
|
@click.argument("bucket")
|
|
@@ -65,8 +79,25 @@ def cli(context : Context, credentials : str, debug : bool):
|
|
|
65
79
|
help = "Simulate the command execution without making actual changes. Useful for testing and verification",
|
|
66
80
|
is_flag = True
|
|
67
81
|
)
|
|
82
|
+
@click.option(
|
|
83
|
+
"-um",
|
|
84
|
+
"--upload_mode",
|
|
85
|
+
help = "Choose an upload method. Default upload mode is STANDARD which uses a basic multipart upload. Use another mode than STANDARD if that mode misbehaves",
|
|
86
|
+
type = click.Choice(
|
|
87
|
+
["STANDARD", "SIMPLE", "EQUAL_PARTS"],
|
|
88
|
+
case_sensitive = False
|
|
89
|
+
),
|
|
90
|
+
default = "STANDARD"
|
|
91
|
+
)
|
|
92
|
+
@click.option(
|
|
93
|
+
"-ep",
|
|
94
|
+
"--equal_parts",
|
|
95
|
+
help = "Supplementary option when using the EQUAL_PARTS upload mode. Splits each file into a given number of parts. Must be a positive integer",
|
|
96
|
+
type = int,
|
|
97
|
+
default = 5
|
|
98
|
+
)
|
|
68
99
|
@click.pass_context
|
|
69
|
-
def upload(context : Context, bucket : str, source : str, destination : str, dry_run : bool):
|
|
100
|
+
def upload(context : Context, bucket : str, source : str, destination : str, dry_run : bool, upload_mode : str, equal_parts : int):
|
|
70
101
|
"""
|
|
71
102
|
Upload files to an HCP bucket/namespace.
|
|
72
103
|
|
|
@@ -76,6 +107,13 @@ def upload(context : Context, bucket : str, source : str, destination : str, dry
|
|
|
76
107
|
|
|
77
108
|
DESTINATION is the destination path on the HCP.
|
|
78
109
|
"""
|
|
110
|
+
|
|
111
|
+
if equal_parts <= 0:
|
|
112
|
+
click.echo("Error: --equal_parts value must be a positive integer", err=True)
|
|
113
|
+
sys.exit(1)
|
|
114
|
+
|
|
115
|
+
upload_mode_choice = HCPHandler.UploadMode(upload_mode.lower())
|
|
116
|
+
|
|
79
117
|
hcph : HCPHandler = get_HCPHandler(context)
|
|
80
118
|
hcph.mount_bucket(bucket)
|
|
81
119
|
destination = add_trailing_slash(destination)
|
|
@@ -84,14 +122,14 @@ def upload(context : Context, bucket : str, source : str, destination : str, dry
|
|
|
84
122
|
if dry_run:
|
|
85
123
|
click.echo("This command would have uploaded the folder \"" + source + "\" to \"" + destination + "\"")
|
|
86
124
|
else:
|
|
87
|
-
hcph.upload_folder(source, destination)
|
|
125
|
+
hcph.upload_folder(source, destination, upload_mode = upload_mode_choice, equal_parts = equal_parts)
|
|
88
126
|
else:
|
|
89
127
|
file_name = Path(source).name
|
|
90
128
|
destination += file_name
|
|
91
129
|
if dry_run:
|
|
92
130
|
click.echo("This command would have uploaded the file \"" + source + "\" to \"" + destination + "\"")
|
|
93
131
|
else:
|
|
94
|
-
hcph.upload_file(source, destination)
|
|
132
|
+
hcph.upload_file(source, destination, upload_mode = upload_mode_choice, equal_parts = equal_parts)
|
|
95
133
|
|
|
96
134
|
@cli.command()
|
|
97
135
|
@click.argument("bucket")
|
|
@@ -426,7 +464,7 @@ def iris_generate_credentials_file(path : str, name : str):
|
|
|
426
464
|
file_path = path + name
|
|
427
465
|
|
|
428
466
|
if not Path(path).is_dir():
|
|
429
|
-
Path(path).mkdir()
|
|
467
|
+
Path(path).mkdir(parents=True)
|
|
430
468
|
else:
|
|
431
469
|
file_path = name
|
|
432
470
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
from NGPIris.parse_credentials import CredentialsHandler
|
|
3
2
|
from NGPIris.hcp.helpers import (
|
|
4
3
|
raise_path_error,
|
|
@@ -41,9 +40,9 @@ from rapidfuzz import (
|
|
|
41
40
|
from requests import get
|
|
42
41
|
from urllib3 import disable_warnings
|
|
43
42
|
from tqdm import tqdm
|
|
44
|
-
|
|
45
43
|
from bitmath import TiB, Byte
|
|
46
44
|
|
|
45
|
+
from enum import Enum
|
|
47
46
|
from typing import Generator
|
|
48
47
|
|
|
49
48
|
_KB = 1024
|
|
@@ -258,22 +257,33 @@ class HCPHandler:
|
|
|
258
257
|
return list_of_buckets
|
|
259
258
|
|
|
260
259
|
@check_mounted
|
|
261
|
-
def list_objects(
|
|
260
|
+
def list_objects(
|
|
261
|
+
self,
|
|
262
|
+
path_key : str = "",
|
|
263
|
+
list_all_bucket_objects : bool = False,
|
|
264
|
+
name_only : bool = False,
|
|
265
|
+
files_only : bool = False
|
|
266
|
+
) -> Generator:
|
|
262
267
|
"""
|
|
263
268
|
List all objects in the mounted bucket as a generator. If one wishes to
|
|
264
269
|
get the result as a list, use :py:function:`list` to type cast the generator
|
|
265
270
|
|
|
266
271
|
:param path_key: Filter string for which keys to list, specifically for finding objects in certain folders. Defaults to \"the root\" of the bucket
|
|
267
272
|
:type path_key: str, optional
|
|
273
|
+
:param list_all_bucket_objects: If True, the value of `path_key` will be ignored and instead will list all objects in the bucket. Defaults to False
|
|
274
|
+
:type list_all_bucket_objects: bool, optional
|
|
268
275
|
:param name_only: If True, yield only a the object names. If False, yield the full metadata about each object. Defaults to False.
|
|
269
276
|
:type name_only: bool, optional
|
|
270
|
-
:param files_only: If
|
|
277
|
+
:param files_only: If True, only yield file objects. Defaults to False
|
|
271
278
|
:type files_only: bool, optional
|
|
272
279
|
:yield: A generator of all objects in specified folder in a bucket
|
|
273
280
|
:rtype: Generator
|
|
274
281
|
"""
|
|
275
282
|
paginator : Paginator = self.s3_client.get_paginator("list_objects_v2")
|
|
276
|
-
|
|
283
|
+
if list_all_bucket_objects:
|
|
284
|
+
pages : PageIterator = paginator.paginate(Bucket = self.bucket_name)
|
|
285
|
+
else:
|
|
286
|
+
pages : PageIterator = paginator.paginate(Bucket = self.bucket_name, Prefix = path_key, Delimiter = "/")
|
|
277
287
|
|
|
278
288
|
for page in pages:
|
|
279
289
|
page : dict | None
|
|
@@ -440,10 +450,18 @@ class HCPHandler:
|
|
|
440
450
|
raise ObjectDoesNotExist("Could not find object", "\"" + folder_key + "\"", "in bucket", "\"" + str(self.bucket_name) + "\"")
|
|
441
451
|
if Path(local_folder_path).is_dir():
|
|
442
452
|
current_download_size_in_bytes = Byte(0) # For tracking download limit
|
|
443
|
-
|
|
453
|
+
(Path(local_folder_path) / Path(folder_key)).mkdir(parents = True) # Create "base folder"
|
|
454
|
+
for object in self.list_objects(folder_key): # Build the tree with directories or add files:
|
|
444
455
|
p = Path(local_folder_path) / Path(object["Key"])
|
|
445
|
-
if object["
|
|
446
|
-
p.mkdir()
|
|
456
|
+
if not object["IsFile"]: # If the object is a "folder"
|
|
457
|
+
p.mkdir(parents = True)
|
|
458
|
+
self.download_folder(
|
|
459
|
+
folder_key = str(object["Key"]),
|
|
460
|
+
local_folder_path = local_folder_path,
|
|
461
|
+
use_download_limit = use_download_limit,
|
|
462
|
+
show_progress_bar = show_progress_bar,
|
|
463
|
+
download_limit_in_bytes = download_limit_in_bytes - current_download_size_in_bytes
|
|
464
|
+
)
|
|
447
465
|
else: # If the object is a file
|
|
448
466
|
current_download_size_in_bytes += Byte(object["Size"])
|
|
449
467
|
if current_download_size_in_bytes >= download_limit_in_bytes and use_download_limit:
|
|
@@ -451,9 +469,14 @@ class HCPHandler:
|
|
|
451
469
|
self.download_file(object["Key"], p.as_posix(), show_progress_bar = show_progress_bar)
|
|
452
470
|
else:
|
|
453
471
|
raise NotADirectory(local_folder_path + " is not a directory")
|
|
472
|
+
|
|
473
|
+
class UploadMode(Enum):
|
|
474
|
+
STANDARD = "standard"
|
|
475
|
+
SIMPLE = "simple"
|
|
476
|
+
EQUAL_PARTS = "equal_parts"
|
|
454
477
|
|
|
455
478
|
@check_mounted
|
|
456
|
-
def upload_file(self, local_file_path : str, key : str = "", show_progress_bar : bool = True) -> None:
|
|
479
|
+
def upload_file(self, local_file_path : str, key : str = "", show_progress_bar : bool = True, upload_mode : UploadMode = UploadMode.STANDARD, equal_parts : int = 5) -> None:
|
|
457
480
|
"""
|
|
458
481
|
Upload one file to the mounted bucket
|
|
459
482
|
|
|
@@ -466,6 +489,16 @@ class HCPHandler:
|
|
|
466
489
|
:param show_progress_bar: Boolean choice of displaying a progress bar. Defaults to True
|
|
467
490
|
:type show_progress_bar: bool, optional
|
|
468
491
|
|
|
492
|
+
:param upload_mode:
|
|
493
|
+
The upload mode of the transfer is any of the following:
|
|
494
|
+
HCPHandler.UploadMode.STANDARD,
|
|
495
|
+
HCPHandler.UploadMode.SIMPLE,
|
|
496
|
+
HCPHandler.UploadMode.EQUAL_PARTS\n
|
|
497
|
+
:type upload_mode: UploadMode, optional
|
|
498
|
+
|
|
499
|
+
:param equal_parts: The number of equal parts that each file should be divided into when using the HCPHandler.UploadMode.EQUAL_PARTS mode. Default is 5
|
|
500
|
+
:type equal_parts: int, optional
|
|
501
|
+
|
|
469
502
|
:raises RuntimeError: If the \"\\\" is used in the file path
|
|
470
503
|
|
|
471
504
|
:raises ObjectAlreadyExist: If the object already exist on the mounted bucket
|
|
@@ -482,8 +515,17 @@ class HCPHandler:
|
|
|
482
515
|
if self.object_exists(key):
|
|
483
516
|
raise ObjectAlreadyExist("The object \"" + key + "\" already exist in the mounted bucket")
|
|
484
517
|
else:
|
|
518
|
+
file_size : int = stat(local_file_path).st_size
|
|
519
|
+
|
|
520
|
+
match upload_mode:
|
|
521
|
+
case HCPHandler.UploadMode.STANDARD:
|
|
522
|
+
config = self.transfer_config
|
|
523
|
+
case HCPHandler.UploadMode.SIMPLE:
|
|
524
|
+
config = TransferConfig(multipart_chunksize = file_size)
|
|
525
|
+
case HCPHandler.UploadMode.EQUAL_PARTS:
|
|
526
|
+
config = TransferConfig(multipart_chunksize = round(file_size / equal_parts))
|
|
527
|
+
|
|
485
528
|
if show_progress_bar:
|
|
486
|
-
file_size : int = stat(local_file_path).st_size
|
|
487
529
|
with tqdm(
|
|
488
530
|
total = file_size,
|
|
489
531
|
unit = "B",
|
|
@@ -494,7 +536,7 @@ class HCPHandler:
|
|
|
494
536
|
Filename = local_file_path,
|
|
495
537
|
Bucket = self.bucket_name,
|
|
496
538
|
Key = key,
|
|
497
|
-
Config =
|
|
539
|
+
Config = config,
|
|
498
540
|
Callback = lambda bytes_transferred : pbar.update(bytes_transferred)
|
|
499
541
|
)
|
|
500
542
|
else:
|
|
@@ -502,12 +544,11 @@ class HCPHandler:
|
|
|
502
544
|
Filename = local_file_path,
|
|
503
545
|
Bucket = self.bucket_name,
|
|
504
546
|
Key = key,
|
|
505
|
-
Config =
|
|
547
|
+
Config = config,
|
|
506
548
|
)
|
|
507
549
|
|
|
508
|
-
|
|
509
550
|
@check_mounted
|
|
510
|
-
def upload_folder(self, local_folder_path : str, key : str = "", show_progress_bar : bool = True) -> None:
|
|
551
|
+
def upload_folder(self, local_folder_path : str, key : str = "", show_progress_bar : bool = True, upload_mode : UploadMode = UploadMode.STANDARD, equal_parts : int = 5) -> None:
|
|
511
552
|
"""
|
|
512
553
|
Upload the contents of a folder to the mounted bucket
|
|
513
554
|
|
|
@@ -519,6 +560,16 @@ class HCPHandler:
|
|
|
519
560
|
|
|
520
561
|
:param show_progress_bar: Boolean choice of displaying a progress bar. Defaults to True
|
|
521
562
|
:type show_progress_bar: bool, optional
|
|
563
|
+
|
|
564
|
+
:param upload_mode:
|
|
565
|
+
The upload mode of the transfer is any of the following:
|
|
566
|
+
HCPHandler.UploadMode.STANDARD,
|
|
567
|
+
HCPHandler.UploadMode.SIMPLE,
|
|
568
|
+
HCPHandler.UploadMode.EQUAL_PARTS\n
|
|
569
|
+
:type upload_mode: UploadMode, optional
|
|
570
|
+
|
|
571
|
+
:param equal_parts: The number of equal parts that each file should be divided into when using the HCPHandler.UploadMode.EQUAL_PARTS mode. Default is 5
|
|
572
|
+
:type equal_parts: int, optional
|
|
522
573
|
"""
|
|
523
574
|
raise_path_error(local_folder_path)
|
|
524
575
|
|
|
@@ -527,7 +578,13 @@ class HCPHandler:
|
|
|
527
578
|
filenames = listdir(local_folder_path)
|
|
528
579
|
|
|
529
580
|
for filename in filenames:
|
|
530
|
-
self.upload_file(
|
|
581
|
+
self.upload_file(
|
|
582
|
+
local_folder_path + filename,
|
|
583
|
+
key + filename,
|
|
584
|
+
show_progress_bar = show_progress_bar,
|
|
585
|
+
upload_mode = upload_mode,
|
|
586
|
+
equal_parts = equal_parts
|
|
587
|
+
)
|
|
531
588
|
|
|
532
589
|
@check_mounted
|
|
533
590
|
def delete_objects(self, keys : list[str], verbose : bool = True) -> None:
|
|
@@ -586,6 +643,7 @@ class HCPHandler:
|
|
|
586
643
|
key += "/"
|
|
587
644
|
|
|
588
645
|
objects : list[str] = list(self.list_objects(key, name_only = True))
|
|
646
|
+
objects.append(key) # Include the object "folder" path to be deleted
|
|
589
647
|
|
|
590
648
|
if not objects:
|
|
591
649
|
raise RuntimeError("\"" + key + "\"" + " is not a valid path") #TODO: change this error
|
|
@@ -653,11 +711,11 @@ class HCPHandler:
|
|
|
653
711
|
processor = utils.default_process
|
|
654
712
|
|
|
655
713
|
if not name_only:
|
|
656
|
-
full_list = list(self.list_objects())
|
|
714
|
+
full_list = list(self.list_objects(list_all_bucket_objects = True))
|
|
657
715
|
|
|
658
716
|
for item, score, index in process.extract_iter(
|
|
659
717
|
search_string,
|
|
660
|
-
self.list_objects(name_only = True),
|
|
718
|
+
self.list_objects(list_all_bucket_objects = True, name_only = True),
|
|
661
719
|
scorer = fuzz.partial_ratio,
|
|
662
720
|
processor = processor
|
|
663
721
|
):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: NGPIris
|
|
3
|
-
Version: 5.4.
|
|
3
|
+
Version: 5.4.2
|
|
4
4
|
Author-email: Erik Brink <erik.brink@gu.se>, Isak Sylvin <isak.sylvin@gu.se>
|
|
5
5
|
Description-Content-Type: text/markdown
|
|
6
6
|
License-File: LICENSE
|
|
@@ -13,6 +13,7 @@ Requires-Dist: tqdm>=4.66.2
|
|
|
13
13
|
Requires-Dist: click>=8.1.7
|
|
14
14
|
Requires-Dist: bitmath==1.3.3.1
|
|
15
15
|
Requires-Dist: tabulate==0.9.0
|
|
16
|
+
Dynamic: license-file
|
|
16
17
|
|
|
17
18
|
# NGP IRIS 👀
|
|
18
19
|
NGP IRIS, or just Iris, is a tool for interacting with a Hitachi Content Platform (HCP) using S3 in the `boto3` package. NGP Iris is designed with two use cases in mind:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: NGPIris
|
|
3
|
-
Version: 5.4.
|
|
3
|
+
Version: 5.4.2
|
|
4
4
|
Author-email: Erik Brink <erik.brink@gu.se>, Isak Sylvin <isak.sylvin@gu.se>
|
|
5
5
|
Description-Content-Type: text/markdown
|
|
6
6
|
License-File: LICENSE
|
|
@@ -13,6 +13,7 @@ Requires-Dist: tqdm>=4.66.2
|
|
|
13
13
|
Requires-Dist: click>=8.1.7
|
|
14
14
|
Requires-Dist: bitmath==1.3.3.1
|
|
15
15
|
Requires-Dist: tabulate==0.9.0
|
|
16
|
+
Dynamic: license-file
|
|
16
17
|
|
|
17
18
|
# NGP IRIS 👀
|
|
18
19
|
NGP IRIS, or just Iris, is a tool for interacting with a Hitachi Content Platform (HCP) using S3 in the `boto3` package. NGP Iris is designed with two use cases in mind:
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
2
|
from pathlib import Path
|
|
4
3
|
from filecmp import cmp
|
|
5
4
|
from typing import Any, Callable
|
|
6
|
-
|
|
7
5
|
from conftest import CustomConfig
|
|
8
|
-
|
|
9
6
|
from NGPIris.hcp import HCPHandler
|
|
7
|
+
from icecream import ic
|
|
10
8
|
|
|
11
9
|
# --------------------------- Helper fucntions ---------------------------------
|
|
12
10
|
|
|
@@ -70,6 +68,15 @@ def test_upload_file(custom_config : CustomConfig) -> None:
|
|
|
70
68
|
show_progress_bar = False
|
|
71
69
|
)
|
|
72
70
|
|
|
71
|
+
# Test every upload mode
|
|
72
|
+
for mode in HCPHandler.UploadMode:
|
|
73
|
+
ic(mode, custom_config.test_file_path + "_" + str(mode).replace(".", "_"))
|
|
74
|
+
custom_config.hcp_h.upload_file(
|
|
75
|
+
custom_config.test_file_path,
|
|
76
|
+
custom_config.test_file_path + "_" + str(mode).replace(".", "_"),
|
|
77
|
+
upload_mode = mode
|
|
78
|
+
)
|
|
79
|
+
|
|
73
80
|
def test_upload_file_without_mounting(custom_config : CustomConfig) -> None:
|
|
74
81
|
_hcp_h = custom_config.hcp_h
|
|
75
82
|
_without_mounting(_hcp_h, HCPHandler.upload_file)
|
|
@@ -119,8 +126,6 @@ def test_get_file_in_sub_directory(custom_config : CustomConfig) -> None:
|
|
|
119
126
|
assert custom_config.hcp_h.object_exists(custom_config.test_file_path)
|
|
120
127
|
assert custom_config.hcp_h.get_object(custom_config.test_file_path)
|
|
121
128
|
|
|
122
|
-
from icecream import ic
|
|
123
|
-
|
|
124
129
|
def test_download_file(custom_config : CustomConfig) -> None:
|
|
125
130
|
test_mount_bucket(custom_config)
|
|
126
131
|
Path(custom_config.result_path).mkdir()
|
|
@@ -215,6 +220,8 @@ def test_delete_file(custom_config : CustomConfig) -> None:
|
|
|
215
220
|
test_mount_bucket(custom_config)
|
|
216
221
|
custom_config.hcp_h.delete_object(custom_config.test_file_path)
|
|
217
222
|
custom_config.hcp_h.delete_object(custom_config.test_file_path + "_no_progress_bar")
|
|
223
|
+
for mode in HCPHandler.UploadMode:
|
|
224
|
+
custom_config.hcp_h.delete_object(custom_config.test_file_path + "_" + str(mode).replace(".", "_"))
|
|
218
225
|
custom_config.hcp_h.delete_object("a_sub_directory/a_file")
|
|
219
226
|
custom_config.hcp_h.delete_object("a_sub_directory")
|
|
220
227
|
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|