From cc56a7dd2b97228f826268c5fcc1fec7b85d3606 Mon Sep 17 00:00:00 2001
From: vermeul <swen@ethz.ch>
Date: Mon, 1 Oct 2018 00:15:18 +0200
Subject: [PATCH] better handling of tags, sample.container

---
 pybis/src/python/pybis/dataset.py |  8 ++--
 pybis/src/python/pybis/pybis.py   | 69 +++++++++++++++++++++----------
 pybis/src/python/pybis/sample.py  | 13 +++---
 3 files changed, 60 insertions(+), 30 deletions(-)

diff --git a/pybis/src/python/pybis/dataset.py b/pybis/src/python/pybis/dataset.py
index f90c837efb8..e1aff9ace2a 100755
--- a/pybis/src/python/pybis/dataset.py
+++ b/pybis/src/python/pybis/dataset.py
@@ -67,10 +67,10 @@ class DataSet(OpenBisObject):
     def __dir__(self):
         return [
             'props', 
-            'get_parents()', 'add_parents()', 'del_parents()', 
-            'get_children()', 'add_children()', 'del_children()',
-            'get_containers()', 'add_containers()', 'del_containers()',
-            'get_components()', 'add_components()', 'del_components()',
+            'get_parents()', 'get_children()', 'get_components()', 'get_containers()',
+            'add_parents()', 'add_children()', 'add_components()', 'add_containers()', 
+            'del_parents()', 'del_children()', 'del_components()', 'del_containers()',
+            'set_parents()', 'set_children()', 'set_components()', 'set_containers()',
             'sample', 
             'experiment', 
             'physicalData',
diff --git a/pybis/src/python/pybis/pybis.py b/pybis/src/python/pybis/pybis.py
index e20e2817fb9..c786c63c3af 100644
--- a/pybis/src/python/pybis/pybis.py
+++ b/pybis/src/python/pybis/pybis.py
@@ -131,6 +131,19 @@ def _type_for_id(ident, entity):
         "@type": "as.dto.sample.id.SamplePermId"
     }
     """
+    # Tags have strange permIds...
+    if entity.lower() == 'tag':
+        if '/' in ident:
+            return {
+                "permId": ident,
+                "@type" : "as.dto.tag.id.TagPermId"
+            }
+        else:
+            return {
+                "code": ident,
+                "@type": "as.dto.tag.id.TagCode"
+            }
+
     entities = {
         "sample"            : "Sample",
         "dataset"           : "DataSet",
@@ -2029,49 +2042,63 @@ class Openbis:
         }
 
         resp = self._post_request(self.as_v3, request)
-        attrs = ['permId', 'code', 'description', 'owner', 'private', 'registrationDate']
-        if len(resp['objects']) == 0:
-            tags = DataFrame(columns = attrs)
-        else: 
-            objects = resp['objects']
-            parse_jackson(resp)
-            tags = DataFrame(objects)
-            tags['registrationDate'] = tags['registrationDate'].map(format_timestamp)
-            tags['permId'] = tags['permId'].map(extract_permid)
-            tags['description'] = tags['description'].map(lambda x: '' if x is None else x)
-            tags['owner'] = tags['owner'].map(extract_person)
-
-        return Things(self, 'tag', tags[attrs], 'permId')
+        return self._tag_list_for_response(response=resp['objects'])
 
 
     def get_tag(self, permId, only_data=False):
         """ Returns a specific tag
         """
-        fetchopts = {}
 
+        just_one = True
+        identifiers = []
+        if isinstance(permId, list):
+            just_one = False
+            for ident in permId:
+                identifiers.append(_type_for_id(ident, 'tag'))
+        else:
+            identifiers.append(_type_for_id(permId, 'tag'))
+
+        fetchopts = fetch_option['tag']
+        for option in ['owner']:
+            fetchopts[option] = fetch_option[option]
         request = {
             "method": "getTags",
             "params": [
                 self.token,
-                [{
-                    "permId": permId,
-                    "@type": "as.dto.tag.id.TagPermId"
-                }],
+                identifiers,
                 fetchopts
             ],
         }
 
         resp = self._post_request(self.as_v3, request)
 
-        if resp is None or len(resp) == 0:
-            raise ValueError('no such tag: ' + permId)
-        else:
+        if just_one:
+            if len(resp) == 0:
+                raise ValueError('no such tag found: {}'.format(permId))
+
             parse_jackson(resp)
             for permId in resp:
                 if only_data:
                     return resp[permId]
                 else:
                     return Tag(self, data=resp[permId])
+        else:
+            return self._tag_list_for_response(response=list(resp.values()))
+
+    def _tag_list_for_response(self, response):
+
+        parse_jackson(response)
+        attrs = ['permId', 'code', 'description', 'owner', 'private', 'registrationDate']
+        if len(response) == 0:
+            tags = DataFrame(columns = attrs)
+        else: 
+            tags = DataFrame(response)
+            tags['registrationDate'] = tags['registrationDate'].map(format_timestamp)
+            tags['permId']           = tags['permId'].map(extract_permid)
+            tags['description']      = tags['description'].map(lambda x: '' if x is None else x)
+            tags['owner']            = tags['owner'].map(extract_person)
+
+        return Things(self, 'tag', tags[attrs], 'permId')
 
 
     def search_semantic_annotations(self, permId=None, entityType=None, propertyType=None, only_data = False):
diff --git a/pybis/src/python/pybis/sample.py b/pybis/src/python/pybis/sample.py
index ca8aee02d69..63fcdb5371a 100644
--- a/pybis/src/python/pybis/sample.py
+++ b/pybis/src/python/pybis/sample.py
@@ -64,8 +64,10 @@ class Sample(OpenBisObject):
             'get_parents()', 'get_children()', 'get_components()',
             'add_parents()', 'add_children()', 'add_components()', 
             'del_parents()', 'del_children()', 'del_components()',
-            'get_datasets()', 'get_experiment()', 'get_container()',
-            'space', 'project', 'experiment', 'tags',
+            'set_parents()', 'set_children()', 'set_components()',
+            'get_datasets()', 
+            'get_experiment()', 
+            'space', 'project', 'experiment', 'container', 'tags',
             'set_tags()', 'add_tags()', 'del_tags()',
             'add_attachment()', 'get_attachments()', 'download_attachments()',
             'save()', 'delete()'
@@ -138,15 +140,16 @@ class Sample(OpenBisObject):
     def get_projects(self, **kwargs):
         return self.openbis.get_project(withSamples=[self.permId], **kwargs)
 
-    def get_experiment(self):
+    @property
+    def experiment(self):
         try:
             return self.openbis.get_experiment(self._experiment['identifier'])
         except Exception:
             pass
 
     @property
-    def experiment(self):
+    def container(self):
         try:
-            return self.openbis.get_experiment(self._experiment['identifier'])
+            return self.openbis.get_sample(self._container['identifier'])
         except Exception:
             pass
-- 
GitLab