Coverage for farmbot_sidecar_starter_pack/state.py: 100%
57 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-09-01 12:19 -0700
« prev ^ index » next coverage.py v7.4.4, created at 2024-09-01 12:19 -0700
1"""State management."""
3import json
4import inspect
5from datetime import datetime
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
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})"
27class State():
28 """State class."""
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."
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.json_printing = True
39 self.timeout = {
40 "api": 15,
41 "listen": 15,
42 "movements": 120,
43 }
44 self.test_env = False
45 self.ssl = True
46 self.min_call_stack_depth = 100
47 self.dry_run = False
49 def print_status(self, endpoint_json=None, description=None, update_only=False, end="\n"):
50 """Handle changes to output based on user-defined verbosity."""
51 depth = get_call_stack_depth()
52 if depth < self.min_call_stack_depth:
53 self.min_call_stack_depth = depth
54 top = depth == self.min_call_stack_depth
55 no_end = end == "" and description != ""
56 indent = "" if (top or no_end) else " " * 4
58 if self.verbosity >= 2 and not update_only:
59 if top:
60 print()
61 function = get_function_call_info()
62 print(f"{indent}`{function}` called at {datetime.now()}")
63 if self.verbosity >= 1:
64 if self.verbosity == 1 and not update_only and top:
65 print()
66 if description is not None:
67 print(indent + description, end=end, flush=(end == ""))
68 if endpoint_json is not None and self.json_printing:
69 json_str = json.dumps(endpoint_json, indent=4)
70 indented_str = indent + json_str.replace("\n", "\n" + indent)
71 print(indented_str)
73 def check_token(self):
74 """Ensure the token persists throughout sidecar."""
76 if self.token is None:
77 self.print_status(description=self.NO_TOKEN_ERROR)
78 self.error = self.NO_TOKEN_ERROR
79 raise ValueError(self.NO_TOKEN_ERROR)