NGPIris 5.4.2.dev5__tar.gz → 5.4.2.dev7__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.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/cli/__init__.py +24 -7
  2. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/hcp/hcp.py +49 -29
  3. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7/NGPIris.egg-info}/PKG-INFO +2 -2
  4. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris.egg-info/requires.txt +1 -1
  5. {ngpiris-5.4.2.dev5/NGPIris.egg-info → ngpiris-5.4.2.dev7}/PKG-INFO +2 -2
  6. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/pyproject.toml +2 -2
  7. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/test_hcp.py +12 -5
  8. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/LICENSE +0 -0
  9. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/MANIFEST.in +0 -0
  10. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/__init__.py +0 -0
  11. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/hci/__init__.py +0 -0
  12. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/hci/exceptions.py +0 -0
  13. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/hci/hci.py +0 -0
  14. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/hci/helpers.py +0 -0
  15. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/hcp/__init__.py +0 -0
  16. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/hcp/exceptions.py +0 -0
  17. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/hcp/helpers.py +0 -0
  18. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/hcp/statistics.py +0 -0
  19. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/parse_credentials/__init__.py +0 -0
  20. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/parse_credentials/parse_credentials.py +0 -0
  21. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/utils/__init__.py +0 -0
  22. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris/utils/utils.py +0 -0
  23. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris.egg-info/SOURCES.txt +0 -0
  24. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris.egg-info/dependency_links.txt +0 -0
  25. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris.egg-info/entry_points.txt +0 -0
  26. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/NGPIris.egg-info/top_level.txt +0 -0
  27. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/README.md +0 -0
  28. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/IRIS_5_changelog.md +0 -0
  29. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/Makefile +0 -0
  30. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/NGPIris.cli.rst +0 -0
  31. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/NGPIris.hci.rst +0 -0
  32. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/NGPIris.hcp.rst +0 -0
  33. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/NGPIris.parse_credentials.rst +0 -0
  34. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/NGPIris.rst +0 -0
  35. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/NGPIris.utils.rst +0 -0
  36. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/Tutorial.md +0 -0
  37. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/conf.py +0 -0
  38. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/index.rst +0 -0
  39. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/make.bat +0 -0
  40. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/docs/modules.rst +0 -0
  41. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/setup.cfg +0 -0
  42. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/data/80MB_test_file +0 -0
  43. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/data/a folder of data/80MB_test_file_0 +0 -0
  44. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/data/a folder of data/80MB_test_file_1 +0 -0
  45. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/data/complete_creds_0.json +0 -0
  46. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/data/complete_creds_1.json +0 -0
  47. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/data/complete_creds_2.json +0 -0
  48. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/data/incomplete_creds_0.json +0 -0
  49. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/data/incomplete_creds_1.json +0 -0
  50. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/data/incomplete_creds_2.json +0 -0
  51. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/data/incomplete_creds_3.json +0 -0
  52. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/data/incomplete_creds_4.json +0 -0
  53. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/test_hci.py +0 -0
  54. {ngpiris-5.4.2.dev5 → ngpiris-5.4.2.dev7}/tests/test_parse_credentials.py +0 -0
@@ -79,13 +79,24 @@ def cli(context : Context, credentials : str, debug : bool, transfer_config : st
79
79
  is_flag = True
80
80
  )
81
81
  @click.option(
82
- "-su",
83
- "--simple_upload",
84
- help = "Use an upload method that does not use mulitpart. Usefull for times when multipart upload misbehaves",
85
- is_flag = True
82
+ "-um",
83
+ "--upload_mode",
84
+ 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",
85
+ type = click.Choice(
86
+ ["STANDARD", "SIMPLE", "EQUAL_PARTS"],
87
+ case_sensitive = False
88
+ ),
89
+ default = "STANDARD"
90
+ )
91
+ @click.option(
92
+ "-ep",
93
+ "--equal_parts",
94
+ help = "Supplementary option when using the EQUAL_PARTS upload mode. Splits each file into a given number of parts. Must be a positive integer",
95
+ type = int,
96
+ default = 5
86
97
  )
