NGPIris 5.1.1.dev3__py3-none-any.whl → 5.2.0.dev1__py3-none-any.whl

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/cli/__init__.py CHANGED
@@ -19,14 +19,14 @@ def format_list(list_of_things : list) -> str:
19
19
  list_of_buckets = list(map(lambda s : s + "\n", list_of_things))
20
20
  return "".join(list_of_buckets).strip("\n")
21
21
 
22
- def _list_objects_generator(hcph : HCPHandler, name_only : bool) -> Generator[str, Any, None]:
22
+ def _list_objects_generator(hcph : HCPHandler, path : str, name_only : bool, files_only : bool) -> Generator[str, Any, None]:
23
23
  """
24
24
  Handle object list as a paginator that `click` can handle. It works slightly
25
25
  different from `list_objects` in `hcp.py` in order to make the output
26
26
  printable in a terminal
27
27
  """
28
28
  paginator : Paginator = hcph.s3_client.get_paginator("list_objects_v2")
29
- pages : PageIterator = paginator.paginate(Bucket = hcph.bucket_name)
29
+ pages : PageIterator = paginator.paginate(Bucket = hcph.bucket_name, Prefix = path)
30
30
  (nb_of_cols, _) = get_terminal_size()
31
31
  max_width = floor(nb_of_cols / 5)
32
32
  if (not name_only):
@@ -36,7 +36,11 @@ def _list_objects_generator(hcph : HCPHandler, name_only : bool) -> Generator[st
36
36
  tablefmt = "plain",
37
37
  stralign = "center"
38
38
  ) + "\n" + "-"*nb_of_cols + "\n"
39
- for object in pages.search("Contents[?!ends_with(Key, '/')][]"): # filter objects that does not end with "/"
39
+ if files_only:
40
+ filter_string = "Contents[?!ends_with(Key, '/')][]" # filter objects that does not end with "/"
41
+ else:
42
+ filter_string = "Contents[*][]"
43
+ for object in pages.search(filter_string):
40
44
  if name_only:
41
45
  yield str(object["Key"]) + "\n"
42
46
  else:
