ivoryos 0.1.9__py3-none-any.whl → 0.1.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ivoryos might be problematic. Click here for more details.

Files changed (37) hide show
  1. ivoryos/__init__.py +122 -99
  2. ivoryos/config.py +47 -47
  3. ivoryos/routes/auth/auth.py +100 -65
  4. ivoryos/routes/auth/templates/auth/login.html +25 -25
  5. ivoryos/routes/auth/templates/auth/signup.html +32 -32
  6. ivoryos/routes/control/control.py +400 -272
  7. ivoryos/routes/control/templates/control/controllers.html +75 -75
  8. ivoryos/routes/control/templates/control/controllers_home.html +50 -50
  9. ivoryos/routes/control/templates/control/controllers_new.html +89 -89
  10. ivoryos/routes/database/database.py +188 -114
  11. ivoryos/routes/database/templates/database/experiment_database.html +72 -72
  12. ivoryos/routes/design/design.py +543 -416
  13. ivoryos/routes/design/templates/design/experiment_builder.html +415 -415
  14. ivoryos/routes/design/templates/design/experiment_run.html +325 -325
  15. ivoryos/routes/main/main.py +42 -25
  16. ivoryos/routes/main/templates/main/help.html +141 -141
  17. ivoryos/routes/main/templates/main/home.html +68 -68
  18. ivoryos/static/.DS_Store +0 -0
  19. ivoryos/static/js/overlay.js +12 -12
  20. ivoryos/static/js/socket_handler.js +34 -34
  21. ivoryos/static/js/sortable_card.js +24 -24
  22. ivoryos/static/js/sortable_design.js +36 -36
  23. ivoryos/static/style.css +201 -201
  24. ivoryos/templates/base.html +143 -143
  25. ivoryos/utils/db_models.py +544 -518
  26. ivoryos/utils/form.py +328 -316
  27. ivoryos/utils/global_config.py +67 -67
  28. ivoryos/utils/llm_agent.py +183 -183
  29. ivoryos/utils/script_runner.py +166 -164
  30. ivoryos/utils/utils.py +437 -422
  31. ivoryos/version.py +1 -0
  32. {ivoryos-0.1.9.dist-info → ivoryos-0.1.12.dist-info}/LICENSE +21 -21
  33. {ivoryos-0.1.9.dist-info → ivoryos-0.1.12.dist-info}/METADATA +170 -169
  34. ivoryos-0.1.12.dist-info/RECORD +47 -0
  35. {ivoryos-0.1.9.dist-info → ivoryos-0.1.12.dist-info}/WHEEL +1 -1
  36. ivoryos-0.1.9.dist-info/RECORD +0 -45
  37. {ivoryos-0.1.9.dist-info → ivoryos-0.1.12.dist-info}/top_level.txt +0 -0
