NGPIris 5.1.1.dev2__tar.gz → 5.1.1.dev3__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 (129) hide show
  1. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/cli/__init__.py +67 -4
  2. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/hcp/hcp.py +94 -43
  3. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris.egg-info/PKG-INFO +3 -110
  4. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris.egg-info/requires.txt +1 -0
  5. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/PKG-INFO +3 -110
  6. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/README.md +1 -109
  7. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/Tutorial.md +32 -41
  8. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/pyproject.toml +2 -1
  9. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/LICENSE +0 -0
  10. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/MANIFEST.in +0 -0
  11. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/__init__.py +0 -0
  12. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/hci/__init__.py +0 -0
  13. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/hci/exceptions.py +0 -0
  14. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/hci/hci.py +0 -0
  15. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/hci/helpers.py +0 -0
  16. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/hcp/__init__.py +0 -0
  17. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/hcp/exceptions.py +0 -0
  18. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/hcp/helpers.py +0 -0
  19. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/hcp/statistics.py +0 -0
  20. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/parse_credentials/__init__.py +0 -0
  21. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/parse_credentials/parse_credentials.py +0 -0
  22. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/utils/__init__.py +0 -0
  23. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris/utils/utils.py +0 -0
  24. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris.egg-info/SOURCES.txt +0 -0
  25. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris.egg-info/dependency_links.txt +0 -0
  26. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris.egg-info/entry_points.txt +0 -0
  27. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/NGPIris.egg-info/top_level.txt +0 -0
  28. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/IRIS_5_changelog.md +0 -0
  29. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/Makefile +0 -0
  30. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/NGPIris.cli.rst +0 -0
  31. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/NGPIris.hci.rst +0 -0
  32. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/NGPIris.hcp.rst +0 -0
  33. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/NGPIris.parse_credentials.rst +0 -0
  34. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/NGPIris.rst +0 -0
  35. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/NGPIris.utils.rst +0 -0
  36. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/.DS_Store +0 -0
  37. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/IRIS_5_changelog.doctree +0 -0
  38. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/NGPIris.cli.doctree +0 -0
  39. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/NGPIris.doctree +0 -0
  40. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/NGPIris.hci.doctree +0 -0
  41. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/NGPIris.hcp.doctree +0 -0
  42. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/NGPIris.parse_credentials.doctree +0 -0
  43. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/NGPIris.utils.doctree +0 -0
  44. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/README.doctree +0 -0
  45. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/Tutorial.doctree +0 -0
  46. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/environment.pickle +0 -0
  47. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/index.doctree +0 -0
  48. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/doctrees/modules.doctree +0 -0
  49. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/.buildinfo +0 -0
  50. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/IRIS_5_changelog.html +0 -0
  51. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/NGPIris.cli.html +0 -0
  52. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/NGPIris.hci.html +0 -0
  53. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/NGPIris.hcp.html +0 -0
  54. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/NGPIris.html +0 -0
  55. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/NGPIris.parse_credentials.html +0 -0
  56. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/NGPIris.utils.html +0 -0
  57. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/README.html +0 -0
  58. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/Tutorial.html +0 -0
  59. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_downloads/ee00c4f6f22dc2671c766f728f00006f/credentials_template.json +0 -0
  60. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_modules/NGPIris/cli.html +0 -0
  61. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_modules/NGPIris/hci/exceptions.html +0 -0
  62. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_modules/NGPIris/hci/hci.html +0 -0
  63. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_modules/NGPIris/hci/helpers.html +0 -0
  64. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_modules/NGPIris/hcp/exceptions.html +0 -0
  65. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_modules/NGPIris/hcp/hcp.html +0 -0
  66. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_modules/NGPIris/hcp/helpers.html +0 -0
  67. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_modules/NGPIris/hcp/statistics.html +0 -0
  68. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_modules/NGPIris/parse_credentials/parse_credentials.html +0 -0
  69. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_modules/NGPIris/utils/utils.html +0 -0
  70. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_modules/index.html +0 -0
  71. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_sources/IRIS_5_changelog.md.txt +0 -0
  72. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_sources/NGPIris.cli.rst.txt +0 -0
  73. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_sources/NGPIris.hci.rst.txt +0 -0
  74. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_sources/NGPIris.hcp.rst.txt +0 -0
  75. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_sources/NGPIris.parse_credentials.rst.txt +0 -0
  76. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_sources/NGPIris.rst.txt +0 -0
  77. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_sources/NGPIris.utils.rst.txt +0 -0
  78. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_sources/README.md.txt +0 -0
  79. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_sources/Tutorial.md.txt +0 -0
  80. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_sources/index.rst.txt +0 -0
  81. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_sources/modules.rst.txt +0 -0
  82. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/alabaster.css +0 -0
  83. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/basic.css +0 -0
  84. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/custom.css +0 -0
  85. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/debug.css +0 -0
  86. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/doctools.js +0 -0
  87. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/documentation_options.js +0 -0
  88. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/file.png +0 -0
  89. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/language_data.js +0 -0
  90. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/minus.png +0 -0
  91. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/plus.png +0 -0
  92. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/pygments.css +0 -0
  93. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/scripts/furo-extensions.js +0 -0
  94. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/scripts/furo.js +0 -0
  95. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/scripts/furo.js.LICENSE.txt +0 -0
  96. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/scripts/furo.js.map +0 -0
  97. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/searchtools.js +0 -0
  98. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/skeleton.css +0 -0
  99. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/sphinx_highlight.js +0 -0
  100. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/styles/furo-extensions.css +0 -0
  101. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/styles/furo-extensions.css.map +0 -0
  102. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/styles/furo.css +0 -0
  103. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/_static/styles/furo.css.map +0 -0
  104. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/genindex.html +0 -0
  105. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/index.html +0 -0
  106. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/modules.html +0 -0
  107. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/objects.inv +0 -0
  108. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/py-modindex.html +0 -0
  109. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/search.html +0 -0
  110. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/_build/html/searchindex.js +0 -0
  111. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/conf.py +0 -0
  112. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/index.rst +0 -0
  113. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/make.bat +0 -0
  114. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/docs/modules.rst +0 -0
  115. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/setup.cfg +0 -0
  116. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/data/80MB_test_file +0 -0
  117. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/data/a folder of data/80MB_test_file_0 +0 -0
  118. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/data/a folder of data/80MB_test_file_1 +0 -0
  119. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/data/complete_creds_0.json +0 -0
  120. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/data/complete_creds_1.json +0 -0
  121. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/data/complete_creds_2.json +0 -0
  122. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/data/incomplete_creds_0.json +0 -0
  123. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/data/incomplete_creds_1.json +0 -0
  124. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/data/incomplete_creds_2.json +0 -0
  125. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/data/incomplete_creds_3.json +0 -0
  126. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/data/incomplete_creds_4.json +0 -0
  127. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/test_hci.py +0 -0
  128. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/test_hcp.py +0 -0
  129. {ngpiris-5.1.1.dev2 → ngpiris-5.1.1.dev3}/tests/test_parse_credentials.py +0 -0
