ivoryos 1.3.0a0__tar.gz → 1.3.2__tar.gz

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.
Files changed (109) hide show
  1. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/PKG-INFO +1 -1
  2. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/__init__.py +2 -1
  3. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/app.py +11 -13
  4. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/auth/auth.py +9 -7
  5. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/control/control.py +6 -2
  6. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/data/data.py +12 -3
  7. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/design.py +2 -2
  8. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/design_file.py +3 -3
  9. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/design_step.py +3 -3
  10. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/execute.py +6 -2
  11. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/library/library.py +9 -11
  12. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/py_to_json.py +27 -1
  13. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/script_runner.py +1 -1
  14. ivoryos-1.3.2/ivoryos/version.py +1 -0
  15. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos.egg-info/PKG-INFO +1 -1
  16. ivoryos-1.3.0a0/ivoryos/version.py +0 -1
  17. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/LICENSE +0 -0
  18. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/README.md +0 -0
  19. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/config.py +0 -0
  20. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/optimizer/ax_optimizer.py +0 -0
  21. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/optimizer/base_optimizer.py +0 -0
  22. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/optimizer/baybe_optimizer.py +0 -0
  23. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/optimizer/registry.py +0 -0
  24. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/__init__.py +0 -0
  25. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/api/api.py +0 -0
  26. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/auth/__init__.py +0 -0
  27. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/auth/templates/login.html +0 -0
  28. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/auth/templates/signup.html +0 -0
  29. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/control/__init__.py +0 -0
  30. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/control/control_file.py +0 -0
  31. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/control/control_new_device.py +0 -0
  32. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/control/templates/controllers.html +0 -0
  33. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/control/templates/controllers_new.html +0 -0
  34. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/control/utils.py +0 -0
  35. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/data/__init__.py +0 -0
  36. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/data/templates/components/step_card.html +0 -0
  37. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/data/templates/workflow_database.html +0 -0
  38. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/data/templates/workflow_view.html +0 -0
  39. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/__init__.py +0 -0
  40. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/action_form.html +0 -0
  41. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/actions_panel.html +0 -0
  42. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/autofill_toggle.html +0 -0
  43. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/canvas.html +0 -0
  44. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/canvas_footer.html +0 -0
  45. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/canvas_header.html +0 -0
  46. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/canvas_main.html +0 -0
  47. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/deck_selector.html +0 -0
  48. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/edit_action_form.html +0 -0
  49. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/instruments_panel.html +0 -0
  50. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/modals/drop_modal.html +0 -0
  51. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/modals/json_modal.html +0 -0
  52. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/modals/new_script_modal.html +0 -0
  53. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/modals/rename_modal.html +0 -0
  54. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/modals/saveas_modal.html +0 -0
  55. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/modals.html +0 -0
  56. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/python_code_overlay.html +0 -0
  57. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/sidebar.html +0 -0
  58. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/components/text_to_code_panel.html +0 -0
  59. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/design/templates/experiment_builder.html +0 -0
  60. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/__init__.py +0 -0
  61. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/execute_file.py +0 -0
  62. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/templates/components/error_modal.html +0 -0
  63. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/templates/components/logging_panel.html +0 -0
  64. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/templates/components/progress_panel.html +0 -0
  65. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/templates/components/run_panel.html +0 -0
  66. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/templates/components/run_tabs.html +0 -0
  67. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/templates/components/tab_bayesian.html +0 -0
  68. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/templates/components/tab_configuration.html +0 -0
  69. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/templates/components/tab_repeat.html +0 -0
  70. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/execute/templates/experiment_run.html +0 -0
  71. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/library/__init__.py +0 -0
  72. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/library/templates/library.html +0 -0
  73. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/main/__init__.py +0 -0
  74. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/main/main.py +0 -0
  75. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/main/templates/help.html +0 -0
  76. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/routes/main/templates/home.html +0 -0
  77. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/server.py +0 -0
  78. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/socket_handlers.py +0 -0
  79. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/favicon.ico +0 -0
  80. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/gui_annotation/Slide1.png +0 -0
  81. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/gui_annotation/Slide2.PNG +0 -0
  82. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/js/action_handlers.js +0 -0
  83. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/js/db_delete.js +0 -0
  84. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/js/overlay.js +0 -0
  85. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/js/script_metadata.js +0 -0
  86. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/js/socket_handler.js +0 -0
  87. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/js/sortable_card.js +0 -0
  88. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/js/sortable_design.js +0 -0
  89. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/js/ui_state.js +0 -0
  90. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/logo.webp +0 -0
  91. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/static/style.css +0 -0
  92. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/templates/base.html +0 -0
  93. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/__init__.py +0 -0
  94. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/bo_campaign.py +0 -0
  95. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/client_proxy.py +0 -0
  96. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/db_models.py +0 -0
  97. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/decorators.py +0 -0
  98. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/form.py +0 -0
  99. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/global_config.py +0 -0
  100. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/llm_agent.py +0 -0
  101. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/serilize.py +0 -0
  102. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/task_runner.py +0 -0
  103. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos/utils/utils.py +0 -0
  104. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos.egg-info/SOURCES.txt +0 -0
  105. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos.egg-info/dependency_links.txt +0 -0
  106. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos.egg-info/requires.txt +0 -0
  107. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/ivoryos.egg-info/top_level.txt +0 -0
  108. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/pyproject.toml +0 -0
  109. {ivoryos-1.3.0a0 → ivoryos-1.3.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ivoryos
3
- Version: 1.3.0a0
3
+ Version: 1.3.2
4
4
  Summary: an open-source Python package enabling Self-Driving Labs (SDLs) interoperability
5
5
  Author-email: Ivory Zhang <ivoryzhang@chem.ubc.ca>
6
6
  License: MIT
@@ -2,12 +2,13 @@ from ivoryos.server import run
2
2
  from ivoryos.optimizer.registry import OPTIMIZER_REGISTRY
3
3
  from ivoryos.version import __version__ as ivoryos_version
4
4
  from ivoryos.utils.decorators import block, BUILDING_BLOCKS
5
-
5
+ from ivoryos.app import app
6
6
 
7
7
  __all__ = [
8
8
  "block",
9
9
  "BUILDING_BLOCKS",
10
10
  "OPTIMIZER_REGISTRY",
11
11
  "run",
12
+ "app",
12
13
  "ivoryos_version",
13
14
  ]
@@ -20,6 +20,16 @@ from ivoryos.version import __version__ as ivoryos_version
20
20
  from sqlalchemy import inspect, text
21
21
  from flask import current_app
22
22
 
23
+ url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
24
+ app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
25
+ app.register_blueprint(main, url_prefix=url_prefix)
26
+ app.register_blueprint(auth, url_prefix=f'{url_prefix}/{auth.name}')
27
+ app.register_blueprint(library, url_prefix=f'{url_prefix}/{library.name}')
28
+ app.register_blueprint(control, url_prefix=f'{url_prefix}/instruments')
29
+ app.register_blueprint(design, url_prefix=f'{url_prefix}')
30
+ app.register_blueprint(execute, url_prefix=f'{url_prefix}')
31
+ app.register_blueprint(data, url_prefix=f'{url_prefix}')
32
+ app.register_blueprint(api, url_prefix=f'{url_prefix}/{api.name}')
23
33
 
24
34
  def reset_old_schema(engine, db_dir):
25
35
  inspector = inspect(engine)
@@ -28,7 +38,7 @@ def reset_old_schema(engine, db_dir):
28
38
 
29
39
  # Check if old tables exist (no workflow_phases table)
30
40
  has_workflow_phase = 'workflow_phases' in tables
31
- old_workflow_run = 'old_workflow_run' in tables
41
+ old_workflow_run = 'workflow_runs' in tables
32
42
  old_workflow_step = 'workflow_steps' in tables
33
43
 
34
44
  if not has_workflow_phase:
@@ -59,18 +69,6 @@ def create_app(config_class=None):
59
69
  create app, init database
60
70
  """
61
71
 
62
- url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
63
- app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
64
- app.register_blueprint(main, url_prefix=url_prefix)
65
- app.register_blueprint(auth, url_prefix=f'{url_prefix}/{auth.name}')
66
- app.register_blueprint(library, url_prefix=f'{url_prefix}/{library.name}')
67
- app.register_blueprint(control, url_prefix=f'{url_prefix}/instruments')
68
- app.register_blueprint(design, url_prefix=f'{url_prefix}')
69
- app.register_blueprint(execute, url_prefix=f'{url_prefix}')
70
- app.register_blueprint(data, url_prefix=f'{url_prefix}')
71
- app.register_blueprint(api, url_prefix=f'{url_prefix}/{api.name}')
72
-
73
-
74
72
  app.config.from_object(config_class or 'config.get_config()')
75
73
  os.makedirs(app.config["OUTPUT_FOLDER"], exist_ok=True)
76
74
  # Initialize extensions
@@ -15,16 +15,16 @@ def login():
15
15
  """
16
16
  .. :quickref: User; login user
17
17
 
18
- .. http:get:: /login
18
+ .. http:get:: /auth/login
19
19
 
20
20
  load user login form.
21
21
 
22
- .. http:post:: /login
22
+ .. http:post:: /auth/login
23
23
 
24
24
  :form username: username
25
25
  :form password: password
26
26
  :status 302: and then redirects to homepage
27
- :status 401: incorrect password, redirects to :http:get:`/ivoryos/login`
27
+ :status 401: incorrect password, redirects to :http:get:`/ivoryos/auth/login`
28
28
  """
29
29
  if request.method == 'POST':
30
30
  username = request.form.get('username')
@@ -57,16 +57,16 @@ def signup():
57
57
  """
58
58
  .. :quickref: User; signup for a new account
59
59
 
60
- .. http:get:: /signup
60
+ .. http:get:: /auth/signup
61
61
 
62
62
  load user sighup
63
63
 
64
- .. http:post:: /signup
64
+ .. http:post:: /auth/signup
65
65
 
66
66
  :form username: username
67
67
  :form password: password
68
- :status 302: and then redirects to :http:get:`/ivoryos/login`
69
- :status 409: when user already exists, redirects to :http:get:`/ivoryos/signup`
68
+ :status 302: and then redirects to :http:get:`/ivoryos/auth/login`
69
+ :status 409: when user already exists, redirects to :http:get:`/ivoryos/auth/signup`
70
70
  """
71
71
  if request.method == 'POST':
72
72
  username = request.form.get('username')
@@ -92,6 +92,8 @@ def logout():
92
92
  """
93
93
  .. :quickref: User; logout the user
94
94
 
95
+ .. http:get:: /auth/logout
96
+
95
97
  logout the current user, clear session info, and redirect to the login page.
96
98
  """
97
99
  logout_user()
@@ -1,3 +1,5 @@
1
+ import copy
2
+
1
3
  from flask import Blueprint, redirect, flash, request, render_template, session, current_app, jsonify
2
4
  from flask_login import login_required
3
5
 
@@ -95,8 +97,10 @@ def deck_controllers(instrument: str = None):
95
97
 
96
98
  # GET request → render web form or return snapshot for API
97
99
  if request.is_json or request.accept_mimetypes.best_match(['application/json', 'text/html']) == 'application/json':
98
-
99
- snapshot = global_config.deck_snapshot.copy()
100
+ # 1.3.2 fix snapshot copy, add building blocks to snapshots
101
+ snapshot = copy.deepcopy(global_config.deck_snapshot)
102
+ building_blocks = copy.deepcopy(global_config.building_blocks)
103
+ snapshot.update(building_blocks)
100
104
  for instrument_key, instrument_data in snapshot.items():
101
105
  for function_key, function_data in instrument_data.items():
102
106
  function_data["signature"] = str(function_data["signature"])
@@ -44,7 +44,7 @@ def workflow_logs(workflow_id:int):
44
44
 
45
45
  get workflow data logs by workflow id
46
46
 
47
- .. http:get:: /executions/<int:workflow_id>
47
+ .. http:get:: /executions/records/<int:workflow_id>
48
48
 
49
49
  :param workflow_id: workflow id
50
50
  :type workflow_id: int
@@ -109,6 +109,15 @@ def workflow_logs(workflow_id:int):
109
109
 
110
110
  @data.get("/executions/data/<int:workflow_id>")
111
111
  def workflow_phase_data(workflow_id: int):
112
+ """
113
+ .. :quickref: Workflow Data Database; get workflow data for plotting
114
+
115
+ get workflow data for plotting by workflow id
116
+
117
+ .. http:get:: /executions/data/<int: workflow_id>
118
+
119
+ :param workflow_id: workflow id
120
+ """
112
121
  workflow = db.session.get(WorkflowRun, workflow_id)
113
122
  if not workflow:
114
123
  return jsonify({})
@@ -140,7 +149,7 @@ def delete_workflow_record(workflow_id: int):
140
149
 
141
150
  delete a workflow execution record by workflow id
142
151
 
143
- .. http:delete:: /executions/records/<int:workflow_id>
152
+ .. http:delete:: /executions/records/<int: workflow_id>
144
153
 
145
154
  :param workflow_id: workflow id
146
155
  :type workflow_id: int
@@ -163,7 +172,7 @@ def download_results(filename:str):
163
172
  :param filename: workflow data filename
164
173
  :type filename: str
165
174
 
166
- # :status 302: load pseudo deck and then redirects to :http:get:`/ivoryos/executions`
175
+ # :status 302: load pseudo deck and then redirects to :http:get:`/ivoryos/executions/records`
167
176
  """
168
177
 
169
178
  filepath = os.path.join(current_app.config["DATA_FOLDER"], filename)
@@ -257,7 +257,7 @@ def submit_script():
257
257
  """
258
258
  .. :quickref: Workflow Design; convert Python to workflow script
259
259
 
260
- .. http:post:: /design/submit_python
260
+ .. http:post:: /draft/submit_python
261
261
 
262
262
  Convert a Python script to a workflow script and save it in the database.
263
263
 
@@ -393,7 +393,7 @@ def get_operation_sidebar(instrument: str = ''):
393
393
  """
394
394
  .. :quickref: Workflow Design; handle methods of a specific instrument
395
395
 
396
- .. http:get:: /design/instruments/<string:instrument>
396
+ .. http:get:: /draft/instruments/<string:instrument>
397
397
 
398
398
  :param instrument: The name of the instrument to handle methods for.
399
399
  :type instrument: str
@@ -17,7 +17,7 @@ def load_json():
17
17
  .. http:post:: /files/script-json
18
18
 
19
19
  :form file: workflow design JSON file
20
- :status 302: load script json and then redirects to :http:get:`/ivoryos/design/draft`
20
+ :status 302: load script json and then redirects to :http:get:`/ivoryos/draft`
21
21
  """
22
22
 
23
23
  if request.method == "POST":
@@ -38,7 +38,7 @@ def download_python():
38
38
 
39
39
  .. http:post:: /files/script-python
40
40
 
41
- :status 302: redirects to :http:get:`/ivoryos/design/script/`
41
+ :status 302: redirects to :http:get:`/ivoryos/draft`
42
42
  """
43
43
  script = utils.get_script_file()
44
44
  run_name = script.name if script.name else "untitled"
@@ -53,7 +53,7 @@ def download_json():
53
53
 
54
54
  .. http:post:: /files/script-json
55
55
 
56
- :status 302: redirects to :http:get:`/ivoryos/design/script/`
56
+ :status 302: redirects to :http:get:`/ivoryos/draft`
57
57
  """
58
58
  script = utils.get_script_file()
59
59
  run_name = script.name if script.name else "untitled"
@@ -12,7 +12,7 @@ def get_step(uuid: int):
12
12
  """
13
13
  .. :quickref: Workflow Design Steps; get an action step editing form
14
14
 
15
- .. http:get:: /steps/<int:uuid>
15
+ .. http:get:: /draft/steps/<int:uuid>
16
16
 
17
17
  get the editing form for an action step
18
18
 
@@ -36,7 +36,7 @@ def save_step(uuid: int):
36
36
  """
37
37
  .. :quickref: Workflow Design Steps; save an action step on canvas
38
38
 
39
- .. http:post:: /steps/<int:uuid>
39
+ .. http:post:: /draft/steps/<int:uuid>
40
40
 
41
41
  save the changes of an action step
42
42
 
@@ -69,7 +69,7 @@ def delete_step(uuid: int):
69
69
  """
70
70
  .. :quickref: Workflow Design Steps; delete an action step on canvas
71
71
 
72
- .. http:delete:: /steps/<int:uuid>
72
+ .. http:delete:: /draft/steps/<int:uuid>
73
73
 
74
74
  delete an action step
75
75
 
@@ -9,7 +9,7 @@ from flask_login import login_required
9
9
  from ivoryos.routes.execute.execute_file import files
10
10
  from ivoryos.utils import utils
11
11
  from ivoryos.utils.bo_campaign import parse_optimization_form
12
- from ivoryos.utils.db_models import SingleStep, WorkflowRun, WorkflowStep
12
+ from ivoryos.utils.db_models import SingleStep, WorkflowRun, WorkflowStep, WorkflowPhase
13
13
  from ivoryos.utils.global_config import GlobalConfig
14
14
  from ivoryos.utils.form import create_action_button
15
15
 
@@ -157,6 +157,7 @@ def experiment_run():
157
157
  def run_bo():
158
158
  """
159
159
  .. :quickref: Workflow Execution; run Bayesian Optimization
160
+
160
161
  Run Bayesian Optimization with the given parameters and objectives.
161
162
 
162
163
  .. http:post:: /executions/campaign
@@ -166,6 +167,7 @@ def run_bo():
166
167
  :form existing_data: existing data to use for optimization
167
168
  :form parameters: parameters for optimization
168
169
  :form objectives: objectives for optimization
170
+
169
171
  TODO: merge to experiment_run or not, add more details about the form fields and their expected values.
170
172
  """
171
173
  script = utils.get_script_file()
@@ -225,7 +227,9 @@ def runner_status():
225
227
  if task_type == "workflow":
226
228
  workflow = WorkflowRun.query.get(task_id)
227
229
  if workflow is not None:
228
- latest_step = WorkflowStep.query.filter_by(workflow_id=workflow.id).order_by(
230
+ phases = WorkflowPhase.query.filter_by(run_id=workflow.id).order_by(WorkflowPhase.start_time).all()
231
+ current_phase = phases[-1]
232
+ latest_step = WorkflowStep.query.filter_by(phase_id=current_phase.id).order_by(
229
233
  WorkflowStep.start_time.desc()).first()
230
234
  if latest_step is not None:
231
235
  current_step = latest_step.as_dict()
@@ -13,25 +13,25 @@ library = Blueprint('library', __name__, template_folder='templates')
13
13
  def workflow_script(script_name:str):
14
14
  # todo: split this into two routes, one for GET and POST, another for DELETE
15
15
  """
16
- .. :quickref: Workflow Script Database; get, post, delete workflow script
16
+ .. :quickref: Workflow Script Database; get, post, delete a workflow script
17
17
 
18
- .. http:get:: /<string:script_name>
18
+ .. http:get:: /library/<string: script_name>
19
19
 
20
20
  :param script_name: script name
21
21
  :type script_name: str
22
- :status 302: redirect to :http:get:`/ivoryos/design/script/`
22
+ :status 302: redirect to :http:get:`/ivoryos/draft`
23
23
 
24
- .. http:post:: /<string:script_name>
24
+ .. http:post:: /library/<string: script_name>
25
25
 
26
26
  :param script_name: script name
27
27
  :type script_name: str
28
28
  :status 200: json response with success status
29
29
 
30
- .. http:delete:: /<string:script_name>
30
+ .. http:delete:: /library/<string: script_name>
31
31
 
32
32
  :param script_name: script name
33
33
  :type script_name: str
34
- :status 302: redirect to :http:get:`/ivoryos/design/script/`
34
+ :status 302: redirect to :http:get:`/ivoryos/draft`
35
35
 
36
36
  """
37
37
  row = Script.query.get(script_name)
@@ -89,10 +89,8 @@ def load_from_database():
89
89
 
90
90
  backend control through http requests
91
91
 
92
- .. http:get:: /designs/get/<deck_name>
92
+ .. http:get:: /library
93
93
 
94
- :param deck_name: filter for deck name
95
- :type deck_name: str
96
94
 
97
95
  """
98
96
  session.pop('edit_action', None) # reset cache
@@ -132,10 +130,10 @@ def save_as():
132
130
 
133
131
  save the current workflow script as
134
132
 
135
- .. http:post:: /library/save_as
133
+ .. http:post:: /library
136
134
 
137
135
  : form run_name: new workflow name
138
- :status 302: redirect to :http:get:`/ivoryos/design/script/`
136
+ :status 302: redirect to :http:get:`/ivoryos/draft`
139
137
 
140
138
  """
141
139
  if request.method == "POST":
@@ -143,12 +143,38 @@ def convert_to_cards(source_code: str):
143
143
  f = f.value
144
144
  if isinstance(f, ast.Name):
145
145
  func_parts.insert(0, f.id)
146
- if not func_parts or not func_parts[0].startswith("deck"):
146
+ if not func_parts:
147
147
  return
148
148
 
149
149
  instrument = ".".join(func_parts[:-1])
150
150
  action = func_parts[-1]
151
151
 
152
+
153
+ # --- special case for time.sleep ---
154
+ if instrument == "time" and action == "sleep":
155
+ wait_value = None
156
+ if node.args:
157
+ arg_node = node.args[0]
158
+ if isinstance(arg_node, ast.Constant):
159
+ wait_value = arg_node.value
160
+ elif isinstance(arg_node, ast.Name):
161
+ wait_value = f"#{arg_node.id}"
162
+ else:
163
+ wait_value = ast.unparse(arg_node)
164
+
165
+ add_card({
166
+ "action": "wait",
167
+ "arg_types": {"statement": infer_type(wait_value)},
168
+ "args": {"statement": wait_value},
169
+ "id": new_id(),
170
+ "instrument": "wait",
171
+ "return": ret_var,
172
+ "uuid": generate_uuid()
173
+ })
174
+ return
175
+ # -----------------------------------
176
+
177
+
152
178
  args = {}
153
179
  arg_types = {}
154
180
 
@@ -170,7 +170,7 @@ class ScriptRunner:
170
170
  # line = line.replace("registered_workflows.", "")
171
171
  try:
172
172
  if line.startswith("time.sleep("): # add safe sleep for time.sleep lines
173
- duration_str = line[len("time.sleep("):-1]
173
+ duration_str = line.strip()[len("time.sleep("):-1]
174
174
  duration = float(duration_str)
175
175
  self.safe_sleep(duration)
176
176
  else:
@@ -0,0 +1 @@
1
+ __version__ = "1.3.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ivoryos
3
- Version: 1.3.0a0
3
+ Version: 1.3.2
4
4
  Summary: an open-source Python package enabling Self-Driving Labs (SDLs) interoperability
5
5
  Author-email: Ivory Zhang <ivoryzhang@chem.ubc.ca>
6
6
  License: MIT
@@ -1 +0,0 @@
1
- __version__ = "1.3.0a0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes