Coverage for farmbot_sidecar_starter_pack/state.py: 100%

56 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-08-31 13:41 -0700

1"""State management.""" 

2 

3import json 

4import inspect 

5from datetime import datetime 

6 

7def get_call_stack_depth(): 

8 """Return the depth of the current call stack.""" 

9 depth = 0 

10 frame = inspect.currentframe() 

11 while frame: 

12 depth += 1 

13 frame = frame.f_back 

14 return depth 

15 

16def get_function_call_info(): 

17 """Return the name and given arguments of the function where this is called.""" 

18 # back to print_status then back to the function that called print_status 

19 frame = inspect.currentframe().f_back.f_back 

20 func_name = frame.f_code.co_name 

21 args, _, _, values = inspect.getargvalues(frame) 

22 arg_strings = [f"{arg}={repr(values[arg])}" for arg in args if arg != "self"] 

23 arg_str = ", ".join(arg_strings) 

24 return f"{func_name}({arg_str})" 

25 

26 

27class State(): 

28 """State class.""" 

29 

30 NO_TOKEN_ERROR = "ERROR: You have no token, please call `get_token` using your login credentials and the server you wish to connect to." 

31 

32 def __init__(self): 

33 self.token = None 

34 self.error = None 

35 self.last_messages = {} 

36 self.last_published = {} 

37 self.verbosity = 2 

38 self.broker_listen_duration = 15 

39 self.test_env = False 

40 self.ssl = True 

41 self.min_call_stack_depth = 100 

42 self.dry_run = False 

43 

44 def print_status(self, endpoint_json=None, description=None, update_only=False, end="\n"): 

45 """Handle changes to output based on user-defined verbosity.""" 

46 depth = get_call_stack_depth() 

47 if depth < self.min_call_stack_depth: 

48 self.min_call_stack_depth = depth 

49 top = depth == self.min_call_stack_depth 

50 no_end = end == "" and description != "" 

51 indent = "" if (top or no_end) else " " * 4 

52 

53 if self.verbosity >= 2 and not update_only: 

54 if top: 

55 print() 

56 function = get_function_call_info() 

57 print(f"{indent}`{function}` called at {datetime.now()}") 

58 if self.verbosity >= 1: 

59 if self.verbosity == 1 and not update_only and top: 

60 print() 

61 if description is not None: 

62 print(indent + description, end=end, flush=(end == "")) 

63 if endpoint_json: 

64 json_str = json.dumps(endpoint_json, indent=4) 

65 indented_str = indent + json_str.replace("\n", "\n" + indent) 

66 print(indented_str) 

67 

68 def check_token(self): 

69 """Ensure the token persists throughout sidecar.""" 

70 

71 if self.token is None: 

72 self.print_status(description=self.NO_TOKEN_ERROR) 

73 self.error = self.NO_TOKEN_ERROR 

74 raise ValueError(self.NO_TOKEN_ERROR)