NGPIris 5.4.0__tar.gz → 5.4.2.dev1__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.
Files changed (54) hide show
  1. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/cli/__init__.py +1 -1
  2. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/hcp/hcp.py +42 -18
  3. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris.egg-info/PKG-INFO +3 -2
  4. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/PKG-INFO +3 -2
  5. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/pyproject.toml +1 -1
  6. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/LICENSE +0 -0
  7. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/MANIFEST.in +0 -0
  8. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/__init__.py +0 -0
  9. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/hci/__init__.py +0 -0
  10. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/hci/exceptions.py +0 -0
  11. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/hci/hci.py +0 -0
  12. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/hci/helpers.py +0 -0
  13. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/hcp/__init__.py +0 -0
  14. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/hcp/exceptions.py +0 -0
  15. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/hcp/helpers.py +0 -0
  16. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/hcp/statistics.py +0 -0
  17. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/parse_credentials/__init__.py +0 -0
  18. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/parse_credentials/parse_credentials.py +0 -0
  19. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/utils/__init__.py +0 -0
  20. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris/utils/utils.py +0 -0
  21. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris.egg-info/SOURCES.txt +0 -0
  22. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris.egg-info/dependency_links.txt +0 -0
  23. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris.egg-info/entry_points.txt +0 -0
  24. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris.egg-info/requires.txt +0 -0
  25. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/NGPIris.egg-info/top_level.txt +0 -0
  26. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/README.md +0 -0
  27. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/IRIS_5_changelog.md +0 -0
  28. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/Makefile +0 -0
  29. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/NGPIris.cli.rst +0 -0
  30. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/NGPIris.hci.rst +0 -0
  31. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/NGPIris.hcp.rst +0 -0
  32. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/NGPIris.parse_credentials.rst +0 -0
  33. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/NGPIris.rst +0 -0
  34. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/NGPIris.utils.rst +0 -0
  35. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/Tutorial.md +0 -0
  36. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/conf.py +0 -0
  37. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/index.rst +0 -0
  38. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/make.bat +0 -0
  39. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/docs/modules.rst +0 -0
  40. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/setup.cfg +0 -0
  41. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/data/80MB_test_file +0 -0
  42. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/data/a folder of data/80MB_test_file_0 +0 -0
  43. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/data/a folder of data/80MB_test_file_1 +0 -0
  44. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/data/complete_creds_0.json +0 -0
  45. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/data/complete_creds_1.json +0 -0
  46. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/data/complete_creds_2.json +0 -0
  47. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/data/incomplete_creds_0.json +0 -0
  48. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/data/incomplete_creds_1.json +0 -0
  49. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/data/incomplete_creds_2.json +0 -0
  50. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/data/incomplete_creds_3.json +0 -0
  51. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/data/incomplete_creds_4.json +0 -0
  52. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/test_hci.py +0 -0
  53. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/test_hcp.py +0 -0
  54. {ngpiris-5.4.0 → ngpiris-5.4.2.dev1}/tests/test_parse_credentials.py +0 -0
@@ -426,7 +426,7 @@ def iris_generate_credentials_file(path : str, name : str):
426
426
  file_path = path + name
427
427
 
428
428
  if not Path(path).is_dir():
429
- Path(path).mkdir()
429
+ Path(path).mkdir(parents=True)
430
430
  else:
431
431
  file_path = name
432
432
 
@@ -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,7 +40,6 @@ 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
 
47
45
  from typing import Generator
@@ -258,22 +256,33 @@ class HCPHandler:
258
256
  return list_of_buckets
259
257
 
260
258
  @check_mounted
261
- def list_objects(self, path_key : str = "", name_only : bool = False, files_only : bool = False) -> Generator:
259
+ def list_objects(
260
+ self,
261
+ path_key : str = "",
262
+ list_all_bucket_objects : bool = False,
263
+ name_only : bool = False,
264
+ files_only : bool = False
265
+ ) -> Generator:
262
266
  """
263
267
  List all objects in the mounted bucket as a generator. If one wishes to
264
268
  get the result as a list, use :py:function:`list` to type cast the generator
265
269
 
266
270
  :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
271
  :type path_key: str, optional
272
+ :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
273
+ :type list_all_bucket_objects: bool, optional
268
274
  :param name_only: If True, yield only a the object names. If False, yield the full metadata about each object. Defaults to False.
269
275
  :type name_only: bool, optional
270
- :param files_only: If true, only yield file objects. Defaults to False
276
+ :param files_only: If True, only yield file objects. Defaults to False
271
277
  :type files_only: bool, optional
272
278
  :yield: A generator of all objects in specified folder in a bucket
273
279
  :rtype: Generator
274
280
  """