87
98
  @click.pass_context
88
- def upload(context : Context, bucket : str, source : str, destination : str, dry_run : bool, simple_upload : bool):
99
+ def upload(context : Context, bucket : str, source : str, destination : str, dry_run : bool, upload_mode : str, equal_parts : int):
89
100
  """
90
101
  Upload files to an HCP bucket/namespace.
91
102
 
@@ -95,6 +106,12 @@ def upload(context : Context, bucket : str, source : str, destination : str, dry
95
106
 
96
107
  DESTINATION is the destination path on the HCP.
97
108
  """
109
+
110
+ if equal_parts <= 0:
111
+ exit("Error: --equal_parts value must be a positive integer")
112
+
113
+ upload_mode_choice = HCPHandler.UploadMode(upload_mode.lower())
114
+
98
115
  hcph : HCPHandler = get_HCPHandler(context)
99
116
  hcph.mount_bucket(bucket)
100
117
  destination = add_trailing_slash(destination)
@@ -103,14 +120,14 @@ def upload(context : Context, bucket : str, source : str, destination : str, dry
103
120
  if dry_run:
104
121
  click.echo("This command would have uploaded the folder \"" + source + "\" to \"" + destination + "\"")
105
122
  else:
106
- hcph.upload_folder(source, destination, use_simple_upload = simple_upload)
123
+ hcph.upload_folder(source, destination, upload_mode = upload_mode_choice, equal_parts = equal_parts)
107
124
  else:
108
125
  file_name = Path(source).name
109
126
  destination += file_name
110
127
  if dry_run:
111
128
  click.echo("This command would have uploaded the file \"" + source + "\" to \"" + destination + "\"")
112
129
  else:
113
- hcph.upload_file(source, destination, use_simple_upload = simple_upload)
130
+ hcph.upload_file(source, destination, upload_mode = upload_mode_choice, equal_parts = equal_parts)
114
131
 
115
132
  @cli.command()
116
133
  @click.argument("bucket")
@@ -42,6 +42,7 @@ from urllib3 import disable_warnings
42
42
  from tqdm import tqdm
43
43
  from bitmath import TiB, Byte
44
44
 
45
+ from enum import Enum
45
46
  from typing import Generator
46
47
 
47
48
  _KB = 1024
@@ -468,9 +469,14 @@ class HCPHandler:
468
469
  self.download_file(object["Key"], p.as_posix(), show_progress_bar = show_progress_bar)
469
470
  else:
470
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"
471
477
 
472
478
  @check_mounted
473
- def upload_file(self, local_file_path : str, key : str = "", show_progress_bar : bool = True, use_simple_upload : bool = False) -> 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:
474
480
  """
475
481
  Upload one file to the mounted bucket
476
482
 
@@ -483,6 +489,16 @@ class HCPHandler:
483
489
  :param show_progress_bar: Boolean choice of displaying a progress bar. Defaults to True
484
490
  :type show_progress_bar: bool, optional
485
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
+
486
502
  :raises RuntimeError: If the \"\\\" is used in the file path
487
503
 
488
504
  :raises ObjectAlreadyExist: If the object already exist on the mounted bucket
@@ -499,47 +515,40 @@ class HCPHandler:
499
515
  if self.object_exists(key):
500
516
  raise ObjectAlreadyExist("The object \"" + key + "\" already exist in the mounted bucket")
501
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
+
502
528
  if show_progress_bar:
503
- file_size : int = stat(local_file_path).st_size
504
529
  with tqdm(
505
530
  total = file_size,
506
531
  unit = "B",
507
532
  unit_scale = True,
508
533
  desc = local_file_path
509
534
  ) as pbar:
510
- if use_simple_upload:
511
- self.s3_client.upload_file(
512
- Filename = local_file_path,
513
- Bucket = self.bucket_name,
514
- Key = key,
515
- Config = TransferConfig(multipart_chunksize = file_size),
516
- Callback = lambda bytes_transferred : pbar.update(bytes_transferred)
517
- )
518
- else:
519
- self.s3_client.upload_file(
520
- Filename = local_file_path,
521
- Bucket = self.bucket_name,
522
- Key = key,
523
- Config = self.transfer_config,
524
- Callback = lambda bytes_transferred : pbar.update(bytes_transferred)
525
- )
526
- else:
527
- if use_simple_upload:
528
535
  self.s3_client.upload_file(
529
536
  Filename = local_file_path,
530
537
  Bucket = self.bucket_name,
531
538
  Key = key,
539
+ Config = config,
540
+ Callback = lambda bytes_transferred : pbar.update(bytes_transferred)
532
541
  )
533
- else:
534
- self.s3_client.upload_file(
535
- Filename = local_file_path,
536
- Bucket = self.bucket_name,
537
- Key = key,
538
- Config = self.transfer_config,
539
- )
542
+ else:
543
+ self.s3_client.upload_file(
544
+ Filename = local_file_path,
545
+ Bucket = self.bucket_name,
546
+ Key = key,
547
+ Config = config,
548
+ )
540
549
 
541
550
  @check_mounted
542
- def upload_folder(self, local_folder_path : str, key : str = "", show_progress_bar : bool = True, use_simple_upload : bool = False) -> 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:
543
552
  """
544
553
  Upload the contents of a folder to the mounted bucket
545
554
 
@@ -551,6 +560,16 @@ class HCPHandler:
551
560
 
552
561
  :param show_progress_bar: Boolean choice of displaying a progress bar. Defaults to True
553
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
554
573
  """
555
574
  raise_path_error(local_folder_path)
556
575
 
@@ -563,7 +582,8 @@ class HCPHandler:
563
582
  local_folder_path + filename,
564
583
  key + filename,
565
584
  show_progress_bar = show_progress_bar,
566
- use_simple_upload = use_simple_upload
585
+ upload_mode = upload_mode,
586
+ equal_parts = equal_parts
567
587
  )
568
588
 
569
589
  @check_mounted
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: NGPIris
3
- Version: 5.4.2.dev5
3
+ Version: 5.4.2.dev7
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
7
7
  Requires-Dist: requests>=2.31.0
8
8
  Requires-Dist: urllib3==1.26.19
9
- Requires-Dist: boto3==1.35.81
9
+ Requires-Dist: boto3==1.37.35
10
10
  Requires-Dist: parse>=1.19.1
11
11
  Requires-Dist: RapidFuzz>=3.10.1
12
12
  Requires-Dist: tqdm>=4.66.2
@@ -1,6 +1,6 @@
1
1
  requests>=2.31.0
2
2
  urllib3==1.26.19
3
- boto3==1.35.81
3
+ boto3==1.37.35
4
4
  parse>=1.19.1
5
5
  RapidFuzz>=3.10.1
6
6
  tqdm>=4.66.2
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: NGPIris
3
- Version: 5.4.2.dev5
3
+ Version: 5.4.2.dev7
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
7
7
  Requires-Dist: requests>=2.31.0
8
8
  Requires-Dist: urllib3==1.26.19
9
- Requires-Dist: boto3==1.35.81
9
+ Requires-Dist: boto3==1.37.35
10
10
  Requires-Dist: parse>=1.19.1
11
11
  Requires-Dist: RapidFuzz>=3.10.1
12
12
  Requires-Dist: tqdm>=4.66.2
@@ -1,11 +1,11 @@
1
1
  [project]
2
2
  name = "NGPIris"
3
- version = "5.4.2.dev5"
3
+ version = "5.4.2.dev7"
4
4
  readme = "README.md"
5
5
  dependencies = [
6
6
  "requests >= 2.31.0",
7
7
  "urllib3 == 1.26.19",
8
- "boto3 == 1.35.81",
8
+ "boto3 == 1.37.35",
9
9
  "parse >= 1.19.1",
10
10
  "RapidFuzz >= 3.10.1",
11
11
  "tqdm >= 4.66.2",
@@ -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