ivoryos 1.0.0__py3-none-any.whl → 1.0.3__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.
- ivoryos/routes/auth/auth.py +3 -3
- ivoryos/routes/control/control.py +89 -60
- ivoryos/routes/control/templates/control/controllers_home.html +7 -7
- ivoryos/routes/database/database.py +98 -39
- ivoryos/routes/database/templates/database/{experiment_database.html → scripts_database.html} +27 -18
- ivoryos/routes/database/templates/database/{workflow_run_database.html → workflow_database.html} +27 -5
- ivoryos/routes/design/design.py +215 -78
- ivoryos/routes/design/templates/design/experiment_run.html +62 -123
- ivoryos/static/js/socket_handler.js +13 -8
- ivoryos/utils/bo_campaign.py +87 -0
- ivoryos/utils/client_proxy.py +1 -1
- ivoryos/utils/db_models.py +27 -7
- ivoryos/utils/global_config.py +16 -7
- ivoryos/utils/script_runner.py +56 -40
- ivoryos/utils/task_runner.py +81 -0
- ivoryos/utils/utils.py +0 -68
- ivoryos/version.py +1 -1
- {ivoryos-1.0.0.dist-info → ivoryos-1.0.3.dist-info}/METADATA +3 -3
- {ivoryos-1.0.0.dist-info → ivoryos-1.0.3.dist-info}/RECORD +23 -21
- /ivoryos/routes/database/templates/database/{experiment_step_view.html → workflow_view.html} +0 -0
- {ivoryos-1.0.0.dist-info → ivoryos-1.0.3.dist-info}/LICENSE +0 -0
- {ivoryos-1.0.0.dist-info → ivoryos-1.0.3.dist-info}/WHEEL +0 -0
- {ivoryos-1.0.0.dist-info → ivoryos-1.0.3.dist-info}/top_level.txt +0 -0
ivoryos/utils/script_runner.py
CHANGED
|
@@ -5,8 +5,8 @@ import threading
|
|
|
5
5
|
import time
|
|
6
6
|
from datetime import datetime
|
|
7
7
|
|
|
8
|
-
from ivoryos.utils import utils
|
|
9
|
-
from ivoryos.utils.db_models import Script, WorkflowRun, WorkflowStep, db
|
|
8
|
+
from ivoryos.utils import utils, bo_campaign
|
|
9
|
+
from ivoryos.utils.db_models import Script, WorkflowRun, WorkflowStep, db, SingleStep
|
|
10
10
|
from ivoryos.utils.global_config import GlobalConfig
|
|
11
11
|
|
|
12
12
|
global_config = GlobalConfig()
|
|
@@ -26,8 +26,9 @@ class ScriptRunner:
|
|
|
26
26
|
self.stop_pending_event = threading.Event()
|
|
27
27
|
self.stop_current_event = threading.Event()
|
|
28
28
|
self.is_running = False
|
|
29
|
-
self.lock =
|
|
29
|
+
self.lock = global_config.runner_lock
|
|
30
30
|
self.paused = False
|
|
31
|
+
self.current_app = None
|
|
31
32
|
|
|
32
33
|
def toggle_pause(self):
|
|
33
34
|
"""Toggles between pausing and resuming the script"""
|
|
@@ -59,23 +60,29 @@ class ScriptRunner:
|
|
|
59
60
|
self.stop_current_event.set()
|
|
60
61
|
self.abort_pending()
|
|
61
62
|
|
|
63
|
+
|
|
62
64
|
def run_script(self, script, repeat_count=1, run_name=None, logger=None, socketio=None, config=None, bo_args=None,
|
|
63
|
-
output_path="", current_app=None):
|
|
64
|
-
# Get run.id
|
|
65
|
+
output_path="", compiled=False, current_app=None):
|
|
65
66
|
global deck
|
|
66
67
|
if deck is None:
|
|
67
68
|
deck = global_config.deck
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
|
|
70
|
+
if self.current_app is None:
|
|
71
|
+
self.current_app = current_app
|
|
72
|
+
# time.sleep(1) # Optional: may help ensure deck readiness
|
|
73
|
+
|
|
74
|
+
# Try to acquire lock without blocking
|
|
75
|
+
if not self.lock.acquire(blocking=False):
|
|
76
|
+
if logger:
|
|
71
77
|
logger.info("System is busy. Please wait for it to finish or stop it before starting a new one.")
|
|
72
|
-
|
|
73
|
-
self.is_running = True
|
|
78
|
+
return None
|
|
74
79
|
|
|
75
80
|
self.reset_stop_event()
|
|
76
81
|
|
|
77
|
-
thread = threading.Thread(
|
|
78
|
-
|
|
82
|
+
thread = threading.Thread(
|
|
83
|
+
target=self._run_with_stop_check,
|
|
84
|
+
args=(script, repeat_count, run_name, logger, socketio, config, bo_args, output_path, current_app, compiled)
|
|
85
|
+
)
|
|
79
86
|
thread.start()
|
|
80
87
|
return thread
|
|
81
88
|
|
|
@@ -86,7 +93,7 @@ class ScriptRunner:
|
|
|
86
93
|
:param kwargs: Arguments to pass to the function
|
|
87
94
|
:return: The final result of the function execution
|
|
88
95
|
"""
|
|
89
|
-
_func_str = script.compile()
|
|
96
|
+
_func_str = script.python_script or script.compile()
|
|
90
97
|
step_list: list = script.convert_to_lines(_func_str).get(section_name, [])
|
|
91
98
|
global deck
|
|
92
99
|
# global deck, registered_workflows
|
|
@@ -138,6 +145,8 @@ class ScriptRunner:
|
|
|
138
145
|
method_name=method_name,
|
|
139
146
|
start_time=start_time,
|
|
140
147
|
)
|
|
148
|
+
db.session.add(step)
|
|
149
|
+
db.session.commit()
|
|
141
150
|
logger.info(f"Executing: {line}")
|
|
142
151
|
socketio.emit('execution', {'section': f"{section_name}-{index}"})
|
|
143
152
|
# self._emit_progress(socketio, 100)
|
|
@@ -158,7 +167,7 @@ class ScriptRunner:
|
|
|
158
167
|
step.run_error = True
|
|
159
168
|
self.toggle_pause()
|
|
160
169
|
step.end_time = datetime.now()
|
|
161
|
-
db.session.add(step)
|
|
170
|
+
# db.session.add(step)
|
|
162
171
|
db.session.commit()
|
|
163
172
|
|
|
164
173
|
self.pause_event.wait()
|
|
@@ -173,7 +182,7 @@ class ScriptRunner:
|
|
|
173
182
|
return exec_locals # Return the 'results' variable
|
|
174
183
|
|
|
175
184
|
def _run_with_stop_check(self, script: Script, repeat_count: int, run_name: str, logger, socketio, config, bo_args,
|
|
176
|
-
output_path, current_app):
|
|
185
|
+
output_path, current_app, compiled):
|
|
177
186
|
time.sleep(1)
|
|
178
187
|
# _func_str = script.compile()
|
|
179
188
|
# step_list_dict: dict = script.convert_to_lines(_func_str)
|
|
@@ -183,11 +192,12 @@ class ScriptRunner:
|
|
|
183
192
|
script_dict = script.script_dict
|
|
184
193
|
with current_app.app_context():
|
|
185
194
|
|
|
186
|
-
run = WorkflowRun(name=script.name or "untitled", platform=script.deck,start_time=datetime.now())
|
|
195
|
+
run = WorkflowRun(name=script.name or "untitled", platform=script.deck or "deck",start_time=datetime.now())
|
|
187
196
|
db.session.add(run)
|
|
188
|
-
db.session.
|
|
189
|
-
|
|
190
|
-
|
|
197
|
+
db.session.commit()
|
|
198
|
+
run_id = run.id # Save the ID
|
|
199
|
+
global_config.runner_status = {"id":run_id, "type": "workflow"}
|
|
200
|
+
self._run_actions(script, section_name="prep", logger=logger, socketio=socketio, run_id=run_id)
|
|
191
201
|
output_list = []
|
|
192
202
|
_, arg_type = script.config("script")
|
|
193
203
|
_, return_list = script.config_return()
|
|
@@ -195,43 +205,46 @@ class ScriptRunner:
|
|
|
195
205
|
# Run "script" section multiple times
|
|
196
206
|
if repeat_count:
|
|
197
207
|
self._run_repeat_section(repeat_count, arg_type, bo_args, output_list, script,
|
|
198
|
-
run_name, return_list, logger, socketio, run_id=
|
|
208
|
+
run_name, return_list, compiled, logger, socketio, run_id=run_id)
|
|
199
209
|
elif config:
|
|
200
210
|
self._run_config_section(config, arg_type, output_list, script, run_name, logger,
|
|
201
|
-
socketio, run_id=
|
|
211
|
+
socketio, run_id=run_id, compiled=compiled)
|
|
202
212
|
|
|
203
213
|
# Run "cleanup" section once
|
|
204
|
-
self._run_actions(script, section_name="cleanup", logger=logger, socketio=socketio,run_id=
|
|
214
|
+
self._run_actions(script, section_name="cleanup", logger=logger, socketio=socketio,run_id=run_id)
|
|
205
215
|
# Reset the running flag when done
|
|
206
|
-
|
|
207
|
-
self.is_running = False
|
|
216
|
+
self.lock.release()
|
|
208
217
|
# Save results if necessary
|
|
209
218
|
filename = None
|
|
210
|
-
if output_list:
|
|
219
|
+
if not script.python_script and output_list:
|
|
211
220
|
filename = self._save_results(run_name, arg_type, return_list, output_list, logger, output_path)
|
|
212
221
|
self._emit_progress(socketio, 100)
|
|
222
|
+
with current_app.app_context():
|
|
223
|
+
run = db.session.get(WorkflowRun, run_id) # SQLAlchemy 1.4+ recommended method
|
|
213
224
|
run.end_time = datetime.now()
|
|
214
225
|
run.data_path = filename
|
|
215
226
|
db.session.commit()
|
|
216
227
|
|
|
217
228
|
def _run_actions(self, script, section_name="", logger=None, socketio=None, run_id=None):
|
|
218
|
-
_func_str = script.compile()
|
|
229
|
+
_func_str = script.python_script or script.compile()
|
|
219
230
|
step_list: list = script.convert_to_lines(_func_str).get(section_name, [])
|
|
220
231
|
logger.info(f'Executing {section_name} steps') if step_list else logger.info(f'No {section_name} steps')
|
|
221
232
|
if self.stop_pending_event.is_set():
|
|
222
233
|
logger.info(f"Stopping execution during {section_name} section.")
|
|
223
234
|
return
|
|
224
|
-
|
|
235
|
+
if step_list:
|
|
236
|
+
self.exec_steps(script, section_name, logger, socketio, run_id=run_id, i_progress=0)
|
|
225
237
|
|
|
226
|
-
def _run_config_section(self, config, arg_type, output_list, script, run_name, logger, socketio, run_id):
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
238
|
+
def _run_config_section(self, config, arg_type, output_list, script, run_name, logger, socketio, run_id, compiled=True):
|
|
239
|
+
if not compiled:
|
|
240
|
+
for i in config:
|
|
241
|
+
try:
|
|
242
|
+
i = utils.convert_config_type(i, arg_type)
|
|
243
|
+
compiled = True
|
|
244
|
+
except Exception as e:
|
|
245
|
+
logger.info(e)
|
|
246
|
+
compiled = False
|
|
247
|
+
break
|
|
235
248
|
if compiled:
|
|
236
249
|
for i, kwargs in enumerate(config):
|
|
237
250
|
kwargs = dict(kwargs)
|
|
@@ -248,11 +261,14 @@ class ScriptRunner:
|
|
|
248
261
|
# kwargs.update(output)
|
|
249
262
|
output_list.append(output)
|
|
250
263
|
|
|
251
|
-
def _run_repeat_section(self, repeat_count, arg_types, bo_args, output_list, script, run_name, return_list,
|
|
264
|
+
def _run_repeat_section(self, repeat_count, arg_types, bo_args, output_list, script, run_name, return_list, compiled,
|
|
252
265
|
logger, socketio, run_id):
|
|
253
266
|
if bo_args:
|
|
254
267
|
logger.info('Initializing optimizer...')
|
|
255
|
-
|
|
268
|
+
if compiled:
|
|
269
|
+
ax_client = bo_campaign.ax_init_opc(bo_args)
|
|
270
|
+
else:
|
|
271
|
+
ax_client = bo_campaign.ax_init_form(bo_args, arg_types)
|
|
256
272
|
for i_progress in range(int(repeat_count)):
|
|
257
273
|
if self.stop_pending_event.is_set():
|
|
258
274
|
logger.info(f'Stopping execution during {run_name}: {i_progress + 1}/{int(repeat_count)}')
|
|
@@ -311,9 +327,9 @@ class ScriptRunner:
|
|
|
311
327
|
|
|
312
328
|
def get_status(self):
|
|
313
329
|
"""Returns current status of the script runner."""
|
|
314
|
-
with self.
|
|
330
|
+
with self.current_app.app_context():
|
|
315
331
|
return {
|
|
316
|
-
"is_running": self.
|
|
332
|
+
"is_running": self.lock.locked(),
|
|
317
333
|
"paused": self.paused,
|
|
318
334
|
"stop_pending": self.stop_pending_event.is_set(),
|
|
319
335
|
"stop_current": self.stop_current_event.is_set(),
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
import time
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
from ivoryos.utils.db_models import db, SingleStep
|
|
6
|
+
from ivoryos.utils.global_config import GlobalConfig
|
|
7
|
+
|
|
8
|
+
global_config = GlobalConfig()
|
|
9
|
+
global deck
|
|
10
|
+
deck = None
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TaskRunner:
|
|
14
|
+
def __init__(self, globals_dict=None):
|
|
15
|
+
self.retry = False
|
|
16
|
+
if globals_dict is None:
|
|
17
|
+
globals_dict = globals()
|
|
18
|
+
self.globals_dict = globals_dict
|
|
19
|
+
self.lock = global_config.runner_lock
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def run_single_step(self, component, method, kwargs, wait=True, current_app=None):
|
|
23
|
+
global deck
|
|
24
|
+
if deck is None:
|
|
25
|
+
deck = global_config.deck
|
|
26
|
+
|
|
27
|
+
# Try to acquire lock without blocking
|
|
28
|
+
if not self.lock.acquire(blocking=False):
|
|
29
|
+
current_status = global_config.runner_status
|
|
30
|
+
current_status["status"] = "busy"
|
|
31
|
+
return current_status
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
if wait:
|
|
35
|
+
output = self._run_single_step(component, method, kwargs, current_app)
|
|
36
|
+
else:
|
|
37
|
+
print("running with thread")
|
|
38
|
+
thread = threading.Thread(
|
|
39
|
+
target=self._run_single_step, args=(component, method, kwargs, current_app)
|
|
40
|
+
)
|
|
41
|
+
thread.start()
|
|
42
|
+
time.sleep(0.1)
|
|
43
|
+
output = {"status": "task started", "task_id": global_config.runner_status.get("id")}
|
|
44
|
+
|
|
45
|
+
return output
|
|
46
|
+
|
|
47
|
+
def _get_executable(self, component, deck, method):
|
|
48
|
+
if component.startswith("deck."):
|
|
49
|
+
component = component.split(".")[1]
|
|
50
|
+
instrument = getattr(deck, component)
|
|
51
|
+
else:
|
|
52
|
+
temp_connections = global_config.defined_variables
|
|
53
|
+
instrument = temp_connections.get(component)
|
|
54
|
+
function_executable = getattr(instrument, method)
|
|
55
|
+
return function_executable
|
|
56
|
+
|
|
57
|
+
def _run_single_step(self, component, method, kwargs, current_app=None):
|
|
58
|
+
try:
|
|
59
|
+
function_executable = self._get_executable(component, deck, method)
|
|
60
|
+
method_name = f"{function_executable.__self__.__class__.__name__}.{function_executable.__name__}"
|
|
61
|
+
except Exception as e:
|
|
62
|
+
self.lock.release()
|
|
63
|
+
return {"status": "error", "msg": e.__str__()}
|
|
64
|
+
|
|
65
|
+
# with self.lock:
|
|
66
|
+
with current_app.app_context():
|
|
67
|
+
step = SingleStep(method_name=method_name, kwargs=kwargs, run_error=False, start_time=datetime.now())
|
|
68
|
+
db.session.add(step)
|
|
69
|
+
db.session.commit()
|
|
70
|
+
global_config.runner_status = {"id":step.id, "type": "task"}
|
|
71
|
+
try:
|
|
72
|
+
output = function_executable(**kwargs)
|
|
73
|
+
step.output = output
|
|
74
|
+
step.end_time = datetime.now()
|
|
75
|
+
except Exception as e:
|
|
76
|
+
step.run_error = e.__str__()
|
|
77
|
+
step.end_time = datetime.now()
|
|
78
|
+
finally:
|
|
79
|
+
db.session.commit()
|
|
80
|
+
self.lock.release()
|
|
81
|
+
return output
|
ivoryos/utils/utils.py
CHANGED
|
@@ -240,74 +240,6 @@ def start_logger(socketio: SocketIO, logger_name: str, log_filename: str = None)
|
|
|
240
240
|
return logger
|
|
241
241
|
|
|
242
242
|
|
|
243
|
-
def ax_wrapper(data: dict, arg_types: list):
|
|
244
|
-
"""
|
|
245
|
-
Ax platform wrapper function for creating optimization campaign parameters and objective from the web form input
|
|
246
|
-
:param data: e.g.,
|
|
247
|
-
{
|
|
248
|
-
"param_1_type": "range", "param_1_value": [1,2],
|
|
249
|
-
"param_2_type": "range", "param_2_value": [1,2],
|
|
250
|
-
"obj_1_min": True,
|
|
251
|
-
"obj_2_min": True
|
|
252
|
-
}
|
|
253
|
-
:return: the optimization campaign parameters
|
|
254
|
-
parameter=[
|
|
255
|
-
{"name": "param_1", "type": "range", "bounds": [1,2]},
|
|
256
|
-
{"name": "param_1", "type": "range", "bounds": [1,2]}
|
|
257
|
-
]
|
|
258
|
-
objectives=[
|
|
259
|
-
{"name": "obj_1", "min": True, "threshold": None},
|
|
260
|
-
{"name": "obj_2", "min": True, "threshold": None},
|
|
261
|
-
]
|
|
262
|
-
"""
|
|
263
|
-
from ax.service.utils.instantiation import ObjectiveProperties
|
|
264
|
-
parameter = []
|
|
265
|
-
objectives = {}
|
|
266
|
-
# Iterate through the webui_data dictionary
|
|
267
|
-
for key, value in data.items():
|
|
268
|
-
# Check if the key corresponds to a parameter type
|
|
269
|
-
if "_type" in key:
|
|
270
|
-
param_name = key.split("_type")[0]
|
|
271
|
-
param_type = value
|
|
272
|
-
param_value = data[f"{param_name}_value"].split(",")
|
|
273
|
-
try:
|
|
274
|
-
values = [float(v) for v in param_value]
|
|
275
|
-
except Exception:
|
|
276
|
-
values = param_value
|
|
277
|
-
if param_type == "range":
|
|
278
|
-
param = {"name": param_name, "type": param_type, "bounds": values}
|
|
279
|
-
if param_type == "choice":
|
|
280
|
-
param = {"name": param_name, "type": param_type, "values": values}
|
|
281
|
-
if param_type == "fixed":
|
|
282
|
-
param = {"name": param_name, "type": param_type, "value": values[0]}
|
|
283
|
-
_type = arg_types[param_name] if arg_types[param_name] in ["str", "bool", "int"] else "float"
|
|
284
|
-
param.update({"value_type": _type})
|
|
285
|
-
parameter.append(param)
|
|
286
|
-
elif key.endswith("_min"):
|
|
287
|
-
if not value == 'none':
|
|
288
|
-
obj_name = key.split("_min")[0]
|
|
289
|
-
is_min = True if value == "minimize" else False
|
|
290
|
-
|
|
291
|
-
threshold = None if f"{obj_name}_threshold" not in data else data[f"{obj_name}_threshold"]
|
|
292
|
-
properties = ObjectiveProperties(minimize=is_min)
|
|
293
|
-
objectives[obj_name] = properties
|
|
294
|
-
|
|
295
|
-
return parameter, objectives
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
def ax_initiation(data, arg_types):
|
|
299
|
-
"""
|
|
300
|
-
create Ax campaign from the web form input
|
|
301
|
-
:param data:
|
|
302
|
-
"""
|
|
303
|
-
install_and_import("ax", "ax-platform")
|
|
304
|
-
parameter, objectives = ax_wrapper(data, arg_types)
|
|
305
|
-
from ax.service.ax_client import AxClient
|
|
306
|
-
ax_client = AxClient()
|
|
307
|
-
ax_client.create_experiment(parameter, objectives=objectives)
|
|
308
|
-
return ax_client
|
|
309
|
-
|
|
310
|
-
|
|
311
243
|
def get_arg_type(args, parameters):
|
|
312
244
|
"""get argument type from signature"""
|
|
313
245
|
arg_types = {}
|
ivoryos/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "1.0.
|
|
1
|
+
__version__ = "1.0.3"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ivoryos
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.3
|
|
4
4
|
Summary: an open-source Python package enabling Self-Driving Labs (SDLs) interoperability
|
|
5
5
|
Home-page: https://gitlab.com/heingroup/ivoryos
|
|
6
6
|
Author: Ivory Zhang
|
|
@@ -22,8 +22,8 @@ Requires-Dist: python-dotenv
|
|
|
22
22
|
[](https://pypi.org/project/ivoryos/)
|
|
23
23
|

|
|
24
24
|
[](https://youtu.be/dFfJv9I2-1g)
|
|
25
|
-
[](https://www.nature.com/articles/s41467-025-60514-w)
|
|
26
|
+
[](https://discord.gg/AX5P9EdGVX)
|
|
27
27
|
|
|
28
28
|

|
|
29
29
|
# ivoryOS: interoperable Web UI for self-driving laboratories (SDLs)
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
ivoryos/__init__.py,sha256=1v6LwuIao8WbmSskifzdfde7E_gH3PWCYaNpLaRtYZk,7341
|
|
2
2
|
ivoryos/config.py,sha256=3FPBYTIBhQTKDvsEoR8ZeTmg65D-CSFEdGmOuIL4pSI,1311
|
|
3
|
-
ivoryos/version.py,sha256=
|
|
3
|
+
ivoryos/version.py,sha256=2plzdEEb24FLjE2I2XyBBcJEPYWHccNL4SgtLC_6erg,22
|
|
4
4
|
ivoryos/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
ivoryos/routes/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
ivoryos/routes/auth/auth.py,sha256=
|
|
6
|
+
ivoryos/routes/auth/auth.py,sha256=rvqMf4oeYXIjcsNWPbHoxK4QJRbM4YSMCl3IDRMnYtM,3255
|
|
7
7
|
ivoryos/routes/auth/templates/auth/login.html,sha256=WSRrKbdM_oobqSXFRTo-j9UlOgp6sYzS9tm7TqqPULI,1207
|
|
8
8
|
ivoryos/routes/auth/templates/auth/signup.html,sha256=b5LTXtpfTSkSS7X8u1ldwQbbgEFTk6UNMAediA5BwBY,1465
|
|
9
9
|
ivoryos/routes/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
ivoryos/routes/control/control.py,sha256=
|
|
10
|
+
ivoryos/routes/control/control.py,sha256=AaXqXqaIIed9xBVQsk52CNnNDTSofje5qQAfDGWd1Q0,16404
|
|
11
11
|
ivoryos/routes/control/templates/control/controllers.html,sha256=iIp0h6WA68gQj9OsoiB7dU1BqH8CGomTueR73F4C8eY,4274
|
|
12
|
-
ivoryos/routes/control/templates/control/controllers_home.html,sha256=
|
|
12
|
+
ivoryos/routes/control/templates/control/controllers_home.html,sha256=qAM4iZBEuXvSgGUWWVVIe2E9MPJOeG7U214hYM84jIE,2976
|
|
13
13
|
ivoryos/routes/control/templates/control/controllers_new.html,sha256=uOQo9kYmwX2jk3KZDkMUF_ylfNUIs_oIWb_kk_MMVDM,4921
|
|
14
14
|
ivoryos/routes/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
ivoryos/routes/database/database.py,sha256=
|
|
16
|
-
ivoryos/routes/database/templates/database/
|
|
17
|
-
ivoryos/routes/database/templates/database/experiment_step_view.html,sha256=u8_XYhiZ98PzglMzFEkuM1Tk9hVWf79xXIrpHVDxKa0,3618
|
|
15
|
+
ivoryos/routes/database/database.py,sha256=kP5dEb5TvX3GlePk2sxlpwer8AsTM36kdeCkzAiFkR8,9837
|
|
16
|
+
ivoryos/routes/database/templates/database/scripts_database.html,sha256=tEpKOj1UGz7mcDq11guwP48XJxwawjxjPvxRhKiIG2I,3640
|
|
18
17
|
ivoryos/routes/database/templates/database/step_card.html,sha256=F4JRfacrEQfk2rrEbcI_i7G84nzKKDmCrMSmStLb4W4,290
|
|
19
|
-
ivoryos/routes/database/templates/database/
|
|
18
|
+
ivoryos/routes/database/templates/database/workflow_database.html,sha256=fsJHrYeEHGBKRn1pIxWITE6e93tdZsXH3zRs9Ob5FX0,4467
|
|
19
|
+
ivoryos/routes/database/templates/database/workflow_view.html,sha256=u8_XYhiZ98PzglMzFEkuM1Tk9hVWf79xXIrpHVDxKa0,3618
|
|
20
20
|
ivoryos/routes/design/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
-
ivoryos/routes/design/design.py,sha256=
|
|
21
|
+
ivoryos/routes/design/design.py,sha256=Ju9Hz0khhAk6HmnZd3Er3PglFkvZBNPAJ-fPJMfrrIM,29328
|
|
22
22
|
ivoryos/routes/design/templates/design/experiment_builder.html,sha256=rEdcHj5onJG_4MejdFBPnJVzsvCMp1KDteqNkpx24kQ,29430
|
|
23
|
-
ivoryos/routes/design/templates/design/experiment_run.html,sha256=
|
|
23
|
+
ivoryos/routes/design/templates/design/experiment_run.html,sha256=7VP0Vo98phcYnFennd5vqaMK1M1QBwDmM-b9aZb8jOw,26282
|
|
24
24
|
ivoryos/routes/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
25
|
ivoryos/routes/main/main.py,sha256=yuVJzXAob1kc1dfflkTBIZQ0tdf6kChfuq-uQlN1e9Q,957
|
|
26
26
|
ivoryos/routes/main/templates/main/help.html,sha256=IOktMEsOPk0SCiMBXZ4mpffClERAyX8W82fel71M3M0,9370
|
|
@@ -31,20 +31,22 @@ ivoryos/static/style.css,sha256=zQVx35A5g6JMJ-K84-6fSKtzXGjp_p5ZVG6KLHPM2IE,4021
|
|
|
31
31
|
ivoryos/static/gui_annotation/Slide1.png,sha256=Lm4gdOkUF5HIUFaB94tl6koQVkzpitKj43GXV_XYMMc,121727
|
|
32
32
|
ivoryos/static/gui_annotation/Slide2.PNG,sha256=z3wQ9oVgg4JTWVLQGKK_KhtepRHUYP1e05XUWGT2A0I,118761
|
|
33
33
|
ivoryos/static/js/overlay.js,sha256=dPxop19es0E0ZUSY3d_4exIk7CJuQEnlW5uTt5fZfzI,483
|
|
34
|
-
ivoryos/static/js/socket_handler.js,sha256=
|
|
34
|
+
ivoryos/static/js/socket_handler.js,sha256=2Iyv_3METjhSlSavs_L9FE3PKY4xDEpfzJpd2FywY9o,5300
|
|
35
35
|
ivoryos/static/js/sortable_card.js,sha256=ifmlGe3yy0U_KzMphV4ClRhK2DLOvkELYMlq1vECuac,807
|
|
36
36
|
ivoryos/static/js/sortable_design.js,sha256=wwpKfIzZGDxfX3moNz0cvPvm9YyHmopZK3wmkUdnBiw,4333
|
|
37
37
|
ivoryos/templates/base.html,sha256=sDdwqOIUP2Get-py4E59PkieoGWLFpX6wAJe93s4aRo,8518
|
|
38
38
|
ivoryos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
-
ivoryos/utils/
|
|
40
|
-
ivoryos/utils/
|
|
39
|
+
ivoryos/utils/bo_campaign.py,sha256=CVs7q15Pm2SRuJNaCvZKIxOFuv1xibM2yymtpAMAWOk,3285
|
|
40
|
+
ivoryos/utils/client_proxy.py,sha256=0OT2xTMkqh_2ybgCxMV_71ZVUThWwrsnAhTIBY5vDR8,2095
|
|
41
|
+
ivoryos/utils/db_models.py,sha256=zlmmD2600CYyn79gQq8k0Vra7BDBKJBAyNLYclIWdvs,27382
|
|
41
42
|
ivoryos/utils/form.py,sha256=b3JKxRc1jN45-bXyfzSJT1lcssUuxT86FhRmNUDv5-U,20973
|
|
42
|
-
ivoryos/utils/global_config.py,sha256=
|
|
43
|
+
ivoryos/utils/global_config.py,sha256=OqfDrPgOzRdIUMD4V3pA9t6b-BATMjGZl8Jn7nkI56k,2138
|
|
43
44
|
ivoryos/utils/llm_agent.py,sha256=-lVCkjPlpLues9sNTmaT7bT4sdhWvV2DiojNwzB2Lcw,6422
|
|
44
|
-
ivoryos/utils/script_runner.py,sha256=
|
|
45
|
-
ivoryos/utils/
|
|
46
|
-
ivoryos
|
|
47
|
-
ivoryos-1.0.
|
|
48
|
-
ivoryos-1.0.
|
|
49
|
-
ivoryos-1.0.
|
|
50
|
-
ivoryos-1.0.
|
|
45
|
+
ivoryos/utils/script_runner.py,sha256=0b5hLKAF2o0SQKiArhUsG8-4MA-eniAcjwi8gCNVwtY,14542
|
|
46
|
+
ivoryos/utils/task_runner.py,sha256=u4nF0wOADu_HVlGYVTOXnUm1woWGgYAccr-ZCzgtb6Q,2899
|
|
47
|
+
ivoryos/utils/utils.py,sha256=OBwrRu02yh7pqG_lyl10zWr_RYes3xhMporxIz8lGYI,13579
|
|
48
|
+
ivoryos-1.0.3.dist-info/LICENSE,sha256=p2c8S8i-8YqMpZCJnadLz1-ofxnRMILzz6NCMIypRag,1084
|
|
49
|
+
ivoryos-1.0.3.dist-info/METADATA,sha256=XE0dH-qpGIUYCXwkzDULsuTLOJPlGj0AnUwhtjeiQPY,6992
|
|
50
|
+
ivoryos-1.0.3.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
51
|
+
ivoryos-1.0.3.dist-info/top_level.txt,sha256=FRIWWdiEvRKqw-XfF_UK3XV0CrnNb6EmVbEgjaVazRM,8
|
|
52
|
+
ivoryos-1.0.3.dist-info/RECORD,,
|
/ivoryos/routes/database/templates/database/{experiment_step_view.html → workflow_view.html}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|