@@ -55,6 +59,11 @@ def _list_objects_generator(hcph : HCPHandler, name_only : bool) -> Generator[st
55
59
  def object_is_folder(object_path : str, hcph : HCPHandler) -> bool:
56
60
  return (object_path[-1] == "/") and (hcph.get_object(object_path)["ContentLength"] == 0)
57
61
 
62
+ def add_trailing_slash(path : str) -> str:
63
+ if not path[-1] == "/":
64
+ path += "/"
65
+ return path
66
+
58
67
  @click.group()
59
68
  @click.argument("credentials")
60
69
  @click.version_option(package_name = "NGPIris")
@@ -85,6 +94,8 @@ def upload(context : Context, bucket : str, source : str, destination : str):
85
94
  """
86
95
  hcph : HCPHandler = get_HCPHandler(context)
87
96
  hcph.mount_bucket(bucket)
97
+ source = add_trailing_slash(source)
98
+ destination = add_trailing_slash(destination)
88
99
  if Path(source).is_dir():
89
100
  hcph.upload_folder(source, destination)
90
101
  else:
@@ -198,22 +209,52 @@ def list_buckets(context : Context):
198
209
 
199
210
  @cli.command()
200
211
  @click.argument("bucket")
212
+ @click.argument("path", required = False)
201
213
  @click.option(
202
214
  "-no",
203
215
  "--name-only",
204
216
  help = "Output only the name of the objects instead of all the associated metadata",
205
- default = False
217
+ default = False,
218
+ is_flag = True
219
+ )
220
+ @click.option(
221
+ "-p",
222
+ "--pagination",
223
+ help = "Output as a paginator",
224
+ default = False,
225
+ is_flag = True
226
+ )
227
+ @click.option(
228
+ "-fo",
229
+ "--files-only",
230
+ help = "Output only file objects",
231
+ default = False,
232
+ is_flag = True
206
233
  )
207
234
  @click.pass_context
208
- def list_objects(context : Context, bucket : str, name_only : bool):
235
+ def list_objects(context : Context, bucket : str, path : str, name_only : bool, pagination : bool, files_only : bool):
209
236
  """
210
237
  List the objects in a certain bucket/namespace on the HCP.
211
238
 
212
239
  BUCKET is the name of the bucket in which to list its objects.
240
+
241
+ PATH is an optional argument for where to list the objects
213
242
  """
214
243
  hcph : HCPHandler = get_HCPHandler(context)
215
244
  hcph.mount_bucket(bucket)
216
- click.echo_via_pager(_list_objects_generator(hcph, name_only))
245
+ if path:
246
+ path_with_slash = add_trailing_slash(path)
247
+
248
+ if not hcph.object_exists(path_with_slash):
249
+ raise RuntimeError("Path does not exist")
250
+ else:
251
+ path_with_slash = ""
252
+
253
+ if pagination:
254
+ click.echo_via_pager(_list_objects_generator(hcph, path_with_slash, name_only, files_only))
255
+ else:
256
+ for obj in hcph.list_objects(path_with_slash, name_only, files_only):
257
+ click.echo(obj)
217
258
 
218
259
  @cli.command()
219
260
  @click.argument("bucket")
NGPIris/hcp/hcp.py CHANGED
@@ -178,6 +178,8 @@ class HCPHandler:
178
178
  pass
179
179
  else:
180
180
  raise RuntimeError("No bucket selected. Either use `mount_bucket` first or supply the optional `bucket_name` parameter for `test_connection`")
181
+
182
+ response = {}
181
183
  try:
182
184
  response = dict(self.s3_client.head_bucket(Bucket = bucket_name))
183
185
  except EndpointConnectionError as e: # pragma: no cover
@@ -234,7 +236,7 @@ class HCPHandler:
234
236
  return list_of_buckets
235
237
 
236
238
  @check_mounted
237
- def list_objects(self, path_key : str = "", name_only : bool = False) -> Generator:
239
+ def list_objects(self, path_key : str = "", name_only : bool = False, files_only : bool = False) -> Generator:
238
240
  """
239
241
  List all objects in the mounted bucket as a generator. If one wishes to
240
242
  get the result as a list, use :py:function:`list` to type cast the generator
@@ -243,16 +245,35 @@ class HCPHandler:
243
245
  :type path_key: str, optional
244
246
  :param name_only: If True, yield only a the object names. If False, yield the full metadata about each object. Defaults to False.
245
247
  :type name_only: bool, optional
248
+ :param files_only: If true, only yield file objects. Defaults to False
249
+ :type files_only: bool, optional
246
250
  :yield: A generator of all objects in a bucket
247
251
  :rtype: Generator
248
252
  """
249
253
  paginator : Paginator = self.s3_client.get_paginator("list_objects_v2")
250
- pages : PageIterator = paginator.paginate(Bucket = self.bucket_name)
251
- for object in pages.search("Contents[?starts_with(Key, '" + path_key + "')][]"):
252
- if name_only:
253
- yield str(object["Key"])
254
- else:
255
- yield object
254
+ pages : PageIterator = paginator.paginate(Bucket = self.bucket_name, Prefix = path_key)
255
+
256
+ if files_only:
257
+ filter_string = "Contents[?!ends_with(Key, '/')][]"
258
+ else:
259
+ filter_string = "Contents[*][]"
260
+
261
+ split_path_key = len(path_key.split("/")) + 1
262
+
263
+ pages_filtered = pages.search(filter_string)
264
+ for object in pages_filtered:
265
+ # Split the object key by "/"
266
+ split_object = object["Key"].split("/")
267
+ # Check if the object is within the specified path_key depth
268
+ if len(split_object) <= split_path_key:
269
+ # Skip objects that are not at the desired depth
270
+ if (len(split_object) == split_path_key) and split_object[-1]:
271
+ continue
272
+
273
+ if name_only:
274
+ yield str(object["Key"])
275
+ else:
276
+ yield object
256
277
 
257
278
  @check_mounted
258
279
  def get_object(self, key : str) -> dict:
@@ -510,7 +531,6 @@ class HCPHandler:
510
531
  """
511
532
  return self.fuzzy_search_in_bucket(search_string, name_only, case_sensitive, 100)
512
533
 
513
-
514
534
  @check_mounted
515
535
  def fuzzy_search_in_bucket(
516
536
  self,
@@ -556,7 +576,7 @@ class HCPHandler:
556
576
  if name_only:
557
577
  yield item
558
578
  else:
559
- yield full_list[index]
579
+ yield full_list[index] # type: ignore
560
580
 
561
581
  @check_mounted
562
582
  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.dev3
3
+ Version: 5.2.0.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
@@ -1,21 +1,21 @@
1
1
  NGPIris/__init__.py,sha256=eHaeRGl1JQ_hjsazEd4oQCXOkdpSxLIzg-ipYAAaa-s,69
2
- NGPIris/cli/__init__.py,sha256=PaivVdvfSNTeU9eAXLp5OAl6V2LmcAWZDGPvR8jgwH4,11843
2
+ NGPIris/cli/__init__.py,sha256=w2_abrZPDFZb_iX31nqWJUGsbVmE_zFv1vjQeMsP7BE,13003
3
3
  NGPIris/hci/__init__.py,sha256=qZRzN2JZp8uIw46TQiqJHMIkleiVDErSoZ3-v0O_cZU,38
4
4
  NGPIris/hci/exceptions.py,sha256=wUbpUwY8u1QtuSvnzlBuql9LgGsxBl207IGsHkCt-JQ,47
5
5
  NGPIris/hci/hci.py,sha256=-7RBWPGqlINVNsl-GbjuXkcLdIF5cs4cu3OFt2FJi1E,4321
6
6
  NGPIris/hci/helpers.py,sha256=THZt9ItmEsEiuvB1v99orAx1oOMgBdGR62PQyOre5yo,2592
7
7
  NGPIris/hcp/__init__.py,sha256=yMDW3WpxsU89GNcBJ3ApeGHOmWvisfuuAsZxwlKWnpw,38
8
8
  NGPIris/hcp/exceptions.py,sha256=24irbs3JMWaVOM_gf4ByR1hfYPpEP1eXPgHvq77uuqU,361
9
- NGPIris/hcp/hcp.py,sha256=xYKZYESS6_k3qcU7KpSDss3M3U59jVqSnhOSdr-PV7Q,24738
9
+ NGPIris/hcp/hcp.py,sha256=1GrqqxLT4Z9Vufg4jQoXykJO-UafOhoBYVSgG6mU8Js,25578
10
10
  NGPIris/hcp/helpers.py,sha256=SRHX-B6TSDogK7Mz2co7VkzHtZdtMaMeH-_NoDWEDh8,1406
11
11
  NGPIris/hcp/statistics.py,sha256=8VgRC-7hWQOCRWwoKk4NHCtGTdY_4C2iHcAHEXKJ0kM,817
12
12
  NGPIris/parse_credentials/__init__.py,sha256=O9uq_F9uOtuW7giW-t10KV4VmTgfkvgaBEwQU43Sf-w,57
13
13
  NGPIris/parse_credentials/parse_credentials.py,sha256=E1NzQCMvjOa2mGLBkEYshZomNSxfSCkoc_iUhUfpBEM,2106
14
14
  NGPIris/utils/__init__.py,sha256=yPCEc1-_7r01dZ-31EKiA7Jova7ztX7XXuU95IKmKX8,59
15
15
  NGPIris/utils/utils.py,sha256=m9qwLuOoiqVNRy7B4raYNFJkigL_wE--PiWhyhVhHII,248
16
- NGPIris-5.1.1.dev3.dist-info/LICENSE,sha256=ZA2Q9u5AEkH_YoNNDRsz-DBJ6ZuL_foE7RsKFjXd4-c,18093
17
- NGPIris-5.1.1.dev3.dist-info/METADATA,sha256=opGIL9MCWMxgEANG02bnvGPJUtz8Gyc-qs7omOoJPTk,7080
18
- NGPIris-5.1.1.dev3.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
19
- NGPIris-5.1.1.dev3.dist-info/entry_points.txt,sha256=t8ADhe3ovPm9tW3XDZq1_vKmfHY98Ei_o6WioJobNzU,117
20
- NGPIris-5.1.1.dev3.dist-info/top_level.txt,sha256=954WCuIJkle_SMtr7MNPapiiLLAFhlKbcz6Bp89-2V0,8
21
- NGPIris-5.1.1.dev3.dist-info/RECORD,,
16
+ NGPIris-5.2.0.dev1.dist-info/LICENSE,sha256=ZA2Q9u5AEkH_YoNNDRsz-DBJ6ZuL_foE7RsKFjXd4-c,18093
17
+ NGPIris-5.2.0.dev1.dist-info/METADATA,sha256=Wd5zaHozIbbbCxyYrlx8ScOJ_wfvCxElv2_OOe2Xq-4,7080
18
+ NGPIris-5.2.0.dev1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
19
+ NGPIris-5.2.0.dev1.dist-info/entry_points.txt,sha256=t8ADhe3ovPm9tW3XDZq1_vKmfHY98Ei_o6WioJobNzU,117
20
+ NGPIris-5.2.0.dev1.dist-info/top_level.txt,sha256=954WCuIJkle_SMtr7MNPapiiLLAFhlKbcz6Bp89-2V0,8
21
+ NGPIris-5.2.0.dev1.dist-info/RECORD,,