275
281
  paginator : Paginator = self.s3_client.get_paginator("list_objects_v2")
276
- pages : PageIterator = paginator.paginate(Bucket = self.bucket_name, Prefix = path_key, Delimiter = "/")
282
+ if list_all_bucket_objects:
283
+ pages : PageIterator = paginator.paginate(Bucket = self.bucket_name)
284
+ else:
285
+ pages : PageIterator = paginator.paginate(Bucket = self.bucket_name, Prefix = path_key, Delimiter = "/")
277
286
 
278
287
  for page in pages:
279
288
  page : dict | None
@@ -440,10 +449,18 @@ class HCPHandler:
440
449
  raise ObjectDoesNotExist("Could not find object", "\"" + folder_key + "\"", "in bucket", "\"" + str(self.bucket_name) + "\"")
441
450
  if Path(local_folder_path).is_dir():
442
451
  current_download_size_in_bytes = Byte(0) # For tracking download limit
443
- for object in self.list_objects(folder_key): # Build the tree with directories or add files
452
+ (Path(local_folder_path) / Path(folder_key)).mkdir(parents = True) # Create "base folder"
453
+ for object in self.list_objects(folder_key): # Build the tree with directories or add files:
444
454
  p = Path(local_folder_path) / Path(object["Key"])
445
- if object["Key"][-1] == "/": # If the object is a "folder"
446
- p.mkdir()
455
+ if not object["IsFile"]: # If the object is a "folder"
456
+ p.mkdir(parents = True)
457
+ self.download_folder(
458
+ folder_key = str(object["Key"]),
459
+ local_folder_path = local_folder_path,
460
+ use_download_limit = use_download_limit,
461
+ show_progress_bar = show_progress_bar,
462
+ download_limit_in_bytes = download_limit_in_bytes - current_download_size_in_bytes
463
+ )
447
464
  else: # If the object is a file
448
465
  current_download_size_in_bytes += Byte(object["Size"])
449
466
  if current_download_size_in_bytes >= download_limit_in_bytes and use_download_limit:
@@ -490,20 +507,26 @@ class HCPHandler:
490
507
  unit_scale = True,
491
508
  desc = local_file_path
492
509
  ) as pbar:
510
+ try:
511
+ self.s3_client.upload_file(
512
+ Filename = local_file_path,
513
+ Bucket = self.bucket_name,
514
+ Key = key,
515
+ Config = self.transfer_config,
516
+ Callback = lambda bytes_transferred : pbar.update(bytes_transferred)
517
+ )
518
+ except Exception as e:
519
+ print("Upload failed:", e)
520
+ else:
521
+ try:
493
522
  self.s3_client.upload_file(
494
523
  Filename = local_file_path,
495
524
  Bucket = self.bucket_name,
496
525
  Key = key,
497
526
  Config = self.transfer_config,
498
- Callback = lambda bytes_transferred : pbar.update(bytes_transferred)
499
527
  )
500
- else:
501
- self.s3_client.upload_file(
502
- Filename = local_file_path,
503
- Bucket = self.bucket_name,
504
- Key = key,
505
- Config = self.transfer_config,
506
- )
528
+ except Exception as e:
529
+ print("Upload failed:", e)
507
530
 
508
531
 
509
532
  @check_mounted
@@ -586,6 +609,7 @@ class HCPHandler:
586
609
  key += "/"
587
610
 
588
611
  objects : list[str] = list(self.list_objects(key, name_only = True))
612
+ objects.append(key) # Include the object "folder" path to be deleted
589
613
 
590
614
  if not objects:
591
615
  raise RuntimeError("\"" + key + "\"" + " is not a valid path") #TODO: change this error
@@ -653,11 +677,11 @@ class HCPHandler:
653
677
  processor = utils.default_process
654
678
 
655
679
  if not name_only:
656
- full_list = list(self.list_objects())
680
+ full_list = list(self.list_objects(list_all_bucket_objects = True))
657
681
 
658
682
  for item, score, index in process.extract_iter(
659
683
  search_string,
660
- self.list_objects(name_only = True),
684
+ self.list_objects(list_all_bucket_objects = True, name_only = True),
661
685
  scorer = fuzz.partial_ratio,
662
686
  processor = processor
663
687
  ):
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: NGPIris
3
- Version: 5.4.0
3
+ Version: 5.4.2.dev1
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.2
1
+ Metadata-Version: 2.4
2
2
  Name: NGPIris
3
- Version: 5.4.0
3
+ Version: 5.4.2.dev1
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
1
  [project]
2
2
  name = "NGPIris"
3
- version = "5.4.0"
3
+ version = "5.4.2.dev1"
4
4
  readme = "README.md"
5
5
  dependencies = [
6
6
  "requests >= 2.31.0",
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