Terarea  2
The automation project
Loading...
Searching...
No Matches
variables.py
Go to the documentation of this file.
1"""_summary_
2 File in charge of tracking the variables for the current action.
3"""
4
5from typing import Dict, Any, Type, Union
6import base64
7from display_tty import Disp, TOML_CONF, FILE_DESCRIPTOR, SAVE_TO_FILE, FILE_NAME
8
9
10class ScopeError(Exception):
11 """Custom exception to handle scope-related errors."""
12
13 def __init__(self, message="There is a problem with the scope."):
14 super().__init__(message)
15
16
17class VariableNotFoundError(Exception):
18 """Custom exception to handle variable-related errors."""
19
20 def __init__(self, message="The variable was not found."):
21 super().__init__(message)
22
23
25 """_summary_
26 """
27
28 def __init__(self, success: int = 0, error: int = 84, debug: bool = False):
29 """_summary_
30 Class in charge of storing and restoring variables.
31
32 Args:
33 success (int, optional): _description_. Defaults to 0.
34 error (int, optional): _description_. Defaults to 84.
35 debug (bool, optional): _description_. Defaults to False.
36 """
37 # -------------------------- Inherited values --------------------------
38 self.success: int = success
39 self.error: int = error
40 self.debug: bool = debug
41 # -------------- The variable tracking runtime variables --------------
42 self.variablesvariables: Dict[str, Dict[str, Any]] = {}
43 # ---------------------- The visual logger class ----------------------
44 self.disp: Disp = Disp(
45 TOML_CONF,
46 SAVE_TO_FILE,
47 FILE_NAME,
48 FILE_DESCRIPTOR,
49 debug=self.debug,
50 logger=self.__class__.__name__
51 )
52
53 def __del__(self) -> None:
54 """_summary_
55 Destructor for the class.
56 """
57 title = "__del__"
58 self.disp.log_debug("Clearing content", title)
59 self.clear_scopes()
60 self.disp.log_debug("Scopes cleared", title)
61
62 def create_scope(self, scope_name: Any) -> int:
63 """_summary_
64 Create a new scope.
65
66 Args:
67 scope_name (Any): _description_: The name of the scope.
68
69 Returns:
70 int: _description_: Returns self.success if it succeeds, self.error otherwise.
71 """
72 title = "create_scope"
73 if scope_name in self.variablesvariables:
74 self.disp.log_warning(
75 f"Scope {scope_name} already present.", title
76 )
77 return self.error
78 self.variablesvariables[scope_name] = {}
79 self.disp.log_debug(f"Scope {scope_name} created.", title)
80 return self.success
81
82 def add_variable(self, name: str, variable_data: Any, variable_type: Type = str, scope: Any = "default_scope") -> int:
83 """_summary_
84 Add a variable to the current action.
85
86 Args:
87 name (str): _description_: The name of the variable
88 variable_data (Any): _description_: The data of the given variable
89 variable_type (Type): _description_: The type of the data
90 scope (str, optional): _description_: The scope of the variable, defaults to "default_scope"
91
92 Raises:
93 TypeError: _description_: If the type of the variable is incorrect.
94
95 Returns:
96 int: _description_: Returns self.success if it succeeds, self.error otherwise.
97 """
98 title = "add_variable"
99 if scope not in self.variablesvariables:
100 self.disp.log_warning(
101 f"scope {scope} not present, creating", title
102 )
103 self.variablesvariables[scope] = {}
104 if name in self.variablesvariables[scope]:
105 self.disp.log_error(f"Variable: {name} is already present.", title)
106 return self.error
107 if isinstance(variable_data, variable_type) is False:
108 msg = f"Incorrect type for variable {name}."
109 self.disp.log_error(msg, title)
110 raise TypeError(msg)
111 self.variablesvariables[scope][name] = {
112 "data": variable_data, "type": variable_type
113 }
114 msg = f"Variable: {name} of type {variable_type}"
115 msg += f" containing {variable_data} successfully added"
116 msg += f" to scope {scope}."
117 self.disp.log_debug(msg, title)
118 return self.success
119
120 def update_variable(self, name: str, variable_data: Any, variable_type: Type = str, scope: Any = "default_scope") -> int:
121 """_summary_
122 Update the variable from the current action.
123
124 Args:
125 name (str): _description_: The name of the variable
126 variable_data (Any): _description_: The data of the given variable
127 variable_type (Type): _description_: The type of the data
128 scope (str, optional): _description_: The scope in which the data is stored. Defaults to "default_scope"
129
130 Raises:
131 ScopeError: _description_: If the scope is not found.
132 VariableNotFoundError: _description_: If the variable is not found.
133 TypeError: _description_: If the type of the variable is incorrect
134
135 Returns:
136 int: _description_: Returns self.success if it succeeds, self.error otherwise.
137 """
138 title = "update_variable"
139 if scope not in self.variablesvariables:
140 msg = f"Scope {scope} not found."
141 self.disp.log_error(msg, title)
142 raise ScopeError(msg)
143 if name not in self.variablesvariables[scope]:
144 msg = f"Variable: {name} is not present."
145 self.disp.log_error(msg, title)
146 raise VariableNotFoundError(msg)
147 if isinstance(variable_data, variable_type) is False:
148 msg = f"Incorrect type for variable {name}."
149 self.disp.log_error(msg, title)
150 raise TypeError(msg)
151 self.variablesvariables[name] = {"data": variable_data, "type": variable_type}
152 msg = f"Variable: {name} of type {variable_type}"
153 msg += f" containing {variable_data} successfully added"
154 msg += f" to scope {scope}."
155 self.disp.log_debug(msg, title)
156 return self.success
157
158 def insert_or_update(self, name: str, variable_data: Any, variable_type: Type = str, scope: Any = "default_scope") -> int:
159 """_summary_
160 Insert or update the variable from the current action.
161
162 Args:
163 name (str): _description_: The name of the variable
164 variable_data (Any): _description_: The data of the given variable
165 variable_type (Type): _description_: The type of the data
166 scope (str, optional): _description_: The scope in which the data is stored. Defaults to "default_scope"
167
168 Raises:
169 ValueError: _description_: If the variable does not exist.
170 TypeError: _description_: If the type of the variable is incorrect
171 ScopeError: _description_: If the scope is not found.
172 VariableNotFoundError: _description_: If the variable is not found.
173
174 Returns:
175 int: _description_: Returns self.success if it succeeds, self.error otherwise.
176 """
177 title = "insert_or_update"
178 if scope not in self.variablesvariables:
179 self.disp.log_warning(
180 "Scope is not present in the list, adding.", title
181 )
182 return self.add_variable(name, variable_data, variable_type, scope)
183 if name in self.variablesvariables[scope]:
184 self.disp.log_debug(
185 "Variable is already present in the list, updating.", title
186 )
187 return self.update_variable(name, variable_data, variable_type, scope)
188 self.disp.log_debug(
189 "Variable is not present in the list, adding.", title
190 )
191 return self.add_variable(name, variable_data, variable_type, scope)
192
193 def has_variable(self, name: str, scope: Any = "default_scope") -> bool:
194 """_summary_
195 Check if the variable exists in the current action.
196
197 Args:
198 name (str): _description_: The name of the variable
199 scope (str, optional): _description_: The scope in which we wish to search for the variable. Enter '*' to search all the variable scopes. Defaults to "default_scope"
200
201 Raises:
202 ScopeError: _description_: If the scope is not found.
203
204 Returns:
205 bool: _description_: Returns True if the variable exists, False otherwise.
206 """
207 title = "has_variable"
208 self.disp.log_debug(f"Checking if variable {name} exists.", title)
209 if scope == "*":
210 for key, value in self.variablesvariables.items():
211 if name in value:
212 self.disp.log_debug(
213 f"Variable {name} exists in scope {key}.", title
214 )
215 return True
216 self.disp.log_debug(
217 f"Variable {name} does not exist in any scopes.", title
218 )
219 return False
220 if scope not in self.variablesvariables:
221 msg = f"Scope {scope} not found."
222 self.disp.log_debug(msg, title)
223 raise ScopeError(msg)
224 if name not in self.variablesvariables[scope]:
225 self.disp.log_debug(f"Variable {name} does not exist.", title)
226 return False
227 self.disp.log_debug(f"Variable {name} exists.", title)
228 return True
229
230 def get_variable(self, name: str, scope: Any = "default_scope") -> Any:
231 """_summary_
232 Get the variable from the current action.
233
234 Args:
235 name (str): _description_: The name of the variable
236 scope (str, optional): _description_: The scope in which to get the variable. Defaults to "default_scope".
237
238 Raises:
239 ScopeError: _description_: If the scope is not found.
240 ValueError: _description_: If the variable does not exist.
241
242 Returns:
243 Any: _description_: Returns the variable if it exists, self.error otherwise.
244 """
245 title = "get_variable"
246 if scope not in self.variablesvariables:
247 msg = f"Scope {scope} not found."
248 self.disp.log_error(msg, title)
249 raise ScopeError(msg)
250 if name not in self.variablesvariables[scope]:
251 msg = f"Variable {name} not found."
252 self.disp.log_error(msg, title)
253 raise ValueError(msg)
254 self.disp.log_debug(f"Variable {name} found.", title)
255 return self.variablesvariables[scope][name]["data"]
256
257 def get_variables(self, scope: Any = "default_scope") -> Dict[str, Any]:
258 """_summary_
259 Get all the variables from the current action.
260
261 Args:
262 scope (str, optional): _description_: The scope in which to get the variables. User '*' to return all the vairables from all the scopes. Defaults to "default_scope".
263
264 Raises:
265 ScopeError: _description_: If the scope is not found.
266
267 Returns:
268 Dict[str, Any]: _description_: Returns all the variables.
269 """
270 title = "get_variables"
271 if scope == "*":
272 self.disp.log_debug("Returning all the variables.", title)
273 return self.variablesvariables.copy()
274 if scope not in self.variablesvariables:
275 msg = f"Scope {scope} not found."
276 self.disp.log_error(msg, title)
277 raise ScopeError(msg)
278 return self.variablesvariables[scope]
279
280 def get_scope(self, scope: Any = "default_scope") -> Dict[str, Any]:
281 """_summary_
282 The function in charge of returning the content of a scope.
283 This function is just there for program logic.
284 This is function behaves the exact same way as the get_variables function.
285
286 Args:
287 scope (str, optional): _description_: The scope in which to get the variables. User '*' to return all the vairables from all the scopes. Defaults to "default_scope".
288
289 Raises:
290 ScopeError: _description_: If the scope is not found.
291
292 Returns:
293 Dict[str, Any]: _description_: Returns all the variables.
294 """
295 return self.get_variables(scope=scope)
296
297 def get_variable_type(self, name: str, scope: Any = "default_scope") -> Union[int, Type]:
298 """_summary_
299 Get the type of the variable from the current action.
300
301 Args:
302 name (str): _description_: The name of the variable
303 scope (str, optional): _description_: The scope in which to get the variable. Defaults to "default_scope".
304
305 Raises:
306 ScopeError: _description_: If the scope is not
307 ValueError: _description_: If the variable does not exist.
308
309 Returns:
310 Type: _description_: Returns the type of the variable if it exists, self.error otherwise.
311 """
312 title = "get_variable_type"
313 if scope not in self.variablesvariables:
314 msg = f"Scope {scope} not found."
315 self.disp.log_error(msg, title)
316 raise ScopeError(msg)
317 if name not in self.variablesvariables[scope]:
318 msg = f"Variable {name} does not exist in scope {scope}."
319 self.disp.log_error(msg, title)
320 raise ValueError(msg)
321 self.disp.log_debug(f"Retrieving type for {name}", title)
322 return self.variablesvariables[scope][name]["type"]
323
324 def remove_variable(self, name: str, scope: Any = "default_scope") -> int:
325 """_summary_
326 Remove the variable from the current action.
327
328 Args:
329 name (str): _description_: The name of the variable
330 scope (str, optional): _description_: The scope in which the variable is stored. Defaults to "default_scope".
331
332 Raises:
333 ScopeError: _description_: If the scope is not found.
334 VariableNotFoundError: _description_: If the variable is not found.
335
336 Returns:
337 int: _description_: Returns self.success if it succeeds, self.error otherwise.
338 """
339 title = "remove_variable"
340 msg = f"Removing variable {name} from the scope {scope}"
341 msg += " if present."
342 self.disp.log_debug(msg, title)
343 if scope not in self.variablesvariables:
344 msg = f"Scope {scope} not found."
345 self.disp.log_error(msg, title)
346 raise ScopeError(msg)
347 if name not in self.variablesvariables[scope]:
348 msg = f"Variable {name} is not present"
349 msg += f" in scope {scope}."
350 self.disp.log_error(msg, title)
351 raise VariableNotFoundError(msg)
352 msg = f"Removing variable {name} "
353 msg += f"from the scope {scope}."
354 self.disp.log_debug(msg, title)
355 del self.variablesvariables[scope][name]
356 return self.success
357
358 def clear_variables(self, scope: Any = "default_scope") -> int:
359 """_summary_
360 Clear all the variables from the current action.
361
362 Args:
363 scope (str, optional): _description_: The scope in which to clear the variables. Enter '*' to clear the content of all the scopes. Defaults to "default_scope".
364
365 Returns:
366 int: _description_: Returns self.success if it succeeds, self.error otherwise.
367 """
368 title = "clear_variables"
369 self.disp.log_debug(
370 f"Clearing all the variables in scope {scope}.", title
371 )
372 if scope == "*":
373 for i in self.variablesvariables:
374 self.disp.log_debug(f"Clearing content for scope {i}", title)
375 self.variablesvariables[i] = {}
376 self.disp.log_debug("All the variables have been cleared.", title)
377 return self.success
378 if scope not in self.variablesvariables:
379 msg = f"Scope {scope} not found."
380 self.disp.log_error(msg, title)
381 raise ScopeError(msg)
382 self.variablesvariables[scope] = {}
383 self.disp.log_debug(
384 f"All the variables have been cleared for scope {scope}.", title
385 )
386 return self.success
387
388 def clear_scopes(self) -> int:
389 """_summary_
390 Clear all the scopes from the current action.
391
392 Returns:
393 int: _description_
394 """
395 title = "clear_scopes"
396 self.disp.log_debug("Clearing all the scopes.", title)
397 self.variablesvariables = {}
398 self.disp.log_debug("All the scopes have been cleared.", title)
399 return self.success
400
401 def clear_scope_contents(self) -> int:
402 """_summary_
403 Clear all the scopes content from the current action.
404
405 Returns:
406 int: _description_
407 """
408 title = "clear_scope_contents"
409 self.disp.log_debug("Clearing all the scopes.", title)
410 for i in self.variablesvariables:
411 self.disp.log_debug(f"Clearing content for scope {i}", title)
412 self.variablesvariables[i] = {}
413 self.disp.log_debug("All the scopes have been cleared.", title)
414 return self.success
415
416 def remove_scope(self, scope: Any) -> int:
417 """_summary_
418 Remove the scope from the current action.
419
420 Args:
421 scope (str): _description_: The scope to remove.
422
423 Raises:
424 ScopeError: _description_: If the scope is not found.
425
426 Returns:
427 int: _description_: Returns self.success if it succeeds, self.error otherwise.
428 """
429 title = "remove_scope"
430 self.disp.log_debug(f"Removing scope {scope}.", title)
431 if scope not in self.variablesvariables:
432 msg = f"Scope {scope} not found."
433 self.disp.log_error(msg, title)
434 raise ScopeError(msg)
435 del self.variablesvariables[scope]
436 self.disp.log_debug(f"Scope {scope} removed.", title)
437 return self.success
438
439 def sanitize_for_json(self, data_or_scope: Any, use_scope: bool = False) -> Any:
440 """_summary_
441 Sanitize the data for json serialization.
442
443 Args:
444 data (Any): _description_: The data to sanitize.
445 use_scope (bool, optional): _description_: Specify if the data to process is to be queried in the variable scopes. Default: False
446
447 Raises:
448 ScopeError: _description_: If the scope is not found.
449
450 Returns:
451 Any: _description_: The sanitized data.
452 """
453 title = "sanitize_for_json"
454 if use_scope is True:
455 if data_or_scope not in self.variablesvariables:
456 msg = f"The provided scope {data_or_scope}"
457 msg += " was not found in the current dataset."
458 self.disp.log_debug(msg, title)
459 raise ScopeError(msg)
460 self.disp.log_debug(f"Sanitising scope {data_or_scope}", title)
461 return self.sanitize_for_json(self.variablesvariables[data_or_scope], False)
462 if isinstance(data_or_scope, dict):
463 for key, value in data_or_scope.items():
464 data_or_scope[key] = self.sanitize_for_json(value)
465 elif isinstance(data_or_scope, list):
466 for index, item in enumerate(data_or_scope):
467 data_or_scope[index] = self.sanitize_for_json(item)
468 elif isinstance(data_or_scope, set):
469 data_or_scope = list(data_or_scope)
470 for index, item in enumerate(data_or_scope):
471 data_or_scope[index] = self.sanitize_for_json(item)
472 elif isinstance(data_or_scope, tuple):
473 data_or_scope = list(data_or_scope)
474 for index, item in enumerate(data_or_scope):
475 data_or_scope[index] = self.sanitize_for_json(item)
476 data_or_scope = tuple(data_or_scope)
477 elif isinstance(data_or_scope, bytes):
478 data_or_scope = base64.b64encode(data_or_scope).decode('utf-8')
479 elif isinstance(data_or_scope, (int, float, str, bool)) is False:
480 data_or_scope = str(data_or_scope)
481 return data_or_scope
__init__(self, message="There is a problem with the scope.")
Definition variables.py:13
__init__(self, message="The variable was not found.")
Definition variables.py:20
Any sanitize_for_json(self, Any data_or_scope, bool use_scope=False)
Definition variables.py:439
int clear_variables(self, Any scope="default_scope")
Definition variables.py:358
int add_variable(self, str name, Any variable_data, Type variable_type=str, Any scope="default_scope")
Definition variables.py:82
int create_scope(self, Any scope_name)
Definition variables.py:62
int remove_variable(self, str name, Any scope="default_scope")
Definition variables.py:324
Any get_variable(self, str name, Any scope="default_scope")
Definition variables.py:230
Dict[str, Any] get_variables(self, Any scope="default_scope")
Definition variables.py:257
int update_variable(self, str name, Any variable_data, Type variable_type=str, Any scope="default_scope")
Definition variables.py:120
bool has_variable(self, str name, Any scope="default_scope")
Definition variables.py:193
int insert_or_update(self, str name, Any variable_data, Type variable_type=str, Any scope="default_scope")
Definition variables.py:158
__init__(self, int success=0, int error=84, bool debug=False)
Definition variables.py:28
Dict[str, Any] get_scope(self, Any scope="default_scope")
Definition variables.py:280
Union[int, Type] get_variable_type(self, str name, Any scope="default_scope")
Definition variables.py:297
int remove_scope(self, Any scope)
Definition variables.py:416