@@ -222,23 +222,86 @@ def list_objects(context : Context, bucket : str, name_only : bool):
222
222
  "-cs",
223
223
  "--case_sensitive",
224
224
  help = "Use case sensitivity? Default value is False",
225
- default = False
225
+ default = False,
226
+ is_flag = True
227
+ )
228
+ @click.option(
229
+ "-v",
230
+ "--verbose",
231
+ help = "Get a verbose output of files. Default value is False, since it might be slower",
232
+ default = False,
233
+ is_flag = True
226
234
  )
227
235
  @click.pass_context
228
- def simple_search(context : Context, bucket : str, search_string : str, case_sensitive : bool):
236
+ def simple_search(context : Context, bucket : str, search_string : str, case_sensitive : bool, verbose : bool):
229
237
  """
230
238
  Make simple search using substrings in a bucket/namespace on the HCP.
231
239
 
240
+ NOTE: This command does not use the HCI. Instead, it uses a linear search of
241
+ all the objects in the HCP. As such, this search might be slow.
242
+
243
+ BUCKET is the name of the bucket in which to make the search.
244
+
245
+ SEARCH_STRING is any string that is to be used for the search.
246
+ """
247
+ hcph : HCPHandler = get_HCPHandler(context)
248
+ hcph.mount_bucket(bucket)
249
+ list_of_results = hcph.search_in_bucket(
250
+ search_string,
251
+ name_only = (not verbose),
252
+ case_sensitive = case_sensitive
253
+ )
254
+ click.echo("Search results:")
255
+ for result in list_of_results:
256
+ click.echo(result)
257
+
258
+ @cli.command()
259
+ @click.argument("bucket")
260
+ @click.argument("search_string")
261
+ @click.option(
262
+ "-cs",
263
+ "--case_sensitive",
264
+ help = "Use case sensitivity? Default value is False",
265
+ default = False,
266
+ is_flag = True
267
+ )
268
+ @click.option(
269
+ "-v",
270
+ "--verbose",
271
+ help = "Get a verbose output of files. Default value is False, since it might be slower",
272
+ default = False,
273
+ is_flag = True
274
+ )
275
+ @click.option(
276
+ "-t",
277
+ "--threshold",
278
+ help = "Set the threshold for the fuzzy search score. Default value is 80",
279
+ default = 80
280
+ )
281
+ @click.pass_context
282
+ def fuzzy_search(context : Context, bucket : str, search_string : str, case_sensitive : bool, verbose : bool, threshold : int):
283
+ """
284
+ Make a fuzzy search using a search string in a bucket/namespace on the HCP.
285
+
286
+ NOTE: This command does not use the HCI. Instead, it uses the RapidFuzz
287
+ library in order to find objects in the HCP. As such, this search might
288
+ be slow.
289
+
232
290
  BUCKET is the name of the bucket in which to make the search.
233
291
 
234
292
  SEARCH_STRING is any string that is to be used for the search.
235
293
  """
