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 +47 -6
- NGPIris/hcp/hcp.py +29 -9
- {NGPIris-5.1.1.dev3.dist-info → NGPIris-5.2.0.dev1.dist-info}/METADATA +1 -1
- {NGPIris-5.1.1.dev3.dist-info → NGPIris-5.2.0.dev1.dist-info}/RECORD +8 -8
- {NGPIris-5.1.1.dev3.dist-info → NGPIris-5.2.0.dev1.dist-info}/LICENSE +0 -0
- {NGPIris-5.1.1.dev3.dist-info → NGPIris-5.2.0.dev1.dist-info}/WHEEL +0 -0
- {NGPIris-5.1.1.dev3.dist-info → NGPIris-5.2.0.dev1.dist-info}/entry_points.txt +0 -0
- {NGPIris-5.1.1.dev3.dist-info → NGPIris-5.2.0.dev1.dist-info}/top_level.txt +0 -0
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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,21 +1,21 @@
|
|
|
1
1
|
NGPIris/__init__.py,sha256=eHaeRGl1JQ_hjsazEd4oQCXOkdpSxLIzg-ipYAAaa-s,69
|
|
2
|
-
NGPIris/cli/__init__.py,sha256=
|
|
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=
|
|
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.
|
|
17
|
-
NGPIris-5.
|
|
18
|
-
NGPIris-5.
|
|
19
|
-
NGPIris-5.
|
|
20
|
-
NGPIris-5.
|
|
21
|
-
NGPIris-5.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|