@@ -1,164 +1,166 @@
1
- import os
2
- import csv
3
- import threading
4
- import time
5
- from datetime import datetime
6
-
7
- from ivoryos.utils import utils
8
- from ivoryos.utils.db_models import Script
9
- from ivoryos.utils.global_config import GlobalConfig
10
-
11
- global_config = GlobalConfig()
12
- global deck
13
- deck = None
14
-
15
- class ScriptRunner:
16
- def __init__(self, globals_dict=None):
17
- if globals_dict is None:
18
- globals_dict = globals()
19
- self.globals_dict = globals_dict
20
-
21
- self.stop_event = threading.Event()
22
- self.is_running = False
23
- self.lock = threading.Lock()
24
-
25
- def reset_stop_event(self):
26
- self.stop_event.clear()
27
-
28
- def stop_execution(self):
29
- self.stop_event.set()
30
- # print("Stop pending tasks")
31
-
32
- def run_script(self, script, repeat_count=1, run_name=None, logger=None, socketio=None, config=None, bo_args=None,
33
- output_path=""):
34
- global deck
35
- if deck is None:
36
- deck = global_config.deck
37
- exec_string = script.compile()
38
- exec(exec_string)
39
- time.sleep(1)
40
- with self.lock:
41
- if self.is_running:
42
- logger.info("System is busy. Please wait for it to finish or stop it before starting a new one.")
43
- return None
44
- self.is_running = True
45
-
46
- self.reset_stop_event()
47
-
48
- thread = threading.Thread(target=self._run_with_stop_check,
49
- args=(script, repeat_count, run_name, logger, socketio, config, bo_args, output_path))
50
- thread.start()
51
- return thread
52
-
53
- def _run_with_stop_check(self, script: Script, repeat_count, run_name, logger, socketio, config, bo_args,
54
- output_path):
55
- time.sleep(1)
56
- self._emit_progress(socketio, 1)
57
- try:
58
- # Run "prep" section once
59
- script_dict = script.script_dict
60
- self._run_actions(script_dict.get("prep", []), section_name="prep", run_name=run_name, logger=logger)
61
- output_list = []
62
- _, arg_type = script.config("script")
63
- _, return_list = script.config_return()
64
- # Run "script" section multiple times
65
- if repeat_count:
66
- self._run_repeat_section(repeat_count, bo_args, output_list, return_list, run_name, logger, socketio)
67
- elif config:
68
- self._run_config_section(config, arg_type, output_list, return_list, run_name, logger, socketio)
69
- # Run "cleanup" section once
70
- self._run_actions(script_dict.get("cleanup", []), section_name="cleanup", run_name=run_name, logger=logger)
71
- # Save results if necessary
72
- if output_list:
73
- self._save_results(run_name, arg_type, return_list, output_list, logger, output_path)
74
- except Exception as e:
75
- logger.error(f"Error during script execution: {e}")
76
- finally:
77
- with self.lock:
78
- self.is_running = False # Reset the running flag when done
79
- self._emit_progress(socketio, 100)
80
-
81
- def _run_actions(self, actions, section_name="", run_name=None, logger=None):
82
- logger.info(f'Executing {section_name} steps') if actions else logger.info(f'No {section_name} steps')
83
- for action in actions:
84
- if self.stop_event.is_set():
85
- logger.info(f"Stopping execution during {section_name} section.")
86
- break
87
- logger.info(f'Executing {action.get("action", "")} action')
88
- fname = f"{run_name}_{section_name}"
89
- function = self.globals_dict[fname]
90
- function()
91
-
92
- def _run_config_section(self, config, arg_type, output_list, return_list, run_name, logger, socketio):
93
- compiled = True
94
- for i in config:
95
- try:
96
- i = utils.convert_config_type(i, arg_type)
97
- except Exception as e:
98
- logger.info(e)
99
- compiled = False
100
- break
101
- if compiled:
102
- for i, kwargs in enumerate(config):
103
- kwargs = dict(kwargs)
104
- if self.stop_event.is_set():
105
- logger.info(f'Stopping execution during {run_name}: {i + 1}/{len(config)}')
106
- break
107
- logger.info(f'Executing {i + 1} of {len(config)} with kwargs = {kwargs}')
108
- progress = (i + 1) * 100 / len(config)
109
- self._emit_progress(socketio, progress)
110
- fname = f"{run_name}_script"
111
- function = self.globals_dict[fname]
112
- output = function(**kwargs)
113
- if output:
114
- kwargs.update(output)
115
- output_list.append(kwargs)
116
-
117
- def _run_repeat_section(self, repeat_count, bo_args, output_list, return_list, run_name, logger, socketio):
118
- if bo_args:
119
- logger.info('Initializing optimizer...')
120
- ax_client = utils.ax_initiation(bo_args)
121
- for i in range(int(repeat_count)):
122
- if self.stop_event.is_set():
123
- logger.info(f'Stopping execution during {run_name}: {i + 1}/{int(repeat_count)}')
124
- break
125
- logger.info(f'Executing {run_name} experiment: {i + 1}/{int(repeat_count)}')
126
- progress = (i + 1) * 100 / int(repeat_count) - 0.1
127
- self._emit_progress(socketio, progress)
128
- if bo_args:
129
- try:
130
- parameters, trial_index = ax_client.get_next_trial()
131
- logger.info(f'Output value: {parameters}')
132
- fname = f"{run_name}_script"
133
- function = self.globals_dict[fname]
134
- output = function(**parameters)
135
- # output = eval(f"{run_name}_script(**{parameters})")
136
- ax_client.complete_trial(trial_index=trial_index, raw_data=output)
137
- except Exception as e:
138
- logger.info(f'Optimization error: {e}')
139
- break
140
- else:
141
- fname = f"{run_name}_script"
142
- function = self.globals_dict[fname]
143
- output = function()
144
-
145
- if output:
146
- output_list.append(output)
147
- logger.info(f'Output value: {output}')
148
- return output_list
149
-
150
- @staticmethod
151
- def _save_results(run_name, arg_type, return_list, output_list, logger, output_path):
152
- args = list(arg_type.keys()) if arg_type else []
153
- args.extend(return_list)
154
- filename = run_name + "_" + datetime.now().strftime("%Y-%m-%d %H-%M") + ".csv"
155
- file_path = os.path.join(output_path, filename)
156
- with open(file_path, "w", newline='') as file:
157
- writer = csv.DictWriter(file, fieldnames=args)
158
- writer.writeheader()
159
- writer.writerows(output_list)
160
- logger.info(f'Results saved to {file_path}')
161
-
162
- @staticmethod
163
- def _emit_progress(socketio, progress):
164
- socketio.emit('progress', {'progress': progress})
1
+ import os
2
+ import csv
3
+ import threading
4
+ import time
5
+ from datetime import datetime
6
+
7
+ from ivoryos.utils import utils
8
+ from ivoryos.utils.db_models import Script
9
+ from ivoryos.utils.global_config import GlobalConfig
10
+
11
+ global_config = GlobalConfig()
12
+ global deck
13
+ deck = None
14
+
15
+ class ScriptRunner:
16
+ def __init__(self, globals_dict=None):
17
+ if globals_dict is None:
18
+ globals_dict = globals()
19
+ self.globals_dict = globals_dict
20
+
21
+ self.stop_event = threading.Event()
22
+ self.is_running = False
23
+ self.lock = threading.Lock()
24
+
25
+ def reset_stop_event(self):
26
+ self.stop_event.clear()
27
+
28
+ def stop_execution(self):
29
+ self.stop_event.set()
30
+ # print("Stop pending tasks")
31
+
32
+ def run_script(self, script, repeat_count=1, run_name=None, logger=None, socketio=None, config=None, bo_args=None,
33
+ output_path=""):
34
+ global deck
35
+ if deck is None:
36
+ deck = global_config.deck
37
+ exec_string = script.compile()
38
+ exec(exec_string)
39
+ time.sleep(1)
40
+ with self.lock:
41
+ if self.is_running:
42
+ logger.info("System is busy. Please wait for it to finish or stop it before starting a new one.")
43
+ return None
44
+ self.is_running = True
45
+
46
+ self.reset_stop_event()
47
+
48
+ thread = threading.Thread(target=self._run_with_stop_check,
49
+ args=(script, repeat_count, run_name, logger, socketio, config, bo_args, output_path))
50
+ thread.start()
51
+ return thread
52
+
53
+ def _run_with_stop_check(self, script: Script, repeat_count, run_name, logger, socketio, config, bo_args,
54
+ output_path):
55
+ time.sleep(1)
56
+ self._emit_progress(socketio, 1)
57
+ try:
58
+ # Run "prep" section once
59
+ script_dict = script.script_dict
60
+ self._run_actions(script_dict.get("prep", []), section_name="prep", run_name=run_name, logger=logger)
61
+ output_list = []
62
+ _, arg_type = script.config("script")
63
+ _, return_list = script.config_return()
64
+ # Run "script" section multiple times
65
+ if repeat_count:
66
+ self._run_repeat_section(repeat_count, arg_type, bo_args, output_list, return_list, run_name, logger, socketio)
67
+ elif config:
68
+ self._run_config_section(config, arg_type, output_list, return_list, run_name, logger, socketio)
69
+ # Run "cleanup" section once
70
+ self._run_actions(script_dict.get("cleanup", []), section_name="cleanup", run_name=run_name, logger=logger)
71
+ # Save results if necessary
72
+ if output_list:
73
+ self._save_results(run_name, arg_type, return_list, output_list, logger, output_path)
74
+ except Exception as e:
75
+ logger.error(f"Error during script execution: {e}")
76
+ finally:
77
+ with self.lock:
78
+ self.is_running = False # Reset the running flag when done
79
+ self._emit_progress(socketio, 100)
80
+
81
+ def _run_actions(self, actions, section_name="", run_name=None, logger=None):
82
+ logger.info(f'Executing {section_name} steps') if actions else logger.info(f'No {section_name} steps')
83
+ for action in actions:
84
+ if self.stop_event.is_set():
85
+ logger.info(f"Stopping execution during {section_name} section.")
86
+ break
87
+ logger.info(f'Executing {action.get("action", "")} action')
88
+ fname = f"{run_name}_{section_name}"
89
+ function = self.globals_dict[fname]
90
+ function()
91
+
92
+ def _run_config_section(self, config, arg_type, output_list, return_list, run_name, logger, socketio):
93
+ compiled = True
94
+ for i in config:
95
+ try:
96
+ i = utils.convert_config_type(i, arg_type)
97
+ except Exception as e:
98
+ logger.info(e)
99
+ compiled = False
100
+ break
101
+ if compiled:
102
+ for i, kwargs in enumerate(config):
103
+ kwargs = dict(kwargs)
104
+ if self.stop_event.is_set():
105
+ logger.info(f'Stopping execution during {run_name}: {i + 1}/{len(config)}')
106
+ break
107
+ logger.info(f'Executing {i + 1} of {len(config)} with kwargs = {kwargs}')
108
+ progress = (i + 1) * 100 / len(config)
109
+ self._emit_progress(socketio, progress)
110
+ fname = f"{run_name}_script"
111
+ function = self.globals_dict[fname]
112
+ output = function(**kwargs)
113
+ if output:
114
+ kwargs.update(output)
115
+ output_list.append(kwargs)
116
+
117
+ def _run_repeat_section(self, repeat_count, arg_types, bo_args, output_list, return_list, run_name, logger, socketio):
118
+ if bo_args:
119
+ logger.info('Initializing optimizer...')
120
+ ax_client = utils.ax_initiation(bo_args, arg_types)
121
+ for i in range(int(repeat_count)):
122
+ if self.stop_event.is_set():
123
+ logger.info(f'Stopping execution during {run_name}: {i + 1}/{int(repeat_count)}')
124
+ break
125
+ logger.info(f'Executing {run_name} experiment: {i + 1}/{int(repeat_count)}')
126
+ progress = (i + 1) * 100 / int(repeat_count) - 0.1
127
+ self._emit_progress(socketio, progress)
128
+ if bo_args:
129
+ try:
130
+ parameters, trial_index = ax_client.get_next_trial()
131
+ logger.info(f'Output value: {parameters}')
132
+ fname = f"{run_name}_script"
133
+ function = self.globals_dict[fname]
134
+ output = function(**parameters)
135
+ # output = eval(f"{run_name}_script(**{parameters})")
136
+ _output = output.copy()
137
+ ax_client.complete_trial(trial_index=trial_index, raw_data=_output)
138
+ output.update(parameters)
139
+ except Exception as e:
140
+ logger.info(f'Optimization error: {e}')
141
+ break
142
+ else:
143
+ fname = f"{run_name}_script"
144
+ function = self.globals_dict[fname]
145
+ output = function()
146
+
147
+ if output:
148
+ output_list.append(output)
149
+ logger.info(f'Output value: {output}')
150
+ return output_list
151
+
152
+ @staticmethod
153
+ def _save_results(run_name, arg_type, return_list, output_list, logger, output_path):
154
+ args = list(arg_type.keys()) if arg_type else []
155
+ args.extend(return_list)
156
+ filename = run_name + "_" + datetime.now().strftime("%Y-%m-%d %H-%M") + ".csv"
157
+ file_path = os.path.join(output_path, filename)
158
+ with open(file_path, "w", newline='') as file:
159
+ writer = csv.DictWriter(file, fieldnames=args)
160
+ writer.writeheader()
161
+ writer.writerows(output_list)
162
+ logger.info(f'Results saved to {file_path}')
163
+
164
+ @staticmethod
165
+ def _emit_progress(socketio, progress):
166
+ socketio.emit('progress', {'progress': progress})