Skip to content

Commit

Permalink
Support retrieving multiple links by name
Browse files Browse the repository at this point in the history
  • Loading branch information
mattjala committed May 21, 2024
1 parent 5b77248 commit db1cdcd
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 20 deletions.
4 changes: 2 additions & 2 deletions h5pyd/_hl/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1026,15 +1026,15 @@ def PUT(self, req, body=None, params=None, format="json", replace=False):
rsp_json = json.loads(rsp.text)
return rsp_json

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

# try to do a POST to the domain

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

rsp = self.id._http_conn.POST(req, body=body, format=format)
rsp = self.id._http_conn.POST(req, body=body, params=params, format=format)
if rsp.status_code == 409:
raise ValueError("name already exists")
if rsp.status_code not in (200, 201):
Expand Down
47 changes: 29 additions & 18 deletions h5pyd/_hl/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ def get(self, name, default=None, getclass=False, getlink=False, track_order=Fal
except KeyError:
return default

if name is not None and name not in self:
if not isinstance(name, list) and name is not None and name not in self:
return default

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

elif getlink:
if name is None:
if name is None or isinstance(name, list):
# Get all links in target group(s)
# Retrieve "limit", "marker", and "pattern" from kwds
limit = kwds.get("limit", None)
marker = kwds.get("marker", None)
pattern = kwds.get("pattern", None)
follow_links = kwds.get("follow_links", False)

if name and (limit or marker or pattern or follow_links):
raise ValueError("Cannot specify 'name' along with 'limit', 'marker', 'pattern', or 'follow_links'")

req = "/groups/" + self.id.uuid + "/links"
params = {}

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

rsp = self.GET(req, params=params)
if name:
body = {}

titles = [linkname.decode('utf-8') if
isinstance(linkname, bytes) else linkname for linkname in name]
body['titles'] = titles
rsp = self.POST(req, body=body, params=params)
else:
rsp = self.GET(req, params=params)

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

return links_out
else:
parent_uuid, link_json = self._get_link_json(name)
typecode = link_json['class']

parent_uuid, link_json = self._get_link_json(name)
typecode = link_json['class']

if typecode == 'H5L_TYPE_SOFT':
if getclass:
return SoftLink
if typecode == 'H5L_TYPE_SOFT':
if getclass:
return SoftLink

return SoftLink(link_json['h5path'])
elif typecode == 'H5L_TYPE_EXTERNAL':
if getclass:
return ExternalLink
return SoftLink(link_json['h5path'])
elif typecode == 'H5L_TYPE_EXTERNAL':
if getclass:
return ExternalLink

return ExternalLink(link_json['h5domain'], link_json['h5path'])
elif typecode == 'H5L_TYPE_HARD':
return HardLink if getclass else HardLink(link_json['id'])
else:
raise TypeError("Unknown link type")
return ExternalLink(link_json['h5domain'], link_json['h5path'])
elif typecode == 'H5L_TYPE_HARD':
return HardLink if getclass else HardLink(link_json['id'])
else:
raise TypeError("Unknown link type")

def __setitem__(self, name, obj):
""" Add an object to the group. The name must not already be in use.
Expand Down
22 changes: 22 additions & 0 deletions test/hl/test_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,17 @@ def test_link_multi_removal(self):
self.assertTrue(name in g1)
self.assertTrue(name in g1_clone)

# delete links with names that must be URL-encoded
names = ['link with spaces', 'link%', 'unicode八link']

for name in names:
g1[name] = g1

del g1[names]

for name in names:
self.assertTrue(name not in g1)

f.close()

def test_link_multi_create(self):
Expand Down Expand Up @@ -521,6 +532,17 @@ def test_link_get_multi(self):
link = links[name]
self.assertEqual(link.id, group_id)

# Retrieve a set of links by name
names = ["link" + str(i) for i in range(5, 15)]
links_out = g1.get(names, getlink=True)

self.assertEqual(len(links_out), 10)

for name in names:
self.assertTrue(name in links_out)
link = links_out[name]
self.assertEqual(link.id, g1.id.uuid)


class TestTrackOrder(TestCase):

Expand Down

0 comments on commit db1cdcd

Please sign in to comment.