236
294
  hcph : HCPHandler = get_HCPHandler(context)
237
295
  hcph.mount_bucket(bucket)
238
- list_of_results = hcph.search_objects_in_bucket(search_string, case_sensitive)
296
+ list_of_results = hcph.fuzzy_search_in_bucket(
297
+ search_string,
298
+ name_only = (not verbose),
299
+ case_sensitive = case_sensitive,
300
+ threshold = threshold
301
+ )
239
302
  click.echo("Search results:")
240
303
  for result in list_of_results:
241
- click.echo("- " + result)
304
+ click.echo(result)
242
305
 
243
306
  @cli.command()
244
307
  @click.argument("bucket")
@@ -31,9 +31,13 @@ from os import (
31
31
  from json import dumps
32
32
  from parse import (
33
33
  parse,
34
- search,
35
34
  Result
36
35
  )
36
+ from rapidfuzz import (
37
+ fuzz,
38
+ process,
39
+ utils
40
+ )
37
41
  from requests import get
38
42
  from urllib3 import disable_warnings
39
43
  from tqdm import tqdm
@@ -173,7 +177,7 @@ class HCPHandler:
173
177
  elif bucket_name:
174
178
  pass
175
179
  else:
176
- raise RuntimeError("No bucket selected. Either use `mount_bucket` first or supply the optional `bucket_name` paramter for `test_connection`")
180
+ raise RuntimeError("No bucket selected. Either use `mount_bucket` first or supply the optional `bucket_name` parameter for `test_connection`")
177
181
  try:
178
182
  response = dict(self.s3_client.head_bucket(Bucket = bucket_name))
179
183
  except EndpointConnectionError as e: # pragma: no cover
@@ -426,25 +430,24 @@ class HCPHandler:
426
430
  :type verbose: bool, optional
427
431
  """
428
432
  object_list = []
433
+ does_not_exist = []
429
434
  for key in keys:
430
- object_list.append({"Key" : key})
431
-
432
- deletion_dict = {"Objects": object_list}
435
+ if self.object_exists(key):
436
+ object_list.append({"Key" : key})
437
+ else:
438
+ does_not_exist.append(key)
433
439
 
434
- response : dict = self.s3_client.delete_objects(
435
- Bucket = self.bucket_name,
436
- Delete = deletion_dict
437
- )
438
- if verbose:
439
- print(dumps(response, indent=4))
440
-
441
- deleted_dict_list : list[dict] = response["Deleted"]
442
- does_not_exist = []
443
- for deleted_dict in deleted_dict_list:
444
- if not "VersionId" in deleted_dict:
445
- does_not_exist.append("- " + key + "\n")
446
- if does_not_exist:
447
- print("The following could not be deleted because they didn't exist: \n" + "".join(does_not_exist))
440
+ if object_list:
441
+ deletion_dict = {"Objects": object_list}
442
+ response : dict = self.s3_client.delete_objects(
443
+ Bucket = self.bucket_name,
444
+ Delete = deletion_dict
445
+ )
446
+ if verbose:
447
+ print(dumps(response, indent=4))
448
+
449
+ if verbose and does_not_exist:
450
+ print("The following could not be deleted because they didn't exist: \n" + "\n".join(does_not_exist))
448
451
 
449
452
  @check_mounted
450
453
  def delete_object(self, key : str, verbose : bool = True) -> None:
@@ -461,51 +464,99 @@ class HCPHandler:
461
464
  @check_mounted
462
465
  def delete_folder(self, key : str, verbose : bool = True) -> None:
463
466
  """
464
- Delete a folder of objects in the mounted bucket. If there are subfolders, a RuntimeError is raisesd
467
+ Delete a folder of objects in the mounted bucket. If there are subfolders, a RuntimeError is raised
465
468
 
466
469
  :param key: The folder of objects to be deleted
467
470
  :type key: str
468
471
  :param verbose: Print the result of the deletion. defaults to True
469
472
  :type verbose: bool, optional
470
- :raises RuntimeError: If there are subfolders, a RuntimeError is raisesd
473
+ :raises RuntimeError: If there are subfolders, a RuntimeError is raised
471
474
  """
472
475
  if key[-1] != "/":
473
476
  key += "/"
474
- object_path_in_folder = []
475
- for s in self.search_objects_in_bucket(key):
476
- parse_object = parse(key + "{}", s)
477
- if type(parse_object) is Result:
478
- object_path_in_folder.append(s)
479
-
480
- for object_path in object_path_in_folder:
481
- if object_path[-1] == "/":
477
+
478
+ objects : list[str] = list(self.list_objects(key, name_only = True))
479
+
480
+ if not objects:
481
+ raise RuntimeError("\"" + key + "\"" + " is not a valid path") #TODO: change this error
482
+
483
+ for object_path in objects:
484
+ if (object_path[-1] == "/") and (not object_path == key): # `objects` might contain key, in which case everything is fine
482
485
  raise RuntimeError("There are subfolders in this folder. Please remove these first, before deleting this one")
483
- self.delete_objects(object_path_in_folder + [key], verbose = verbose)
486
+ self.delete_objects(objects, verbose = verbose)
484
487
 
485
488
  @check_mounted
486
- def search_objects_in_bucket(self, search_string : str, case_sensitive : bool = False) -> list[str]:
489
+ def search_in_bucket(
490
+ self,
491
+ search_string : str,
492
+ name_only : bool = True,
493
+ case_sensitive : bool = False
494
+ ) -> Generator:
487
495
  """
488
- Simple search method using substrings in order to find certain objects. Case insensitive by default. Does not utilise the HCI
496
+ Simple search method using exact substrings in order to find certain
497
+ objects. Case insensitive by default. Does not utilise the HCI
489
498
 
490
499
  :param search_string: Substring to be used in the search
491
500
  :type search_string: str
492
501
 
502
+ :param name_only: If True, yield only a the object names. If False, yield the full metadata about each object. Defaults to False.
503
+ :type name_only: bool, optional
504
+
493
505
  :param case_sensitive: Case sensitivity. Defaults to False
494
506
  :type case_sensitive: bool, optional
495
507
 
496
- :return: List of object names that match the in some way to the object names
497
- :rtype: list[str]
508
+ :return: A generator of objects based on the search string
509
+ :rtype: Generator
498
510
  """
499
- search_result : list[str] = []
500
- for key in self.list_objects(name_only = True):
501
- parse_object = search(
511
+ return self.fuzzy_search_in_bucket(search_string, name_only, case_sensitive, 100)
512
+
513
+
514
+ @check_mounted
515
+ def fuzzy_search_in_bucket(
516
+ self,
517
+ search_string : str,
518
+ name_only : bool = True,
519
+ case_sensitive : bool = False,
520
+ threshold : int = 80
521
+ ) -> Generator:
522
+ """
523
+ Fuzzy search implementation based on the `RapidFuzz` library.
524
+
525
+ :param search_string: Substring to be used in the search
526
+ :type search_string: str
527
+
528
+ :param name_only: If True, yield only a the object names. If False, yield the full metadata about each object. Defaults to False.
529
+ :type name_only: bool, optional
530
+
531
+ :param case_sensitive: Case sensitivity. Defaults to False
532
+ :type case_sensitive: bool, optional
533
+
534
+ :param threshold: The fuzzy search similarity score. Defaults to 80
535
+ :type threshold: int, optional
536
+
537
+ :return: A generator of objects based on the search string
538
+ :rtype: Generator
539
+ """
540
+
541
+ if case_sensitive:
542
+ processor = None
543
+ else:
544
+ processor = utils.default_process
545
+
546
+ if not name_only:
547
+ full_list = list(self.list_objects())
548
+
549
+ for item, score, index in process.extract_iter(
502
550
  search_string,
503
- key,
504
- case_sensitive = case_sensitive
505
- )
506
- if type(parse_object) is Result:
507
- search_result.append(key)
508
- return search_result
551
+ self.list_objects(name_only = True),
552
+ scorer = fuzz.partial_ratio,
553
+ processor = processor
554
+ ):
555
+ if score >= threshold:
556
+ if name_only:
557
+ yield item
558
+ else:
559
+ yield full_list[index]
509
560
 
510
561
  @check_mounted
511
562
  def get_object_acl(self, key : str) -> dict:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: NGPIris
3
- Version: 5.1.1.dev2
3
+ Version: 5.1.1.dev3
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
@@ -8,6 +8,7 @@ Requires-Dist: requests>=2.31.0
8
8
  Requires-Dist: urllib3==1.26.19
9
9
  Requires-Dist: boto3>=1.26.76
10
10
  Requires-Dist: parse>=1.19.1
11
+ Requires-Dist: RapidFuzz>=3.10.1
11
12
  Requires-Dist: tqdm>=4.66.2
12
13
  Requires-Dist: click>=8.1.7
13
14
  Requires-Dist: bitmath==1.3.3.1
@@ -164,116 +165,8 @@ Commands:
164
165
  test-connection Test the connection to a bucket/namespace.
165
166
  upload Upload files to an HCP bucket/namespace.
166
167
  ```
168
+ Each sub-command has its own help message and is displayed by `iris path/to/your/credentials.json sub-command --help`
167
169
 
168
- #### The `delete-folder` command
169
- ```
170
- Usage: iris CREDENTIALS delete-folder [OPTIONS] FOLDER BUCKET
171
-
172
- Delete a folder from an HCP bucket/namespace.
173
-
174
- FOLDER is the name of the folder to be deleted.
175
-
176
- BUCKET is the name of the bucket where the folder to be deleted exist.
177
-
178
- Options:
179
- --help Show this message and exit.
180
- ```
181
-
182
- #### The `delete-object` command
183
- ```
184
- Usage: iris CREDENTIALS delete-object [OPTIONS] OBJECT BUCKET
185
-
186
- Delete an object from an HCP bucket/namespace.
187
-
188
- OBJECT is the name of the object to be deleted.
189
-
190
- BUCKET is the name of the bucket where the object to be deleted exist.
191
-
192
- Options:
193
- --help Show this message and exit.
194
- ```
195
-
196
- #### The `download` command
197
- ```
198
- Usage: iris CREDENTIALS download [OPTIONS] OBJECT BUCKET LOCAL_PATH
199
-
200
- Download files from an HCP bucket/namespace.
201
-
202
- OBJECT is the name of the object to be downloaded.
203
-
204
- BUCKET is the name of the upload destination bucket.
205
-
206
- LOCAL_PATH is the path to where the downloaded objects are to be stored
207
- locally.
208
-
209
- Options:
210
- --help Show this message and exit.
211
- ```
212
-
213
- #### The `list-buckets` command
214
- ```
215
- Usage: iris CREDENTIALS list-buckets [OPTIONS]
216
-
217
- List the available buckets/namespaces on the HCP.
218
-
219
- Options:
220
- --help Show this message and exit.
221
- ```
222
-
223
- #### The `list-objects` command
224
- ```
225
- Usage: iris CREDENTIALS list-objects [OPTIONS] BUCKET
226
-
227
- List the objects in a certain bucket/namespace on the HCP.
228
-
229
- BUCKET is the name of the bucket in which to list its objects.
230
-
231
- Options:
232
- -no, --name-only BOOLEAN Output only the name of the objects instead of all
233
- the associated metadata
234
- --help Show this message and exit.
235
- ```
236
-
237
- #### The `simple-search` command
238
- ```
239
- Usage: iris CREDENTIALS simple-search [OPTIONS] BUCKET SEARCH_STRING
240
-
241
- Make simple search using substrings in a bucket/namespace on the HCP.
242
-
243
- BUCKET is the name of the bucket in which to make the search.
244
-
245
- SEARCH_STRING is any string that is to be used for the search.
246
-
247
- Options:
248
- -cs, --case_sensitive BOOLEAN Use case sensitivity?
249
- --help Show this message and exit.
250
- ```
251
-
252
- #### The `test-connection` command
253
- ```
254
- Usage: iris CREDENTIALS test-connection [OPTIONS] BUCKET
255
-
256
- Test the connection to a bucket/namespace.
257
-
258
- BUCKET is the name of the bucket for which a connection test should be made.
259
-
260
- Options:
261
- --help Show this message and exit.
262
- ```
263
-
264
- #### The `upload` command
265
- ```
266
- Usage: iris CREDENTIALS upload [OPTIONS] FILE_OR_FOLDER BUCKET
267
-
268
- Upload files to an HCP bucket/namespace.
269
-
270
- FILE-OR-FOLDER is the path to the file or folder of files to be uploaded.
271
-
272
- BUCKET is the name of the upload destination bucket.
273
-
274
- Options:
275
- --help Show this message and exit.
276
- ```
277
170
  ## Testing
278
171
  Assuming that the repository has been cloned, run the following tests:
279
172
  ```shell
@@ -2,6 +2,7 @@ requests>=2.31.0
2
2
  urllib3==1.26.19
3
3
  boto3>=1.26.76
4
4
  parse>=1.19.1
5
+ RapidFuzz>=3.10.1
5
6
  tqdm>=4.66.2
6
7
  click>=8.1.7
7
8
  bitmath==1.3.3.1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: NGPIris
3
- Version: 5.1.1.dev2
3
+ Version: 5.1.1.dev3
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
@@ -8,6 +8,7 @@ Requires-Dist: requests>=2.31.0
8
8
  Requires-Dist: urllib3==1.26.19
9
9
  Requires-Dist: boto3>=1.26.76
10
10
  Requires-Dist: parse>=1.19.1
11
+ Requires-Dist: RapidFuzz>=3.10.1
11
12
  Requires-Dist: tqdm>=4.66.2
12
13
  Requires-Dist: click>=8.1.7
13
14
  Requires-Dist: bitmath==1.3.3.1
@@ -164,116 +165,8 @@ Commands:
164
165
  test-connection Test the connection to a bucket/namespace.
165
166
  upload Upload files to an HCP bucket/namespace.
166
167
  ```
168
+ Each sub-command has its own help message and is displayed by `iris path/to/your/credentials.json sub-command --help`
167
169
 
168
- #### The `delete-folder` command
169
- ```
170
- Usage: iris CREDENTIALS delete-folder [OPTIONS] FOLDER BUCKET
171
-
172
- Delete a folder from an HCP bucket/namespace.
173
-
174
- FOLDER is the name of the folder to be deleted.
175
-
176
- BUCKET is the name of the bucket where the folder to be deleted exist.
177
-
178
- Options:
179
- --help Show this message and exit.
180
- ```
181
-
182
- #### The `delete-object` command
183
- ```
184
- Usage: iris CREDENTIALS delete-object [OPTIONS] OBJECT BUCKET
185
-
186
- Delete an object from an HCP bucket/namespace.
187
-
188
- OBJECT is the name of the object to be deleted.
189
-
190
- BUCKET is the name of the bucket where the object to be deleted exist.
191
-
192
- Options:
193
- --help Show this message and exit.
194
- ```
195
-
196
- #### The `download` command
197
- ```
198
- Usage: iris CREDENTIALS download [OPTIONS] OBJECT BUCKET LOCAL_PATH
199
-
200
- Download files from an HCP bucket/namespace.
201
-
202
- OBJECT is the name of the object to be downloaded.
203
-
204
- BUCKET is the name of the upload destination bucket.
205
-
206
- LOCAL_PATH is the path to where the downloaded objects are to be stored
207
- locally.
208
-
209
- Options:
210
- --help Show this message and exit.
211
- ```
212
-
213
- #### The `list-buckets` command
214
- ```
215
- Usage: iris CREDENTIALS list-buckets [OPTIONS]
216
-
217
- List the available buckets/namespaces on the HCP.
218
-
219
- Options:
220
- --help Show this message and exit.
221
- ```
222
-
223
- #### The `list-objects` command
224
- ```
225
- Usage: iris CREDENTIALS list-objects [OPTIONS] BUCKET
226
-
227
- List the objects in a certain bucket/namespace on the HCP.
228
-
229
- BUCKET is the name of the bucket in which to list its objects.
230
-
231
- Options:
232
- -no, --name-only BOOLEAN Output only the name of the objects instead of all
233
- the associated metadata
234
- --help Show this message and exit.
235
- ```
236
-
237
- #### The `simple-search` command
238
- ```
239
- Usage: iris CREDENTIALS simple-search [OPTIONS] BUCKET SEARCH_STRING
240
-
241
- Make simple search using substrings in a bucket/namespace on the HCP.
242
-
243
- BUCKET is the name of the bucket in which to make the search.
244
-
245
- SEARCH_STRING is any string that is to be used for the search.
246
-
247
- Options:
248
- -cs, --case_sensitive BOOLEAN Use case sensitivity?
249
- --help Show this message and exit.
250
- ```
251
-
252
- #### The `test-connection` command
253
- ```
254
- Usage: iris CREDENTIALS test-connection [OPTIONS] BUCKET
255
-
256
- Test the connection to a bucket/namespace.
257
-
258
- BUCKET is the name of the bucket for which a connection test should be made.
259
-
260
- Options:
261
- --help Show this message and exit.
262
- ```
263
-
264
- #### The `upload` command
265
- ```
266
- Usage: iris CREDENTIALS upload [OPTIONS] FILE_OR_FOLDER BUCKET
267
-
268
- Upload files to an HCP bucket/namespace.
269
-
270
- FILE-OR-FOLDER is the path to the file or folder of files to be uploaded.
271
-
272
- BUCKET is the name of the upload destination bucket.
273
-
274
- Options:
275
- --help Show this message and exit.
276
- ```
277
170
  ## Testing
278
171
  Assuming that the repository has been cloned, run the following tests:
279
172
  ```shell
@@ -149,116 +149,8 @@ Commands:
149
149
  test-connection Test the connection to a bucket/namespace.
150
150
  upload Upload files to an HCP bucket/namespace.
151
151
  ```
152
+ Each sub-command has its own help message and is displayed by `iris path/to/your/credentials.json sub-command --help`
152
153
 
153
- #### The `delete-folder` command
154
- ```
155
- Usage: iris CREDENTIALS delete-folder [OPTIONS] FOLDER BUCKET
156
-
157
- Delete a folder from an HCP bucket/namespace.
158
-
159
- FOLDER is the name of the folder to be deleted.
160
-
161
- BUCKET is the name of the bucket where the folder to be deleted exist.
162
-
163
- Options:
164
- --help Show this message and exit.
165
- ```
166
-
167
- #### The `delete-object` command
168
- ```
169
- Usage: iris CREDENTIALS delete-object [OPTIONS] OBJECT BUCKET
170
-
171
- Delete an object from an HCP bucket/namespace.
172
-
173
- OBJECT is the name of the object to be deleted.
174
-
175
- BUCKET is the name of the bucket where the object to be deleted exist.
176
-
177
- Options:
178
- --help Show this message and exit.
179
- ```
180
-
181
- #### The `download` command
182
- ```
183
- Usage: iris CREDENTIALS download [OPTIONS] OBJECT BUCKET LOCAL_PATH
184
-
185
- Download files from an HCP bucket/namespace.
186
-
187
- OBJECT is the name of the object to be downloaded.
188
-
189
- BUCKET is the name of the upload destination bucket.
190
-
191
- LOCAL_PATH is the path to where the downloaded objects are to be stored
192
- locally.
193
-
194
- Options:
195
- --help Show this message and exit.
196
- ```
197
-
198
- #### The `list-buckets` command
199
- ```
200
- Usage: iris CREDENTIALS list-buckets [OPTIONS]
201
-
202
- List the available buckets/namespaces on the HCP.
203
-
204
- Options:
205
- --help Show this message and exit.
206
- ```
207
-
208
- #### The `list-objects` command
209
- ```
210
- Usage: iris CREDENTIALS list-objects [OPTIONS] BUCKET
211
-
212
- List the objects in a certain bucket/namespace on the HCP.
213
-
214
- BUCKET is the name of the bucket in which to list its objects.
215
-
216
- Options:
217
- -no, --name-only BOOLEAN Output only the name of the objects instead of all
218
- the associated metadata
219
- --help Show this message and exit.
220
- ```
221
-
222
- #### The `simple-search` command
223
- ```
224
- Usage: iris CREDENTIALS simple-search [OPTIONS] BUCKET SEARCH_STRING
225
-
226
- Make simple search using substrings in a bucket/namespace on the HCP.
227
-
228
- BUCKET is the name of the bucket in which to make the search.
229
-
230
- SEARCH_STRING is any string that is to be used for the search.
231
-
232
- Options:
233
- -cs, --case_sensitive BOOLEAN Use case sensitivity?
234
- --help Show this message and exit.
235
- ```
236
-
237
- #### The `test-connection` command
238
- ```
239
- Usage: iris CREDENTIALS test-connection [OPTIONS] BUCKET
240
-
241
- Test the connection to a bucket/namespace.
242
-
243
- BUCKET is the name of the bucket for which a connection test should be made.
244
-
245
- Options:
246
- --help Show this message and exit.
247
- ```
248
-
249
- #### The `upload` command
250
- ```
251
- Usage: iris CREDENTIALS upload [OPTIONS] FILE_OR_FOLDER BUCKET
252
-
253
- Upload files to an HCP bucket/namespace.
254
-
255
- FILE-OR-FOLDER is the path to the file or folder of files to be uploaded.
256
-
257
- BUCKET is the name of the upload destination bucket.
258
-
259
- Options:
260
- --help Show this message and exit.
261
- ```
262
154
  ## Testing
263
155
  Assuming that the repository has been cloned, run the following tests:
264
156
  ```shell