ivoryos 1.1.0__py3-none-any.whl → 1.2.0__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 (58) hide show
  1. ivoryos/__init__.py +12 -5
  2. ivoryos/routes/api/api.py +5 -58
  3. ivoryos/routes/control/control.py +46 -43
  4. ivoryos/routes/control/control_file.py +4 -4
  5. ivoryos/routes/control/control_new_device.py +10 -10
  6. ivoryos/routes/control/templates/controllers.html +38 -9
  7. ivoryos/routes/control/templates/controllers_new.html +1 -1
  8. ivoryos/routes/data/data.py +81 -60
  9. ivoryos/routes/data/templates/components/step_card.html +9 -3
  10. ivoryos/routes/data/templates/workflow_database.html +10 -4
  11. ivoryos/routes/design/design.py +306 -243
  12. ivoryos/routes/design/design_file.py +42 -31
  13. ivoryos/routes/design/design_step.py +132 -30
  14. ivoryos/routes/design/templates/components/action_form.html +4 -3
  15. ivoryos/routes/design/templates/components/{instrument_panel.html → actions_panel.html} +7 -5
  16. ivoryos/routes/design/templates/components/autofill_toggle.html +8 -12
  17. ivoryos/routes/design/templates/components/canvas.html +5 -14
  18. ivoryos/routes/design/templates/components/canvas_footer.html +5 -1
  19. ivoryos/routes/design/templates/components/canvas_header.html +36 -15
  20. ivoryos/routes/design/templates/components/canvas_main.html +34 -0
  21. ivoryos/routes/design/templates/components/deck_selector.html +8 -10
  22. ivoryos/routes/design/templates/components/edit_action_form.html +16 -7
  23. ivoryos/routes/design/templates/components/instruments_panel.html +66 -0
  24. ivoryos/routes/design/templates/components/modals/drop_modal.html +3 -5
  25. ivoryos/routes/design/templates/components/modals/new_script_modal.html +1 -2
  26. ivoryos/routes/design/templates/components/modals/rename_modal.html +5 -5
  27. ivoryos/routes/design/templates/components/modals/saveas_modal.html +2 -2
  28. ivoryos/routes/design/templates/components/python_code_overlay.html +26 -4
  29. ivoryos/routes/design/templates/components/sidebar.html +12 -13
  30. ivoryos/routes/design/templates/experiment_builder.html +20 -20
  31. ivoryos/routes/execute/execute.py +157 -13
  32. ivoryos/routes/execute/execute_file.py +38 -4
  33. ivoryos/routes/execute/templates/components/tab_bayesian.html +365 -114
  34. ivoryos/routes/execute/templates/components/tab_configuration.html +1 -1
  35. ivoryos/routes/library/library.py +70 -115
  36. ivoryos/routes/library/templates/library.html +27 -19
  37. ivoryos/static/js/action_handlers.js +213 -0
  38. ivoryos/static/js/db_delete.js +23 -0
  39. ivoryos/static/js/script_metadata.js +39 -0
  40. ivoryos/static/js/sortable_design.js +89 -56
  41. ivoryos/static/js/ui_state.js +113 -0
  42. ivoryos/utils/bo_campaign.py +137 -1
  43. ivoryos/utils/db_models.py +14 -5
  44. ivoryos/utils/form.py +4 -9
  45. ivoryos/utils/global_config.py +13 -1
  46. ivoryos/utils/script_runner.py +24 -5
  47. ivoryos/utils/serilize.py +203 -0
  48. ivoryos/utils/task_runner.py +4 -1
  49. ivoryos/version.py +1 -1
  50. {ivoryos-1.1.0.dist-info → ivoryos-1.2.0.dist-info}/METADATA +1 -1
  51. {ivoryos-1.1.0.dist-info → ivoryos-1.2.0.dist-info}/RECORD +54 -51
  52. ivoryos/routes/design/templates/components/action_list.html +0 -15
  53. ivoryos/routes/design/templates/components/operations_panel.html +0 -43
  54. ivoryos/routes/design/templates/components/script_info.html +0 -31
  55. ivoryos/routes/design/templates/components/scripts.html +0 -50
  56. {ivoryos-1.1.0.dist-info → ivoryos-1.2.0.dist-info}/LICENSE +0 -0
  57. {ivoryos-1.1.0.dist-info → ivoryos-1.2.0.dist-info}/WHEEL +0 -0
  58. {ivoryos-1.1.0.dist-info → ivoryos-1.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,203 @@
1
+ import ast
2
+ import json
3
+ import inspect
4
+ import logging
5
+ from typing import get_type_hints, Union, Optional, get_origin, get_args
6
+ import sys
7
+
8
+ import flask
9
+
10
+ from example.abstract_sdl_example.abstract_balance import AbstractBalance
11
+ from example.abstract_sdl_example.abstract_pump import AbstractPump
12
+
13
+
14
+ class ScriptAnalyzer:
15
+ def __init__(self):
16
+ self.primitive_types = {
17
+ 'int', 'float', 'str', 'bool', 'tuple', 'list'
18
+ }
19
+ self.type_mapping = {
20
+ int: 'int',
21
+ float: 'float',
22
+ str: 'str',
23
+ bool: 'bool',
24
+ tuple: 'tuple',
25
+ list: 'list'
26
+ }
27
+
28
+ def extract_type_from_hint(self, type_hint):
29
+ """Extract primitive types from type hints, handling Union and Optional"""
30
+ if type_hint is None:
31
+ return None
32
+
33
+ # Handle Union types (including Optional which is Union[T, None])
34
+ origin = get_origin(type_hint)
35
+ if origin is Union:
36
+ args = get_args(type_hint)
37
+ types = []
38
+ for arg in args:
39
+ if arg is type(None): # Skip None type
40
+ continue
41
+ if arg in self.type_mapping:
42
+ types.append(self.type_mapping[arg])
43
+ elif hasattr(arg, '__name__') and arg.__name__ in self.primitive_types:
44
+ types.append(arg.__name__)
45
+ else:
46
+ return None # Non-primitive type found
47
+ return types if types else None
48
+
49
+ # Handle direct primitive types
50
+ if type_hint in self.type_mapping:
51
+ return [self.type_mapping[type_hint]]
52
+ elif hasattr(type_hint, '__name__') and type_hint.__name__ in self.primitive_types:
53
+ return [type_hint.__name__]
54
+ else:
55
+ return None # Non-primitive type
56
+
57
+
58
+ def analyze_method(self, method):
59
+ """Analyze a single method and extract its signature"""
60
+ try:
61
+ sig = inspect.signature(method)
62
+ type_hints = get_type_hints(method)
63
+
64
+ parameters = []
65
+ type_hint_warning = False
66
+ user_input_params = []
67
+
68
+ for param_name, param in sig.parameters.items():
69
+ if param_name == 'self':
70
+ continue
71
+
72
+ param_info = {"name": param_name}
73
+
74
+ # Get type hint
75
+ if param_name in type_hints:
76
+ type_list = self.extract_type_from_hint(type_hints[param_name])
77
+ if type_list is None:
78
+ type_hint_warning = True
79
+ user_input_params.append(param_name)
80
+ param_info["type"] = ""
81
+ else:
82
+ param_info["type"] = type_list[0] if len(type_list) == 1 else type_list
83
+ else:
84
+ type_hint_warning = True
85
+ user_input_params.append(param_name)
86
+ param_info["type"] = ""
87
+
88
+ # Get default value
89
+ if param.default != inspect.Parameter.empty:
90
+ param_info["default"] = param.default
91
+
92
+ parameters.append(param_info)
93
+
94
+ # Get docstring
95
+ docstring = inspect.getdoc(method)
96
+
97
+ method_info = {
98
+ "docstring": docstring or "",
99
+ "parameters": parameters
100
+ }
101
+
102
+ return method_info, type_hint_warning
103
+
104
+ except Exception as e:
105
+ print(f"Error analyzing method {method.__name__}: {e}")
106
+ return None
107
+
108
+
109
+ def analyze_module(self, module, exclude_names=[]):
110
+ """Analyze module from sys.modules and extract class instances and methods"""
111
+ exclude_classes = (flask.Blueprint, logging.Logger)
112
+ # Get all variables in the module that are class instances
113
+ included = {}
114
+ excluded = {}
115
+ failed = {}
116
+ included_with_warnings = {}
117
+ for name, obj in vars(module).items():
118
+ if (
119
+ type(obj).__module__ == 'builtins'
120
+ or name[0].isupper()
121
+ or name.startswith("_")
122
+ or isinstance(obj, exclude_classes)
123
+ or name in exclude_names
124
+ or not hasattr(obj, '__class__')
125
+ ):
126
+ excluded[name] = type(obj).__name__
127
+ continue
128
+
129
+ cls = obj.__class__
130
+
131
+ try:
132
+ class_methods, type_hint_warning = self.analyze_class(cls)
133
+ if class_methods:
134
+ if type_hint_warning:
135
+ included_with_warnings[name] = class_methods
136
+ included[name] = class_methods
137
+ except Exception as e:
138
+ failed[name] = str(e)
139
+ continue
140
+ return included, included_with_warnings, failed, excluded
141
+
142
+ def save_to_json(self, data, output_path):
143
+ """Save analysis result to JSON file"""
144
+ with open(output_path, 'w') as f:
145
+ json.dump(data, f, indent=2)
146
+
147
+ def analyze_class(self, cls):
148
+ class_methods = {}
149
+ type_hint_flag = False
150
+ for method_name, method in inspect.getmembers(cls, predicate=callable):
151
+ if method_name.startswith("_") or method_name.isupper():
152
+ continue
153
+ method_info, type_hint_warning = self.analyze_method(method)
154
+ if type_hint_warning:
155
+ type_hint_flag = True
156
+ if method_info:
157
+ class_methods[method_name] = method_info
158
+ return class_methods, type_hint_flag
159
+
160
+ @staticmethod
161
+ def print_deck_snapshot(result, with_warnings, failed):
162
+ print("\nDeck Snapshot:")
163
+ print("Included Classes:")
164
+ for name, methods in result.items():
165
+ print(f" {name}:")
166
+ for method_name, method_info in methods.items():
167
+ print(f" {method_name}: {method_info}")
168
+
169
+ if with_warnings:
170
+ print("\nClasses with Type Hint Warnings:")
171
+ for name, methods in with_warnings.items():
172
+ print(f" {name}:")
173
+ for method_name, method_info in methods.items():
174
+ print(f" {method_name}: {method_info}")
175
+
176
+ if failed:
177
+ print("\nFailed Classes:")
178
+ for name, error in failed.items():
179
+ print(f" {name}: {error}")
180
+
181
+ if __name__ == "__main__":
182
+ balance = AbstractBalance("re")
183
+ pump = AbstractPump("re")
184
+
185
+ _analyzer = ScriptAnalyzer()
186
+ module = sys.modules[__name__]
187
+ try:
188
+
189
+ result, with_warnings, failed, _ = _analyzer.analyze_module(module)
190
+
191
+ output_path = f"analysis.json"
192
+ _analyzer.save_to_json(result, output_path)
193
+
194
+ print(f"\nAnalysis complete! Results saved to: {output_path}")
195
+
196
+
197
+
198
+
199
+ _analyzer.print_deck_snapshot(result, with_warnings, failed)
200
+
201
+ except Exception as e:
202
+ print(f"Error: {e}")
203
+
@@ -72,10 +72,13 @@ class TaskRunner:
72
72
  output = function_executable(**kwargs)
73
73
  step.output = output
74
74
  step.end_time = datetime.now()
75
+ success = True
75
76
  except Exception as e:
76
77
  step.run_error = e.__str__()
77
78
  step.end_time = datetime.now()
79
+ success = False
80
+ output = e.__str__()
78
81
  finally:
79
82
  db.session.commit()
80
83
  self.lock.release()
81
- return output
84
+ return dict(success=success, output=output)
ivoryos/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.1.0"
1
+ __version__ = "1.2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ivoryos
3
- Version: 1.1.0
3
+ Version: 1.2.0
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
@@ -1,66 +1,64 @@
1
- ivoryos/__init__.py,sha256=Rqw9LExz-XuluiXnwextp8wsa39k8R6UWAvE42lz058,8892
1
+ ivoryos/__init__.py,sha256=p9m5csEeKgE7VJ_PPf-d50G5Q4A9aN2vRfJRJdi9Z4c,9149
2
2
  ivoryos/config.py,sha256=sk4dskm-K_Nv4uaA3QuE6xtew8wL6q3HmIoLgRm7p8U,2153
3
3
  ivoryos/socket_handlers.py,sha256=VWVWiIdm4jYAutwGu6R0t1nK5MuMyOCL0xAnFn06jWQ,1302
4
- ivoryos/version.py,sha256=LGVQyDsWifdACo7qztwb8RWWHds1E7uQ-ZqD8SAjyw4,22
4
+ ivoryos/version.py,sha256=MpAT5hgNoHnTtG1XRD_GV_A7QrHVU6vJjGSw_8qMGA4,22
5
5
  ivoryos/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- ivoryos/routes/api/api.py,sha256=nHjRdZIYHKkA0FxU27qHd9rLlC6fa9ZcvHmYcqJFP9c,4003
6
+ ivoryos/routes/api/api.py,sha256=X_aZMB_nCxW41pqZpJOiEEwGmlqLqJUArruevuy41v0,2284
7
7
  ivoryos/routes/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  ivoryos/routes/auth/auth.py,sha256=SbtiMc1kFHDXIauvT1o3_8rJ-jVVz2C6hfKeSCmoXSE,3231
9
9
  ivoryos/routes/auth/templates/login.html,sha256=WSRrKbdM_oobqSXFRTo-j9UlOgp6sYzS9tm7TqqPULI,1207
10
10
  ivoryos/routes/auth/templates/signup.html,sha256=b5LTXtpfTSkSS7X8u1ldwQbbgEFTk6UNMAediA5BwBY,1465
11
11
  ivoryos/routes/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- ivoryos/routes/control/control.py,sha256=P18Eu_Q-arrTxKjTbDtSp7JMy8TKeGVHq_rftuMmCBM,4914
13
- ivoryos/routes/control/control_file.py,sha256=DTs2dZc1ZwS-4ZpKqEUL-krZ9b4ItYzFBv92NlY_h9I,1543
14
- ivoryos/routes/control/control_new_device.py,sha256=aZuMGMgbz9fjfTfD0_u1ojwmqFFAlP8H6eyOYlCN9jM,5420
12
+ ivoryos/routes/control/control.py,sha256=Vmy3GRZz8EbKmV9qslR8gsaYaYzb5HQTpukp42HfMow,5236
13
+ ivoryos/routes/control/control_file.py,sha256=NIAzwhswvpl3u0mansy1ku-rPDybS5hVbmbnymOikWk,1548
14
+ ivoryos/routes/control/control_new_device.py,sha256=mfJKg5JAOagIpUKbp2b5nRwvd2V3bzT3M0zIhIsEaFM,5456
15
15
  ivoryos/routes/control/utils.py,sha256=at11wA5HPAZN4BfMaymj1GKEvRTrqi4Wg6cTqUZJDjU,1155
16
- ivoryos/routes/control/templates/controllers.html,sha256=Ltl7rVx_hMP10JZDh0SNcnMKDe1M5jFuNxCF2T9i32I,6863
17
- ivoryos/routes/control/templates/controllers_new.html,sha256=5DNLZN4I2yKbv8RPtjwkhEGIoEVuPh4Gko6JvXhVtk4,5941
16
+ ivoryos/routes/control/templates/controllers.html,sha256=tgtTuns8S2Pf6XKeojinQZ1bz112ieRGLPF5-1cElfE,8030
17
+ ivoryos/routes/control/templates/controllers_new.html,sha256=eVeLABT39DWOIYrwWClw7sAD3lCoAGCznygPgFbQoRc,5945
18
18
  ivoryos/routes/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- ivoryos/routes/data/data.py,sha256=tEl8wetuZLAHObBffzBvI-3lQfHH_4HqLk8c0YQrKMQ,3406
20
- ivoryos/routes/data/templates/workflow_database.html,sha256=wBOyAkBj6ErDLRYmgXFCFO8x3-DpKhiEWjU0K_FdVD4,4456
19
+ ivoryos/routes/data/data.py,sha256=PhuTNlQptpqBZ_9cVCYN_PbM7LBma5BjvsDlZ5gpPxM,4186
20
+ ivoryos/routes/data/templates/workflow_database.html,sha256=ofvHcovpwmJXo1SFiSrL8I9kLU_3U1UxsJUUrQ2CJUU,4878
21
21
  ivoryos/routes/data/templates/workflow_view.html,sha256=72xKreX9WhYx-0n0cFf-CL-fJIWXPCIaTi_Aa8Tq3xg,3651
22
- ivoryos/routes/data/templates/components/step_card.html,sha256=F4JRfacrEQfk2rrEbcI_i7G84nzKKDmCrMSmStLb4W4,290
22
+ ivoryos/routes/data/templates/components/step_card.html,sha256=9lKR4NCgU2v5Nbdv2uaJ-9aKibtiB_2-Y_kyHX6Ka1k,730
23
23
  ivoryos/routes/design/__init__.py,sha256=zS3HXKaw0ALL5n6t_W1rUz5Uj5_tTQ-Y1VMXyzewvR0,113
24
- ivoryos/routes/design/design.py,sha256=fwORYtBKvbhpE4H_rEXmiH5FwYuS9KJJ2U1TIgrUmCw,14700
25
- ivoryos/routes/design/design_file.py,sha256=Ewm6AOa6eJhnbWF_sdnw2U0GObLPtXVW5uZxA1gredE,2119
26
- ivoryos/routes/design/design_step.py,sha256=bKXIMZ5C1bRzvHYeAGn0TdFSvyklXZ2Eo8dmfEt56M8,1632
27
- ivoryos/routes/design/templates/experiment_builder.html,sha256=SmLUH799N4BfdvMCJj41isIKIeWguSt8ZyVYcDkBcrA,1010
28
- ivoryos/routes/design/templates/components/action_form.html,sha256=Tl_iq8vUmB2YKPGD0JND7Vph3hzmqL0Ljw5BO153zL0,2896
29
- ivoryos/routes/design/templates/components/action_list.html,sha256=LsfWNCzZ8rLsa1_0TJ7xpGGtwtY5jvLcmO_oO2VKxoE,948
30
- ivoryos/routes/design/templates/components/autofill_toggle.html,sha256=TddA5xSXA159HUtDCPrToznj4FXHYSLc4zRXOVrGGi0,828
31
- ivoryos/routes/design/templates/components/canvas.html,sha256=THswB6cNBJ5Ucsz-42zjqvjgx69PzT7SF6TJ_bEj72w,499
32
- ivoryos/routes/design/templates/components/canvas_footer.html,sha256=5Zndz5Q5risjWwEFMPw-Y1vQIqJTyXr6RwDz4XpCJQc,295
33
- ivoryos/routes/design/templates/components/canvas_header.html,sha256=fwJ8lCugUaHjKi1fUrz3MSeJP_hbw88g5cZKpAtJGTk,3386
34
- ivoryos/routes/design/templates/components/deck_selector.html,sha256=a4aaUjYZzzaB84zPgvBEI_sA8aqkxsbdEEdDwZvPWoA,836
35
- ivoryos/routes/design/templates/components/edit_action_form.html,sha256=FALFNxjcABRRGRQdapTkT53UDBmyCVmP6Isp4STRZCM,1574
36
- ivoryos/routes/design/templates/components/instrument_panel.html,sha256=6QKgkvn9jCpEQLUNPCa5g0bKADwiB5U8CKUwBVtjIYM,895
24
+ ivoryos/routes/design/design.py,sha256=9xP6uOro4ZRzvVNJ0oVv9cc27LrQw06lLsxhgYTym9c,17711
25
+ ivoryos/routes/design/design_file.py,sha256=m4yku8fkpLUs4XvLJBqR5V-kyaGKbGB6ZoRxGbjEU5Q,2140
26
+ ivoryos/routes/design/design_step.py,sha256=l8U3-FuXmap__sYm51AueKdbTaLCFaKjAz-j02b4g-E,5200
27
+ ivoryos/routes/design/templates/experiment_builder.html,sha256=hh-d2tOc_40gww5WfUYIf8sM3qBaALZnR8Sx7Ja4tpU,1623
28
+ ivoryos/routes/design/templates/components/action_form.html,sha256=ktnmXVwe2WFLM6Sg_VbBfDrPXrnongSUxjpYhZGamPY,3058
29
+ ivoryos/routes/design/templates/components/actions_panel.html,sha256=jHTR58saTUIZInBdC-vLc1ZTbStLiULeWbupjB4hQzo,977
30
+ ivoryos/routes/design/templates/components/autofill_toggle.html,sha256=CRVQUHoQT7sOSO5-Vax54ImHdT4G_mEgqR5OQkeUwK8,617
31
+ ivoryos/routes/design/templates/components/canvas.html,sha256=bKLCJaG1B36Yy9Vsnz4P5qiX4BPdfaGe9JeQQzu9rsI,268
32
+ ivoryos/routes/design/templates/components/canvas_footer.html,sha256=5VRRacMZbzx0hUej0NPP-PmXM_AtUqduHzDS7a60cQY,435
33
+ ivoryos/routes/design/templates/components/canvas_header.html,sha256=7iIzLDGHX7MnmBbf98nWtLDprbeIgoNV4dJUO1zE4Tc,3598
34
+ ivoryos/routes/design/templates/components/canvas_main.html,sha256=9inYO700zRa09lfQI2NY4FJGGeTh-9rvX4ltjj0LK3k,1432
35
+ ivoryos/routes/design/templates/components/deck_selector.html,sha256=ryTRpljYezo0AzGLCJu_qOMokjjnft3GIxddmNGtBA0,657
36
+ ivoryos/routes/design/templates/components/edit_action_form.html,sha256=Dz7FnnOK4PYptAHNy9_WFCU1RZTSV61-1lNHHOSRJNs,1876
37
+ ivoryos/routes/design/templates/components/instruments_panel.html,sha256=r1jnScVRAknrRPRbAnIVApfnx9f4yavgf9ZlNhNpjW4,3135
37
38
  ivoryos/routes/design/templates/components/modals.html,sha256=6Dl8I8oD4ln7kK8C5e92pFVVH5KDte-vVTL0U_6NSTg,306
38
- ivoryos/routes/design/templates/components/operations_panel.html,sha256=yQOuRr_wpY0s_i52erWiRTY1BnC8h0azFEyi-8b8zDE,2096
39
- ivoryos/routes/design/templates/components/python_code_overlay.html,sha256=-gwXNJ4yYyTRf_hwL-fNEEE7ZERdeV1-4LaoAysDJ9c,807
40
- ivoryos/routes/design/templates/components/script_info.html,sha256=aYI5QHjpeoWvwKAQWI6y4T3h7VpqbJZMq3U9m0zB2Hs,1710
41
- ivoryos/routes/design/templates/components/scripts.html,sha256=y6Sw_Fjm6IeFG1qLA4bH5caeN4vEUukMwehRIjoTmp0,1703
42
- ivoryos/routes/design/templates/components/sidebar.html,sha256=95mbPs-er3VN6Tf8oIp2vFCEQaNuCE4cu1I7SiPJ8Xg,509
39
+ ivoryos/routes/design/templates/components/python_code_overlay.html,sha256=GUHgsmUWQf0P1Fbg5W0OJC34TXCUIMQVUkS7KDoauyI,1264
40
+ ivoryos/routes/design/templates/components/sidebar.html,sha256=A6dRo53zIB6QJVrRLJcBZHUNJ3qpYPnR3kWxM8gTkjw,501
43
41
  ivoryos/routes/design/templates/components/text_to_code_panel.html,sha256=d-omdXk-PXAR5AyWPr4Rc4pqsebZOiTiMrnz3pPCnUY,1197
44
- ivoryos/routes/design/templates/components/modals/drop_modal.html,sha256=edMqtMPE-t0UxW1uDbKxDXFWTrm_2xStnlrO67jvoG4,893
42
+ ivoryos/routes/design/templates/components/modals/drop_modal.html,sha256=LPxcycSiBjdQbajYOegjMQEi7ValcaczGoWmW8Sz3Ms,779
45
43
  ivoryos/routes/design/templates/components/modals/json_modal.html,sha256=R-SeEdhtuDVbwOWYYH_hCdpul7y4ybCWoNwVIO5j49s,1122
46
- ivoryos/routes/design/templates/components/modals/new_script_modal.html,sha256=46IGEY7Q5whn58T8h8dIeW1nUj_Y7hqXnnY8EfoKQno,957
47
- ivoryos/routes/design/templates/components/modals/rename_modal.html,sha256=2NNSerxsWgA-k0KqTA_fhL9Y-Xt-OI0HGvjnMVEalGU,1241
48
- ivoryos/routes/design/templates/components/modals/saveas_modal.html,sha256=hTyHgxse7uYSGsrLvoiaIRKKKp8UvQaapQmYHEtg4lk,1555
44
+ ivoryos/routes/design/templates/components/modals/new_script_modal.html,sha256=pxZdWWDgI52VsTFzz6pIM9m_dTwR6jARcvCYQ6fV3Lc,937
45
+ ivoryos/routes/design/templates/components/modals/rename_modal.html,sha256=40rLNF9JprdXekB3mv_S3OdqVuQYOe-BZSCgOnIkxJQ,1202
46
+ ivoryos/routes/design/templates/components/modals/saveas_modal.html,sha256=N5PEqUuK3qxDFbtDKFnzHwhLarQLPHiX-XQAdQPL1AU,1555
49
47
  ivoryos/routes/execute/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
- ivoryos/routes/execute/execute.py,sha256=xam3HywT7lR7HoMCqQ_txeClnCwK7ulpzLQkwPrE6Ys,7040
51
- ivoryos/routes/execute/execute_file.py,sha256=GiEwVVhwx2H775JL7Cg_AWRZDTTK8sGMfygJRoR2aqc,1560
48
+ ivoryos/routes/execute/execute.py,sha256=hFnCvzO1OzR0XckCRzHfP_RZV70DtbH_p7kw1YhIe3o,12250
49
+ ivoryos/routes/execute/execute_file.py,sha256=TelWYV295p4ZPhkUDJSVxfYROfVaKodEmDPTS2plQHI,2816
52
50
  ivoryos/routes/execute/templates/experiment_run.html,sha256=D-ek7ISQrIQXy4PH37TnsURihbGNdpCgdTC8w79cwQc,10355
53
51
  ivoryos/routes/execute/templates/components/error_modal.html,sha256=5Dmp9V0Ys6781Y-pKn_mc4N9J46c8EwIkjkHX22xCsw,1025
54
52
  ivoryos/routes/execute/templates/components/logging_panel.html,sha256=FllozlPd6o7uBd8eflGjRktPV435J3XgiEeLZugoUi0,1623
55
53
  ivoryos/routes/execute/templates/components/progress_panel.html,sha256=-nX76aFLxSOiYgI1xMjznC9rDYF-Vb92TmfjXYpBtps,1323
56
54
  ivoryos/routes/execute/templates/components/run_panel.html,sha256=CmK-LYJ4K6RonHn6l9eJkqRw0XQizThOugxiXZonSDs,373
57
55
  ivoryos/routes/execute/templates/components/run_tabs.html,sha256=u-msoTQPBGvyE_5_UczRtR9bh7zD3EvsgJhT77rTzOI,1145
58
- ivoryos/routes/execute/templates/components/tab_bayesian.html,sha256=Ud50BE-O7FicFW6G057WIyS65ZEPVGmYhmRPf8yVB_M,7301
59
- ivoryos/routes/execute/templates/components/tab_configuration.html,sha256=BVSKeHug2sxAfDYon2eMEnTwQEdf8PJTV7xnA4NSySs,5116
56
+ ivoryos/routes/execute/templates/components/tab_bayesian.html,sha256=5XTMHZzbGxcCZ2M0LSRqqmVh4qmu0R1MjCkT_FQ0ag0,21314
57
+ ivoryos/routes/execute/templates/components/tab_configuration.html,sha256=JIHsYvwcYQZmJJz503NXnhcceKxd9B3JKFUSvGNWe_0,5131
60
58
  ivoryos/routes/execute/templates/components/tab_repeat.html,sha256=X-r7p78tVRrfwmAbhhZGBZbm78C4nTJS6O2A4dvzGEg,760
61
59
  ivoryos/routes/library/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
- ivoryos/routes/library/library.py,sha256=TFKY9ByiW1h0pskmwru4BjKLqei7lYKZ9CsElZbSkNY,6381
63
- ivoryos/routes/library/templates/library.html,sha256=y2KIYt_f9QS8hdPtyz_x2vzx_AbxVaZNRFkGerM5T5U,3632
60
+ ivoryos/routes/library/library.py,sha256=jook_OZRIO1nr3nBxU_X9yrDw5PSLqa0wrInI7GY6sg,5457
61
+ ivoryos/routes/library/templates/library.html,sha256=8pyKTc0TmrSSrwSVAYrh6cuPRHutg_yAA8mqzLFyZIg,3968
64
62
  ivoryos/routes/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
63
  ivoryos/routes/main/main.py,sha256=1AcSouCocHWjlpEED-ECn5OFiu0-3u0N-0st5RtKCVY,952
66
64
  ivoryos/routes/main/templates/help.html,sha256=IOktMEsOPk0SCiMBXZ4mpffClERAyX8W82fel71M3M0,9370
@@ -70,21 +68,26 @@ ivoryos/static/logo.webp,sha256=lXgfQR-4mHTH83k7VV9iB54-oC2ipe6uZvbwdOnLETc,1497
70
68
  ivoryos/static/style.css,sha256=zQVx35A5g6JMJ-K84-6fSKtzXGjp_p5ZVG6KLHPM2IE,4021
71
69
  ivoryos/static/gui_annotation/Slide1.png,sha256=Lm4gdOkUF5HIUFaB94tl6koQVkzpitKj43GXV_XYMMc,121727
72
70
  ivoryos/static/gui_annotation/Slide2.PNG,sha256=z3wQ9oVgg4JTWVLQGKK_KhtepRHUYP1e05XUWGT2A0I,118761
71
+ ivoryos/static/js/action_handlers.js,sha256=VEDox3gQvg0YXJ6WW6IthOsFqZKmvUGJ8pmQdfzHQFw,5122
72
+ ivoryos/static/js/db_delete.js,sha256=l67fqUaN_FVDaL7v91Hd7LyRbxnqXx9nyjF34-7aewY,561
73
73
  ivoryos/static/js/overlay.js,sha256=dPxop19es0E0ZUSY3d_4exIk7CJuQEnlW5uTt5fZfzI,483
74
+ ivoryos/static/js/script_metadata.js,sha256=m8VYZ8OGT2oTx1kXMXq60bKQI9WCbJNkzcFDzLvRuGc,1188
74
75
  ivoryos/static/js/socket_handler.js,sha256=2Iyv_3METjhSlSavs_L9FE3PKY4xDEpfzJpd2FywY9o,5300
75
76
  ivoryos/static/js/sortable_card.js,sha256=ifmlGe3yy0U_KzMphV4ClRhK2DLOvkELYMlq1vECuac,807
76
- ivoryos/static/js/sortable_design.js,sha256=d55AEz8LpPX_j-hREom-I19i4l-SOG2RVSR4CnozRtY,4366
77
+ ivoryos/static/js/sortable_design.js,sha256=QqYyk385JNm6zCgZK_Oa-cJEP1uPtZ_tVz27x4hyx5A,4790
78
+ ivoryos/static/js/ui_state.js,sha256=5EuqwIDndjZTqj9dsAR_IA91iGMcodY_TuQo17LLL1w,3331
77
79
  ivoryos/templates/base.html,sha256=SdZswZmfLWehorMsoGkm-FjLFtB1ivLkdUJFbpDRqp4,8519
78
80
  ivoryos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
- ivoryos/utils/bo_campaign.py,sha256=7WSYVhCaDOuXIMJll_pMRUGWPQCnVt47uLHjlIomsv8,4608
81
+ ivoryos/utils/bo_campaign.py,sha256=Fil-zT7JexL_p9XqyWByjAk42XB1R9XUKN8CdV5bi6c,9714
80
82
  ivoryos/utils/client_proxy.py,sha256=0OT2xTMkqh_2ybgCxMV_71ZVUThWwrsnAhTIBY5vDR8,2095
81
- ivoryos/utils/db_models.py,sha256=HQSjMrZc1o1fvjx5Mf7W_53xPbT9aZ00xtUJJNPbwio,27502
82
- ivoryos/utils/form.py,sha256=KlzTyG4sg1PQ-lnhKYpqaGugNWwL54PvmspqQfBoMu0,21967
83
- ivoryos/utils/global_config.py,sha256=OqfDrPgOzRdIUMD4V3pA9t6b-BATMjGZl8Jn7nkI56k,2138
83
+ ivoryos/utils/db_models.py,sha256=baE4LJcSGUj10Tj6imfINXi4JQX_4oLv_kb9bd0rp-M,27920
84
+ ivoryos/utils/form.py,sha256=eIk1N77Ynxc4Omww5ZYlmpOIJfQPWto2qfiU6nzIIeQ,21755
85
+ ivoryos/utils/global_config.py,sha256=zNO9GYhGn7El3msWoxJIm3S4Mzb3VMh2i5ZEsVtvb2Q,2463
84
86
  ivoryos/utils/llm_agent.py,sha256=-lVCkjPlpLues9sNTmaT7bT4sdhWvV2DiojNwzB2Lcw,6422
85
87
  ivoryos/utils/py_to_json.py,sha256=fyqjaxDHPh-sahgT6IHSn34ktwf6y51_x1qvhbNlH-U,7314
86
- ivoryos/utils/script_runner.py,sha256=YIdOs_s-UroN1f1s_VSlWY74dWamaGBAgxDUzqvrwfU,15791
87
- ivoryos/utils/task_runner.py,sha256=u4nF0wOADu_HVlGYVTOXnUm1woWGgYAccr-ZCzgtb6Q,2899
88
+ ivoryos/utils/script_runner.py,sha256=W4UL2iMt9bTBlb47pu2kc7SJyL9hlKzdtPudVZ9FvIM,16723
89
+ ivoryos/utils/serilize.py,sha256=Ded3Vbicl4KYN8GJ_gY7HJMuInAeFZEPk5ZtuEtHPns,6933
90
+ ivoryos/utils/task_runner.py,sha256=cDIcmDaqYh0vXoYaL_kO877pluAo2tyfsHl9OgZqJJE,3029
88
91
  ivoryos/utils/utils.py,sha256=BzgKIMMb7vyUIwYMhGDsWtwJEy5vNKtEHRJHHSiTSnM,13881
89
92
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
90
93
  tests/conftest.py,sha256=u2sQ6U-Lghyl7et1Oz6J2E5VZ47VINKcjRM_2leAE2s,3627
@@ -95,8 +98,8 @@ tests/integration/test_route_database.py,sha256=mS026W_hEuCTMpSkdRWvM-f4MYykK_6n
95
98
  tests/integration/test_route_design.py,sha256=PJAvGRiCY6B53Pu1v5vPAVHHsuaqRmRKk2eesSNshLU,1157
96
99
  tests/integration/test_route_main.py,sha256=bmuf8Y_9CRWhiLLf4up11ltEd5YCdsLx6I-o26VGDEw,1228
97
100
  tests/integration/test_sockets.py,sha256=4ZyFyExm7a-DYzVqpzEONpWeb1a0IT68wyFaQu0rY_Y,925
98
- ivoryos-1.1.0.dist-info/LICENSE,sha256=p2c8S8i-8YqMpZCJnadLz1-ofxnRMILzz6NCMIypRag,1084
99
- ivoryos-1.1.0.dist-info/METADATA,sha256=Wc_isMpJxE7DyOOrpBSoEILSAEOVgghO_LVIU7lt1Ys,8834
100
- ivoryos-1.1.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
101
- ivoryos-1.1.0.dist-info/top_level.txt,sha256=mIOiZkdpSwxFJt1R5fsyOff8mNprXHq1nMGNKNULIyE,14
102
- ivoryos-1.1.0.dist-info/RECORD,,
101
+ ivoryos-1.2.0.dist-info/LICENSE,sha256=p2c8S8i-8YqMpZCJnadLz1-ofxnRMILzz6NCMIypRag,1084
102
+ ivoryos-1.2.0.dist-info/METADATA,sha256=EjG1H1CEgd3eiOshrWhkp2nw8SeoGQ7qB2SZiuxqf9Q,8834
103
+ ivoryos-1.2.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
104
+ ivoryos-1.2.0.dist-info/top_level.txt,sha256=mIOiZkdpSwxFJt1R5fsyOff8mNprXHq1nMGNKNULIyE,14
105
+ ivoryos-1.2.0.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- {# Action list component #}
2
- <div class="list-group" id="list" style="margin-top: 20px">
3
- <ul class="reorder">
4
- {% for button in buttons %}
5
- <li id="{{ button['id'] }}" style="list-style-type: none;">
6
- <span class="line-number d-none">{{ button['id'] }}.</span>
7
- <a href="{{ url_for('design.design_steps.edit_action', uuid=button['uuid']) }}" type="button" class="btn btn-light" style="{{ button['style'] }}">{{ button['label'] }}</a>
8
- {% if not button["instrument"] in ["if","while","repeat"] %}
9
- <a href="{{ url_for('design.design_steps.duplicate_action', id=button['id']) }}" type="button" class="btn btn-light"><span class="bi bi-copy"></span></a>
10
- {% endif %}
11
- <a href="{{ url_for('design.design_steps.delete_action', id=button['id']) }}" type="button" class="btn btn-light"><span class="bi bi-trash"></span></a>
12
- </li>
13
- {% endfor %}
14
- </ul>
15
- </div>
@@ -1,43 +0,0 @@
1
- {# Operations panel component #}
2
- <div style="margin-bottom: 4vh;"></div>
3
- <div class="accordion accordion-flush">
4
- <div class="accordion-item design-control">
5
- <h5 class="accordion-header">
6
- <button class="accordion-button" data-bs-toggle="collapse" data-bs-target="#deck" role="button" aria-expanded="false" aria-controls="collapseExample">
7
- Operations
8
- </button>
9
- </h5>
10
- <div class="accordion-collapse collapse show" id="deck">
11
- <ul class="list-group">
12
- {% for instrument in defined_variables %}
13
- <form role="form" method='GET' name="{{instrument}}" action="{{url_for('design.experiment_builder',instrument=instrument)}}">
14
- <div>
15
- <button class="list-group-item list-group-item-action" type="submit">{{format_name(instrument)}}</button>
16
- </div>
17
- </form>
18
- {% endfor %}
19
- </ul>
20
- </div>
21
- </div>
22
-
23
- {% if local_variables %}
24
- <div class="accordion-item design-control">
25
- <h5 class="accordion-header">
26
- <button class="accordion-button" data-bs-toggle="collapse" data-bs-target="#local" role="button" aria-expanded="false" aria-controls="collapseExample">
27
- Local Operations
28
- </button>
29
- </h5>
30
- <div class="accordion-collapse collapse show" id="local">
31
- <ul class="list-group">
32
- {% for instrument in local_variables %}
33
- <form role="form" method='GET' name="{{instrument}}" action="{{url_for('design.experiment_builder',instrument=instrument)}}">
34
- <div>
35
- <button class="list-group-item list-group-item-action" type="submit" name="device" value="{{instrument}}" >{{instrument}}</button>
36
- </div>
37
- </form>
38
- {% endfor%}
39
- </ul>
40
- </div>
41
- </div>
42
- {% endif %}
43
- </div>
@@ -1,31 +0,0 @@
1
- {# Script info component #}
2
- <div class="collapse" id="info">
3
- <table class="table script-table">
4
- <tbody>
5
- <tr><th scope="row">Deck Name</th><td>{{script.deck}}</td></tr>
6
- <tr><th scope="row">Script Name</th><td>{{ script.name }}</td></tr>
7
- <tr>
8
- <th scope="row">Editing status <a role="button" data-bs-toggle="popover" data-bs-title="How to use:" data-bs-content="You can choose to disable editing, so the script is finalized and cannot be edited. Use save as to rename the script"><i class="bi bi-info-circle"></i></a></th>
9
- <td>{{script.status}}</td>
10
- </tr>
11
- <tr>
12
- <th scope="row">Output Values <a role="button" data-bs-toggle="popover" data-bs-title="How to use:" data-bs-content="This will be your output data. If the return data is not a value, it will save as None is the result file"><i class="bi bi-info-circle"></i></a></th>
13
- <td>
14
- {% for i in script.config_return()[1] %}
15
- <input type="checkbox">{{i}}
16
- {% endfor %}
17
- </td>
18
- </tr>
19
- <tr>
20
- <th scope="row">Config Variables <a role="button" data-bs-toggle="popover" data-bs-title="How to use:" data-bs-content="This shows variables you want to configure later using .csv file"><i class="bi bi-info-circle"></i></a></th>
21
- <td>
22
- <ul>
23
- {% for i in script.config("script")[0] %}
24
- <li>{{i}}</li>
25
- {% endfor %}
26
- </ul>
27
- </td>
28
- </tr>
29
- </tbody>
30
- </table>
31
- </div>
@@ -1,50 +0,0 @@
1
- {# Scripts component for experiment builder #}
2
- {% if instrument and use_llm %}
3
- <script>
4
- const buttonIds = {{ ['generate'] | tojson }};
5
- </script>
6
- <script src="{{ url_for('static', filename='js/overlay.js') }}"></script>
7
- {% endif %}
8
-
9
- <script>
10
- const updateListUrl = "{{ url_for('design.update_list') }}";
11
-
12
- // Toggle visibility of line numbers
13
- function toggleLineNumbers(save = true) {
14
- const show = document.getElementById('toggleLineNumbers').checked;
15
- document.querySelectorAll('.line-number').forEach(el => {
16
- el.classList.toggle('d-none', !show);
17
- });
18
-
19
- if (save) {
20
- localStorage.setItem('showLineNumbers', show ? 'true' : 'false');
21
- }
22
- }
23
-
24
- function toggleCodeOverlay() {
25
- const overlay = document.getElementById("pythonCodeOverlay");
26
- const toggleBtn = document.getElementById("codeToggleBtn");
27
- overlay.classList.toggle("show");
28
-
29
- // Change arrow icon
30
- const icon = toggleBtn.querySelector("i");
31
- icon.classList.toggle("bi-chevron-left");
32
- icon.classList.toggle("bi-chevron-right");
33
- }
34
-
35
- // Restore state on page load
36
- document.addEventListener('DOMContentLoaded', () => {
37
- const savedState = localStorage.getItem('showLineNumbers');
38
- const checkbox = document.getElementById('toggleLineNumbers');
39
-
40
- if (savedState === 'true') {
41
- checkbox.checked = true;
42
- }
43
-
44
- toggleLineNumbers(false); // don't overwrite localStorage on load
45
-
46
- checkbox.addEventListener('change', () => toggleLineNumbers());
47
- });
48
- </script>
49
-
50
- <script src="{{ url_for('static', filename='js/sortable_design.js') }}"></script>