DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
configuration_handler.py
Go to the documentation of this file.
1import os
2from typing import Dict, List
3
4import conffwk
5
6
8 # Contains the full configuration of a single configuration instance
9 def __init__(self, configuration_file_name: str):
10 """Configuration handler object, essentially a wrapper around a conffwk.Configuration object
11
12 Arguments:
13 configuration_file_name -- name of the configuration .database.xml file to open
14 """
15
16 # Load configuration
17 self._configuration = self.__open_configuration(configuration_file_name)
18
19 # To be filled with ALL config objects (as DALs)
20 self._loaded_dals = []
21 # Fills self._loaded_dals,
23
24 def __open_configuration(self, configuration_file_name: str)->conffwk.Configuration:
25 '''Opens configuration object safely '''
26 if not os.path.isfile(configuration_file_name):
27 raise Exception(f"Cannot find file: {configuration_file_name}")
28
29 try:
30 configuration = conffwk.Configuration(f"oksconflibs:{configuration_file_name}")
31 except Exception as e:
32 raise e
33
34 return configuration
35
36 def __cache_all_conf_objects(self)->None:
37 """Adds all loaded dals to self._loaded_dals
38 """
39 for conf_class in self._configuration.classes():
40 for conf_obj in self._configuration.get_dals(conf_class):
41 if conf_obj in self._loaded_dals: continue
42
43 self._loaded_dals.append(conf_obj)
44
45 #============================== Getters + Setters ==============================#
46 def get_relationships_for_conf_object(self, conf_object: object) -> List[Dict[str, object]]:
47 """For a given configuration object, return all related objects
48
49 Arguments:
50 conf_object -- configuration DAL object
51
52 Returns:
53 List of related objects
54 """
55 relations = self.get_related_classes(conf_object.className())
56
57 relations_list = []
58
59 # Loop over relations
60 for rel, rel_info in relations.items():
61 rel_val = getattr(conf_object, rel)
62 # Hacky but pybind got fussy about casting list(dal)
63 if not isinstance(rel_val, list):
64 rel_val = [rel_val]
65
66 relations_list.append({rel: [v for v in rel_val if v is not None], 'rel_info': rel_info})
67
68 return relations_list
69
70 def get_conf_objects_class(self, conf_class: str) -> List[object]:
71 """Get all configuration objects of a given class
72
73 Arguments:
74 conf_class -- Coniguration class to get objects of
75
76 Returns:
77 List of configuration objects of the given class
78 """
79 return self._configuration.get_dals(conf_class)
80
81 def get_all_conf_classes(self) -> Dict[str, List[object]]:
82 """Gets all classes + objects of that class in the configuration
83
84 Returns:
85 dictionary of class : dal objects
86 """
87 return {conf_class: self.get_conf_objects_class(conf_class)
88 for conf_class in self._configuration.classes()}
89
90 def get_related_classes(self, class_id: str)->List[str]:
91 """Get all related to classes to a given input class
92
93 Arguments:
94 class_id -- Name of class
95
96 Returns:
97 List of all related classses
98 """
99 return self._configuration.relations(class_id, True)
100
101 def get_inherited_classes(self, class_id: str)->List[str]:
102 inherited_classes = [class_ for class_ in self._configuration.classes()\
103 if self._configuration.is_subclass(class_, class_id)]
104 return inherited_classes
105
106
107 @property
108 def configuration(self)->conffwk.Configuration:
109 """Access the underlying configuration object
110 """
111 return self._configuration
112
113 @configuration.setter
114 def configuration(self)->None:
115 """dummy method in case I try to do something silly
116 """
117 raise NotImplementedError(f"Configuration object is not mutable, please create new object")
118
119 @property
120 def conf_obj_list(self):
121 """List of loaded in dals
122 """
123 return self._loaded_dals
124
125 def get_obj(self, class_id: str, uid: str) -> object:
126 """Get a particular configuration object
127
128 Arguments:
129 class_id -- Class name
130 uid -- Unique object ID
131
132 Returns:
133 DAL object satisfying the input
134 """
135 return self.configuration.get_obj(class_id, uid)
136
137 def commit(self, update_message: str) -> None:
138 """Commit changes to the database
139
140 Arguments:
141 update_message -- Add message to the update
142 """
143 self.configuration.commit(update_message)
144
145 @property
146 def n_dals(self)->int:
147 """Lists the total number of loaded objects
148 _description_
149 """
150 return len(self._loaded_dals)
151
152 def add_new_conf_obj(self, class_id: str, uid: str) -> None:
153 """Add new configuration object
154
155 Arguments:
156 class_id -- Class name
157 uid -- Unique object ID
158 """
159 self.configuration.create_obj(class_id, uid, at=self.configuration.active_database)
160 config_as_dal = self.configuration.get_dal(class_id, uid)
161 self.configuration.update_dal(config_as_dal)
162 self._loaded_dals.append(config_as_dal)
163
164 def destroy_conf_obj(self, class_id: str, uid: str) -> None:
165 """Destroy a configuration object
166
167 Arguments:
168 class_id -- class name
169 uid -- unique object ID
170 """
171 dal = self.configuration.get_dal(class_id, uid)
172 self.configuration.destroy_dal(dal)
173 self._loaded_dals.remove(dal)
174
176 self,
177 class_id: str,
178 uid: str,
179 relationship_name: str,
180 updated_value: object,
181 append: bool = False,
182 ) -> None:
183 """Modify TODO: EDIT THIS
184
185 :param class_id: _description_
186 :type class_id: _type_
187 :param uid: _description_
188 :type uid: _type_
189 :param relationship_name: _description_
190 :type relationship_name: str
191 :param updated_value: _description_
192 :type updated_value: _type_
193 :param append: _description_, defaults to False
194 :type append: bool, optional
195 """
196 # Firstly we need to find the relationship this is referring to
197 selected_dal = self.configuration.get_dal(class_id, uid)
198 # Okay need a better way of doing this...
199 rel_list = self.get_relationships_for_conf_object(selected_dal)
200
201 for relations in rel_list:
202 # Need to find our dal
203 if list(relations.keys())[0] != relationship_name:
204 continue
205
206 # Next we need to check the type of our object is okay
207 if updated_value not in self.get_conf_objects_class(relations['rel_info']['type']):
208 raise Exception(updated_value)
209 # raise TypeError(f"Cannot use object {updated_value} for relation expecting type {relations['rel_info']['type']}")
210
211 # Need to make sure everything is typed correctly
212 if append and relations['rel_info']['multivalue']:
213 rel = list(relations.items)[0]
214 rel.append(updated_value)
215
216 elif relations['rel_info']['multivalue']:
217 rel = [updated_value]
218 else:
219 rel = updated_value
220
221 # Should update the dal
222 setattr(selected_dal, relationship_name, rel)
223 self.configuration.update_dal(selected_dal)
224
225
226 return
227
228 raise RuntimeError(f"Cannot find relationship with name {relationship_name}")
conffwk.Configuration __open_configuration(self, str configuration_file_name)
List[Dict[str, object]] get_relationships_for_conf_object(self, object conf_object)
None modify_relationship(self, str class_id, str uid, str relationship_name, object updated_value, bool append=False)