Skip to content

Commit db1cdcd

Browse files
committed
Support retrieving multiple links by name
1 parent 5b77248 commit db1cdcd

File tree

3 files changed

+53
-20
lines changed

3 files changed

+53
-20
lines changed

h5pyd/_hl/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,15 +1026,15 @@ def PUT(self, req, body=None, params=None, format="json", replace=False):
10261026
rsp_json = json.loads(rsp.text)
10271027
return rsp_json
10281028

1029-
def POST(self, req, body=None, format="json"):
1029+
def POST(self, req, body=None, params=None, format="json"):
10301030
if self.id.http_conn is None:
10311031
raise IOError("object not initialized")
10321032

10331033
# try to do a POST to the domain
10341034

10351035
self.log.info("POST: {} [{}]".format(req, self.id.domain))
10361036

1037-
rsp = self.id._http_conn.POST(req, body=body, format=format)
1037+
rsp = self.id._http_conn.POST(req, body=body, params=params, format=format)
10381038
if rsp.status_code == 409:
10391039
raise ValueError("name already exists")
10401040
if rsp.status_code not in (200, 201):

h5pyd/_hl/group.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ def get(self, name, default=None, getclass=False, getlink=False, track_order=Fal
736736
except KeyError:
737737
return default
738738

739-
if name is not None and name not in self:
739+
if not isinstance(name, list) and name is not None and name not in self:
740740
return default
741741

742742
elif getclass and not getlink:
@@ -753,14 +753,17 @@ def get(self, name, default=None, getclass=False, getlink=False, track_order=Fal
753753
raise TypeError("Unknown object type")
754754

755755
elif getlink:
756-
if name is None:
756+
if name is None or isinstance(name, list):
757757
# Get all links in target group(s)
758758
# Retrieve "limit", "marker", and "pattern" from kwds
759759
limit = kwds.get("limit", None)
760760
marker = kwds.get("marker", None)
761761
pattern = kwds.get("pattern", None)
762762
follow_links = kwds.get("follow_links", False)
763763

764+
if name and (limit or marker or pattern or follow_links):
765+
raise ValueError("Cannot specify 'name' along with 'limit', 'marker', 'pattern', or 'follow_links'")
766+
764767
req = "/groups/" + self.id.uuid + "/links"
765768
params = {}
766769

@@ -775,7 +778,15 @@ def get(self, name, default=None, getclass=False, getlink=False, track_order=Fal
775778
if track_order:
776779
params["CreateOrder"] = 1
777780

778-
rsp = self.GET(req, params=params)
781+
if name:
782+
body = {}
783+
784+
titles = [linkname.decode('utf-8') if
785+
isinstance(linkname, bytes) else linkname for linkname in name]
786+
body['titles'] = titles
787+
rsp = self.POST(req, body=body, params=params)
788+
else:
789+
rsp = self.GET(req, params=params)
779790

780791
if "links" in rsp:
781792
# Process list of link objects so they may be accessed by name
@@ -798,24 +809,24 @@ def get(self, name, default=None, getclass=False, getlink=False, track_order=Fal
798809
raise ValueError("Can't parse server response to links query")
799810

800811
return links_out
812+
else:
813+
parent_uuid, link_json = self._get_link_json(name)
814+
typecode = link_json['class']
801815

802-
parent_uuid, link_json = self._get_link_json(name)
803-
typecode = link_json['class']
804-
805-
if typecode == 'H5L_TYPE_SOFT':
806-
if getclass:
807-
return SoftLink
816+
if typecode == 'H5L_TYPE_SOFT':
817+
if getclass:
818+
return SoftLink
808819

809-
return SoftLink(link_json['h5path'])
810-
elif typecode == 'H5L_TYPE_EXTERNAL':
811-
if getclass:
812-
return ExternalLink
820+
return SoftLink(link_json['h5path'])
821+
elif typecode == 'H5L_TYPE_EXTERNAL':
822+
if getclass:
823+
return ExternalLink
813824

814-
return ExternalLink(link_json['h5domain'], link_json['h5path'])
815-
elif typecode == 'H5L_TYPE_HARD':
816-
return HardLink if getclass else HardLink(link_json['id'])
817-
else:
818-
raise TypeError("Unknown link type")
825+
return ExternalLink(link_json['h5domain'], link_json['h5path'])
826+
elif typecode == 'H5L_TYPE_HARD':
827+
return HardLink if getclass else HardLink(link_json['id'])
828+
else:
829+
raise TypeError("Unknown link type")
819830

820831
def __setitem__(self, name, obj):
821832
""" Add an object to the group. The name must not already be in use.

test/hl/test_group.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,17 @@ def test_link_multi_removal(self):
334334
self.assertTrue(name in g1)
335335
self.assertTrue(name in g1_clone)
336336

337+
# delete links with names that must be URL-encoded
338+
names = ['link with spaces', 'link%', 'unicode八link']
339+
340+
for name in names:
341+
g1[name] = g1
342+
343+
del g1[names]
344+
345+
for name in names:
346+
self.assertTrue(name not in g1)
347+
337348
f.close()
338349

339350
def test_link_multi_create(self):
@@ -521,6 +532,17 @@ def test_link_get_multi(self):
521532
link = links[name]
522533
self.assertEqual(link.id, group_id)
523534

535+
# Retrieve a set of links by name
536+
names = ["link" + str(i) for i in range(5, 15)]
537+
links_out = g1.get(names, getlink=True)
538+
539+
self.assertEqual(len(links_out), 10)
540+
541+
for name in names:
542+
self.assertTrue(name in links_out)
543+
link = links_out[name]
544+
self.assertEqual(link.id, g1.id.uuid)
545+
524546

525547
class TestTrackOrder(TestCase):
526548

0 commit comments

Comments
 (0)