b4148890aa31e547879d940f5aa1ce9ff46bb742
[arvados.git] / sdk / python / arvados / vocabulary.py
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: Apache-2.0
4
5 import logging
6
7 from . import api
8
9 _logger = logging.getLogger('arvados.vocabulary')
10
11 def load_vocabulary(api_client=api('v1')):
12     """Load the Arvados vocabulary from the API.
13     """
14     return Vocabulary(api_client.vocabulary())
15
16 class Vocabulary(object):
17     def __init__(self, voc_definition={}):
18         self.strict_keys = voc_definition.get('strict_tags', False)
19         self.key_aliases = {}
20
21         for key_id, val in voc_definition.get('tags', {}).items():
22             strict = val.get('strict', False)
23             key_labels = [l['label'] for l in val.get('labels', [])]
24             values = {}
25             for v_id, v_val in val.get('values', {}).items():
26                 labels = [l['label'] for l in v_val.get('labels', [])]
27                 values[v_id] = VocabularyValue(v_id, labels)
28             vk = VocabularyKey(key_id, key_labels, values, strict)
29             self.key_aliases[key_id.lower()] = vk
30             for alias in vk.aliases:
31                 self.key_aliases[alias.lower()] = vk
32
33     def __getitem__(self, key):
34         return self.key_aliases[key.lower()]
35
36     def convert_to_identifiers(self, obj={}):
37         """Translate key/value pairs to machine readable identifiers.
38         """
39         if not isinstance(obj, dict):
40             raise ValueError("obj must be a dict")
41         r = {}
42         for k, v in obj.items():
43             k_id, v_id = k, v
44             try:
45                 k_id = self[k].identifier
46                 try:
47                     v_id = self[k][v].identifier
48                 except KeyError:
49                     pass
50             except KeyError:
51                 pass
52             r[k_id] = v_id
53         return r
54
55     def convert_to_labels(self, obj={}):
56         """Translate key/value pairs to human readable labels.
57         """
58         if not isinstance(obj, dict):
59             raise ValueError("obj must be a dict")
60         r = {}
61         for k, v in obj.items():
62             k_lbl, v_lbl = k, v
63             try:
64                 k_lbl = self[k].preferred_label
65                 try:
66                     v_lbl = self[k][v].preferred_label
67                 except KeyError:
68                     pass
69             except KeyError:
70                 pass
71             r[k_lbl] = v_lbl
72         return r
73
74 class VocabularyData(object):
75     def __init__(self, identifier, aliases=[]):
76         self.identifier = identifier
77         self.aliases = aliases
78
79     def __getattribute__(self, name):
80         if name == 'preferred_label':
81             return self.aliases[0]
82         return super(VocabularyData, self).__getattribute__(name)
83
84 class VocabularyValue(VocabularyData):
85     def __init__(self, identifier, aliases=[]):
86         super(VocabularyValue, self).__init__(identifier, aliases)
87
88 class VocabularyKey(VocabularyData):
89     def __init__(self, identifier, aliases=[], values={}, strict=False):
90         super(VocabularyKey, self).__init__(identifier, aliases)
91         self.strict = strict
92         self.value_aliases = {}
93         for v_id, v_val in values.items():
94             self.value_aliases[v_id.lower()] = v_val
95             for v_alias in v_val.aliases:
96                 self.value_aliases[v_alias.lower()] = v_val
97
98     def __getitem__(self, key):
99         return self.value_aliases[key.lower()]