18574: Adds conversion methods. Improves & adds tests.
[arvados.git] / sdk / python / arvados / vocabulary.py
index 8d89746ca927bc6062018b9c1094a4b25056f32d..b4148890aa31e547879d940f5aa1ce9ff46bb742 100644 (file)
@@ -15,8 +15,7 @@ def load_vocabulary(api_client=api('v1')):
 
 class Vocabulary(object):
     def __init__(self, voc_definition={}):
-        self._definition = voc_definition
-        self.strict_keys = self._definition.get('strict_tags', False)
+        self.strict_keys = voc_definition.get('strict_tags', False)
         self.key_aliases = {}
 
         for key_id, val in voc_definition.get('tags', {}).items():
@@ -26,12 +25,61 @@ class Vocabulary(object):
             for v_id, v_val in val.get('values', {}).items():
                 labels = [l['label'] for l in v_val.get('labels', [])]
                 values[v_id] = VocabularyValue(v_id, labels)
-            self.key_aliases[key_id] = VocabularyKey(key_id, key_labels, values, strict)
+            vk = VocabularyKey(key_id, key_labels, values, strict)
+            self.key_aliases[key_id.lower()] = vk
+            for alias in vk.aliases:
+                self.key_aliases[alias.lower()] = vk
+
+    def __getitem__(self, key):
+        return self.key_aliases[key.lower()]
+
+    def convert_to_identifiers(self, obj={}):
+        """Translate key/value pairs to machine readable identifiers.
+        """
+        if not isinstance(obj, dict):
+            raise ValueError("obj must be a dict")
+        r = {}
+        for k, v in obj.items():
+            k_id, v_id = k, v
+            try:
+                k_id = self[k].identifier
+                try:
+                    v_id = self[k][v].identifier
+                except KeyError:
+                    pass
+            except KeyError:
+                pass
+            r[k_id] = v_id
+        return r
+
+    def convert_to_labels(self, obj={}):
+        """Translate key/value pairs to human readable labels.
+        """
+        if not isinstance(obj, dict):
+            raise ValueError("obj must be a dict")
+        r = {}
+        for k, v in obj.items():
+            k_lbl, v_lbl = k, v
+            try:
+                k_lbl = self[k].preferred_label
+                try:
+                    v_lbl = self[k][v].preferred_label
+                except KeyError:
+                    pass
+            except KeyError:
+                pass
+            r[k_lbl] = v_lbl
+        return r
 
 class VocabularyData(object):
     def __init__(self, identifier, aliases=[]):
         self.identifier = identifier
-        self.aliases = set([x.lower() for x in aliases])
+        self.aliases = aliases
+
+    def __getattribute__(self, name):
+        if name == 'preferred_label':
+            return self.aliases[0]
+        return super(VocabularyData, self).__getattribute__(name)
 
 class VocabularyValue(VocabularyData):
     def __init__(self, identifier, aliases=[]):
@@ -40,5 +88,12 @@ class VocabularyValue(VocabularyData):
 class VocabularyKey(VocabularyData):
     def __init__(self, identifier, aliases=[], values={}, strict=False):
         super(VocabularyKey, self).__init__(identifier, aliases)
-        self.values = values
-        self.strict = strict
\ No newline at end of file
+        self.strict = strict
+        self.value_aliases = {}
+        for v_id, v_val in values.items():
+            self.value_aliases[v_id.lower()] = v_val
+            for v_alias in v_val.aliases:
+                self.value_aliases[v_alias.lower()] = v_val
+
+    def __getitem__(self, key):
+        return self.value_aliases[key.lower()]
\ No newline at end of file