ivoryos 1.3.7__tar.gz → 1.4.6__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 (137) hide show
  1. {ivoryos-1.3.7 → ivoryos-1.4.6}/PKG-INFO +70 -47
  2. {ivoryos-1.3.7 → ivoryos-1.4.6}/README.md +64 -43
  3. ivoryos-1.4.6/docs/source/conf.py +84 -0
  4. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/app.py +29 -5
  5. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/optimizer/ax_optimizer.py +52 -25
  6. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/optimizer/base_optimizer.py +19 -1
  7. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/optimizer/baybe_optimizer.py +27 -17
  8. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/optimizer/nimo_optimizer.py +35 -24
  9. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/auth/auth.py +26 -1
  10. ivoryos-1.4.6/ivoryos/routes/auth/templates/change_password.html +32 -0
  11. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/control/control_new_device.py +21 -11
  12. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/data/data.py +27 -9
  13. ivoryos-1.4.6/ivoryos/routes/data/templates/components/step_card.html +78 -0
  14. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/data/templates/workflow_view.html +14 -5
  15. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/design.py +31 -1
  16. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/design_step.py +2 -1
  17. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/edit_action_form.html +16 -3
  18. ivoryos-1.4.6/ivoryos/routes/design/templates/components/info_modal.html +318 -0
  19. ivoryos-1.4.6/ivoryos/routes/design/templates/components/python_code_overlay.html +56 -0
  20. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/experiment_builder.html +3 -0
  21. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/execute/execute.py +76 -20
  22. ivoryos-1.4.6/ivoryos/routes/execute/templates/components/logging_panel.html +56 -0
  23. ivoryos-1.4.6/ivoryos/routes/execute/templates/components/run_tabs.html +60 -0
  24. ivoryos-1.4.6/ivoryos/routes/execute/templates/components/tab_bayesian.html +520 -0
  25. ivoryos-1.4.6/ivoryos/routes/execute/templates/components/tab_configuration.html +383 -0
  26. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/execute/templates/components/tab_repeat.html +6 -2
  27. ivoryos-1.4.6/ivoryos/routes/execute/templates/experiment_run.html +30 -0
  28. ivoryos-1.4.6/ivoryos/routes/main/main.py +70 -0
  29. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/server.py +1 -0
  30. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/socket_handlers.py +1 -1
  31. ivoryos-1.4.6/ivoryos/static/ivoryos_logo.png +0 -0
  32. ivoryos-1.4.6/ivoryos/static/js/action_handlers.js +378 -0
  33. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/js/sortable_design.js +1 -0
  34. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/js/ui_state.js +1 -3
  35. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/templates/base.html +61 -2
  36. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/bo_campaign.py +17 -16
  37. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/client_proxy.py +11 -6
  38. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/db_models.py +171 -37
  39. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/decorators.py +1 -0
  40. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/form.py +32 -12
  41. ivoryos-1.4.6/ivoryos/utils/nest_script.py +314 -0
  42. ivoryos-1.4.6/ivoryos/utils/script_runner.py +770 -0
  43. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/task_runner.py +30 -0
  44. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/utils.py +21 -2
  45. ivoryos-1.4.6/ivoryos/version.py +1 -0
  46. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos.egg-info/PKG-INFO +70 -47
  47. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos.egg-info/SOURCES.txt +17 -2
  48. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos.egg-info/requires.txt +6 -4
  49. ivoryos-1.4.6/ivoryos.egg-info/top_level.txt +4 -0
  50. {ivoryos-1.3.7 → ivoryos-1.4.6}/pyproject.toml +6 -2
  51. ivoryos-1.4.6/tests/__init__.py +0 -0
  52. ivoryos-1.4.6/tests/conftest.py +133 -0
  53. ivoryos-1.4.6/tests/integration/__init__.py +0 -0
  54. ivoryos-1.4.6/tests/integration/test_route_auth.py +80 -0
  55. ivoryos-1.4.6/tests/integration/test_route_control.py +94 -0
  56. ivoryos-1.4.6/tests/integration/test_route_database.py +61 -0
  57. ivoryos-1.4.6/tests/integration/test_route_design.py +36 -0
  58. ivoryos-1.4.6/tests/integration/test_route_main.py +35 -0
  59. ivoryos-1.4.6/tests/integration/test_sockets.py +26 -0
  60. ivoryos-1.4.6/tests/unit/test_type_conversion.py +42 -0
  61. ivoryos-1.4.6/tests/unit/test_util.py +3 -0
  62. ivoryos-1.3.7/ivoryos/routes/api/api.py +0 -57
  63. ivoryos-1.3.7/ivoryos/routes/data/templates/components/step_card.html +0 -42
  64. ivoryos-1.3.7/ivoryos/routes/design/templates/components/python_code_overlay.html +0 -39
  65. ivoryos-1.3.7/ivoryos/routes/execute/templates/components/logging_panel.html +0 -31
  66. ivoryos-1.3.7/ivoryos/routes/execute/templates/components/run_tabs.html +0 -17
  67. ivoryos-1.3.7/ivoryos/routes/execute/templates/components/tab_bayesian.html +0 -398
  68. ivoryos-1.3.7/ivoryos/routes/execute/templates/components/tab_configuration.html +0 -98
  69. ivoryos-1.3.7/ivoryos/routes/execute/templates/experiment_run.html +0 -294
  70. ivoryos-1.3.7/ivoryos/routes/main/main.py +0 -42
  71. ivoryos-1.3.7/ivoryos/static/js/action_handlers.js +0 -250
  72. ivoryos-1.3.7/ivoryos/utils/script_runner.py +0 -489
  73. ivoryos-1.3.7/ivoryos/version.py +0 -1
  74. ivoryos-1.3.7/ivoryos.egg-info/top_level.txt +0 -1
  75. {ivoryos-1.3.7 → ivoryos-1.4.6}/LICENSE +0 -0
  76. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/__init__.py +0 -0
  77. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/config.py +0 -0
  78. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/optimizer/registry.py +0 -0
  79. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/__init__.py +0 -0
  80. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/auth/__init__.py +0 -0
  81. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/auth/templates/login.html +0 -0
  82. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/auth/templates/signup.html +0 -0
  83. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/control/__init__.py +0 -0
  84. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/control/control.py +0 -0
  85. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/control/control_file.py +0 -0
  86. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/control/templates/controllers.html +0 -0
  87. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/control/templates/controllers_new.html +0 -0
  88. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/control/utils.py +0 -0
  89. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/data/__init__.py +0 -0
  90. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/data/templates/workflow_database.html +0 -0
  91. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/__init__.py +0 -0
  92. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/design_file.py +0 -0
  93. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/action_form.html +0 -0
  94. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/actions_panel.html +0 -0
  95. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/autofill_toggle.html +0 -0
  96. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/canvas.html +0 -0
  97. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/canvas_footer.html +0 -0
  98. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/canvas_header.html +0 -0
  99. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/canvas_main.html +0 -0
  100. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/deck_selector.html +0 -0
  101. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/instruments_panel.html +0 -0
  102. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/modals/drop_modal.html +0 -0
  103. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/modals/json_modal.html +0 -0
  104. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/modals/new_script_modal.html +0 -0
  105. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/modals/rename_modal.html +0 -0
  106. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/modals/saveas_modal.html +0 -0
  107. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/modals.html +0 -0
  108. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/sidebar.html +0 -0
  109. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/design/templates/components/text_to_code_panel.html +0 -0
  110. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/execute/__init__.py +0 -0
  111. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/execute/execute_file.py +0 -0
  112. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/execute/templates/components/error_modal.html +0 -0
  113. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/execute/templates/components/progress_panel.html +0 -0
  114. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/execute/templates/components/run_panel.html +0 -0
  115. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/library/__init__.py +0 -0
  116. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/library/library.py +0 -0
  117. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/library/templates/library.html +0 -0
  118. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/main/__init__.py +0 -0
  119. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/main/templates/help.html +0 -0
  120. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/routes/main/templates/home.html +0 -0
  121. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/favicon.ico +0 -0
  122. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/gui_annotation/Slide1.png +0 -0
  123. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/gui_annotation/Slide2.PNG +0 -0
  124. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/js/db_delete.js +0 -0
  125. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/js/overlay.js +0 -0
  126. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/js/script_metadata.js +0 -0
  127. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/js/socket_handler.js +0 -0
  128. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/js/sortable_card.js +0 -0
  129. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/logo.webp +0 -0
  130. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/static/style.css +0 -0
  131. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/__init__.py +0 -0
  132. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/global_config.py +0 -0
  133. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/llm_agent.py +0 -0
  134. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/py_to_json.py +0 -0
  135. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos/utils/serilize.py +0 -0
  136. {ivoryos-1.3.7 → ivoryos-1.4.6}/ivoryos.egg-info/dependency_links.txt +0 -0
  137. {ivoryos-1.3.7 → ivoryos-1.4.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ivoryos
3
- Version: 1.3.7
3
+ Version: 1.4.6
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
@@ -17,6 +17,7 @@ Requires-Dist: Flask-SQLAlchemy
17
17
  Requires-Dist: Flask-WTF
18
18
  Requires-Dist: SQLAlchemy-Utils
19
19
  Requires-Dist: python-dotenv
20
+ Requires-Dist: pandas
20
21
  Requires-Dist: astor; python_version < "3.9"
21
22
  Provides-Extra: optimizer-ax
22
23
  Requires-Dist: ax-platform; extra == "optimizer-ax"
@@ -24,9 +25,10 @@ Provides-Extra: optimizer-baybe
24
25
  Requires-Dist: baybe; extra == "optimizer-baybe"
25
26
  Provides-Extra: optimizer-nimo
26
27
  Requires-Dist: nimo; extra == "optimizer-nimo"
27
- Provides-Extra: optimizer
28
- Requires-Dist: ax-platform>=1.1.2; extra == "optimizer"
29
- Requires-Dist: baybe; extra == "optimizer"
28
+ Provides-Extra: optimizers
29
+ Requires-Dist: ax-platform>=1.1.2; extra == "optimizers"
30
+ Requires-Dist: baybe>=0.14.0; extra == "optimizers"
31
+ Requires-Dist: nimo; extra == "optimizers"
30
32
  Provides-Extra: doc
31
33
  Requires-Dist: sphinx; extra == "doc"
32
34
  Requires-Dist: sphinx-rtd-theme; extra == "doc"
@@ -41,34 +43,35 @@ Dynamic: license-file
41
43
  [![YouTube](https://img.shields.io/badge/YouTube-tutorial-red?logo=youtube)](https://youtu.be/dFfJv9I2-1g)
42
44
  [![YouTube](https://img.shields.io/badge/YouTube-demo-red?logo=youtube)](https://youtu.be/flr5ydiE96s)
43
45
  [![Published](https://img.shields.io/badge/Nature_Comm.-paper-blue)](https://www.nature.com/articles/s41467-025-60514-w)
46
+ [![Community](https://img.shields.io/discord/1313641159356059770?label=Discord&logo=discord&color=5865F2)](https://discord.gg/AX5P9EdGVX)
44
47
 
45
- [//]: # ([![Discord]&#40;https://img.shields.io/discord/1313641159356059770?label=Discord&logo=discord&color=5865F2&#41;]&#40;https://discord.gg/AX5P9EdGVX&#41;)
48
+ ![ivoryos_logo.png](https://gitlab.com/heingroup/ivoryos/raw/main/docs/source/_static/ivoryos_logo.png)
46
49
 
47
- ![](https://gitlab.com/heingroup/ivoryos/raw/main/docs/source/_static/ivoryos.png)
48
- # ivoryOS: interoperable Web UI for self-driving laboratories (SDLs)
49
- A **plug-and-play** web interface for flexible SDLs
50
+ # [IvoryOS](https://ivoryos.ai): interoperable orchestrator for self-driving laboratories (SDLs)
51
+
52
+ A **plug-and-play** web interface for flexible, modular SDLs
53
+ you focus on developing protocols, IvoryOS handles the rest.
54
+
55
+ ![code_launch_design.png](https://gitlab.com/heingroup/ivoryos/raw/main/docs/source/_static/code_launch_design.png)
50
56
 
51
57
  ---
52
58
 
53
59
  ## Table of Contents
54
- - [Description](#description)
60
+ - [What IvoryOS does](#what-ivoryos-does)
55
61
  - [System requirements](#system-requirements)
56
62
  - [Installation](#installation)
57
- - [Quick Start](#quick-start)
58
63
  - [Features](#features)
59
64
  - [Demo](#demo)
60
65
  - [Roadmap](#roadmap)
66
+ - [Contributing](#contributing)
61
67
  - [Acknowledgements](#acknowledgements)
62
68
 
63
69
  ---
64
- ## Description
65
- Building UIs for SDLs is challenging because flexibility and modularity make them unpredictable yet accessibility is essential for **democratisation** of AI-driven scientific discovery.
66
-
67
- **IvoryOS** bridges the gap by:
68
- - Dynamically inspecting initialized Python modules (hardware APIs, high-level functions, or workflows)
69
- - Automatically displaying functions and parameters in a web UI
70
- - Allowing users to **design**, **manage**, and **execute** experimental workflows with minimal changes to existing scripts
71
- - Providing natural language support for workflow design and execution, check [IvoryOS MCP](https://gitlab.com/heingroup/ivoryos-suite/ivoryos-mcp) for more details.
70
+ ## What IvoryOS Does
71
+ - Turns Python modules into UIs by dynamically inspecting your hardware APIs, functions, and workflows.
72
+ - Standardizes optimization inputs/outputs, making any optimizer plug-and-play.
73
+ - Provides a visual workflow builder for designing and running experiments.
74
+ - Adds natural-language control for creating and executing workflows, see [IvoryOS MCP](https://gitlab.com/heingroup/ivoryos-suite/ivoryos-mcp) for more details.
72
75
 
73
76
  ----
74
77
  ## System Requirements
@@ -90,10 +93,13 @@ Building UIs for SDLs is challenging because flexibility and modularity make the
90
93
  - SQLAlchemy-Utils~=0.41
91
94
  - Flask-WTF~=1.2
92
95
  - python-dotenv==1.0.1
96
+ - pandas
93
97
 
94
98
  **Optional:**
95
- - ax-platform (≥1.0, Python≥3.10)
96
- - baybe
99
+ - ax-platform==1.1.2
100
+ - baybe==0.14.0
101
+ - nimo
102
+ - slack-sdk
97
103
  </details>
98
104
 
99
105
  ---
@@ -104,16 +110,22 @@ From PyPI:
104
110
  ```bash
105
111
  pip install ivoryos
106
112
  ```
107
- From source:
108
- ```bash
109
- git clone https://gitlab.com/heingroup/ivoryos.git
110
- cd ivoryos
111
- pip install -e .
112
- ```
113
+
114
+ [//]: # (From source:)
115
+
116
+ [//]: # (```bash)
117
+
118
+ [//]: # (git clone https://gitlab.com/heingroup/ivoryos.git)
119
+
120
+ [//]: # (cd ivoryos)
121
+
122
+ [//]: # (pip install -e .)
123
+
124
+ [//]: # (```)
113
125
 
114
126
 
115
127
  ## Quick start
116
- In your SDL script,
128
+ In your script, where you initialize or import your robot:
117
129
  ```python
118
130
  my_robot = Robot()
119
131
 
@@ -121,8 +133,8 @@ import ivoryos
121
133
 
122
134
  ivoryos.run(__name__)
123
135
  ```
124
- You can now access the web UI at http://127.0.0.1:8000,
125
- create an account, login, and start designing workflows!
136
+ Then run the script and visit `http://localhost:8000` in your browser.
137
+ Use `admin` for both username and password, and start building workflows!
126
138
 
127
139
  ----
128
140
  ## Features
@@ -145,7 +157,8 @@ ivoryos.run(__name__, logger="logger name")
145
157
  ivoryos.run(__name__, logger=["logger 1", "logger 2"])
146
158
  ```
147
159
  ### Human-in-the-loop
148
- Add single or multiple notification handlers for `pause` feature in flow control:
160
+ Use `pause` in flow control to pause the workflow and send a notification with custom message handler(s).
161
+ When run into `pause`, it will pause, send a message, and wait for human's response. Example of a Slack bot:
149
162
  ```python
150
163
 
151
164
  def slack_bot(msg: str = "Hi"):
@@ -168,24 +181,24 @@ ivoryos.run(__name__, notification_handler=slack_bot)
168
181
 
169
182
  ### Directory Structure
170
183
 
171
- Created automatically on first run:
184
+ Created automatically in the same working directory on the first run:
185
+ <details>
186
+ <summary>click to see the data folder structure</summary>
187
+
172
188
  - **`ivoryos_data/`**:
173
- - **`ivoryos_data/config_csv/`**: Batch configuration `csv`
174
- - **`ivoryos_data/pseudo_deck/`**: Offline deck `.pkl`
175
- - **`ivoryos_data/results/`**: Execution results
176
- - **`ivoryos_data/scripts/`**: Compiled workflows Python scripts
177
- - **`default.log`**: Application logs
178
- - **`ivoryos.db`**: Local database
189
+ - **`config_csv/`**: Batch configuration `csv`
190
+ - **`pseudo_deck/`**: Offline deck `.pkl`
191
+ - **`results/`**: Execution results
192
+ - **`scripts/`**: Compiled workflows Python scripts
193
+ - **`default.log`**: Application logs
194
+ - **`ivoryos.db`**: Local database
195
+ </details>
196
+
179
197
  ---
180
- ## Demo
181
- In the [abstract_sdl.py](https://gitlab.com/heingroup/ivoryos/-/blob/main/example/abstract_sdl_example/abstract_sdl.py)
182
- ```Python
183
- ivoryos.run(__name__)
184
- ```
185
198
 
186
- * Running on all addresses (0.0.0.0)
187
- * Running on http://127.0.0.1:8000
188
- * Running on http://0.0.0.0:8000
199
+ ## Demo
200
+ Online demo at [demo.ivoryos.ai](https://demo.ivoryos.ai).
201
+ Local version in [abstract_sdl.py](https://gitlab.com/heingroup/ivoryos/-/blob/main/community/examples/abstract_sdl_example/abstract_sdl.py)
189
202
 
190
203
  ---
191
204
 
@@ -193,14 +206,22 @@ ivoryos.run(__name__)
193
206
 
194
207
  - [ ] dropdown input
195
208
  - [ ] snapshot version control
196
- - [ ] optimizer-agnostic
197
- - [ ] prefect compatibility
198
209
  - [ ] check batch-config file compatibility
199
210
 
200
211
  ---
201
212
 
213
+ ## Contributing
214
+
215
+ We welcome all contributions — from core improvements to new drivers, plugins, and real-world use cases.
216
+ See `CONTRIBUTING.md` for details and let us know you're interested: https://forms.gle/fPSvw5LEGrweUQUH8
217
+
218
+ ---
219
+
202
220
  ## Citing
203
221
 
222
+ <details>
223
+ <summary>Click to see citations</summary>
224
+
204
225
  If you find this project useful, please consider citing the following manuscript:
205
226
 
206
227
  > Zhang, W., Hao, L., Lai, V. et al. [IvoryOS: an interoperable web interface for orchestrating Python-based self-driving laboratories.](https://www.nature.com/articles/s41467-025-60514-w) Nat Commun 16, 5182 (2025).
@@ -234,6 +255,8 @@ For an additional perspective related to the development of the tool, please see
234
255
  url = {https://communities.springernature.com/posts/behind-ivoryos-empowering-scientists-to-harness-self-driving-labs-for-accelerated-discovery}
235
256
  }
236
257
  ```
258
+ </details>
259
+
237
260
  ---
238
261
  ## Acknowledgements
239
262
  Authors acknowledge Telescope Innovations Corp., UBC Hein Lab, and Acceleration Consortium members for their valuable suggestions and contributions.
@@ -4,34 +4,35 @@
4
4
  [![YouTube](https://img.shields.io/badge/YouTube-tutorial-red?logo=youtube)](https://youtu.be/dFfJv9I2-1g)
5
5
  [![YouTube](https://img.shields.io/badge/YouTube-demo-red?logo=youtube)](https://youtu.be/flr5ydiE96s)
6
6
  [![Published](https://img.shields.io/badge/Nature_Comm.-paper-blue)](https://www.nature.com/articles/s41467-025-60514-w)
7
+ [![Community](https://img.shields.io/discord/1313641159356059770?label=Discord&logo=discord&color=5865F2)](https://discord.gg/AX5P9EdGVX)
7
8
 
8
- [//]: # ([![Discord]&#40;https://img.shields.io/discord/1313641159356059770?label=Discord&logo=discord&color=5865F2&#41;]&#40;https://discord.gg/AX5P9EdGVX&#41;)
9
+ ![ivoryos_logo.png](https://gitlab.com/heingroup/ivoryos/raw/main/docs/source/_static/ivoryos_logo.png)
9
10
 
10
- ![](https://gitlab.com/heingroup/ivoryos/raw/main/docs/source/_static/ivoryos.png)
11
- # ivoryOS: interoperable Web UI for self-driving laboratories (SDLs)
12
- A **plug-and-play** web interface for flexible SDLs
11
+ # [IvoryOS](https://ivoryos.ai): interoperable orchestrator for self-driving laboratories (SDLs)
12
+
13
+ A **plug-and-play** web interface for flexible, modular SDLs
14
+ you focus on developing protocols, IvoryOS handles the rest.
15
+
16
+ ![code_launch_design.png](https://gitlab.com/heingroup/ivoryos/raw/main/docs/source/_static/code_launch_design.png)
13
17
 
14
18
  ---
15
19
 
16
20
  ## Table of Contents
17
- - [Description](#description)
21
+ - [What IvoryOS does](#what-ivoryos-does)
18
22
  - [System requirements](#system-requirements)
19
23
  - [Installation](#installation)
20
- - [Quick Start](#quick-start)
21
24
  - [Features](#features)
22
25
  - [Demo](#demo)
23
26
  - [Roadmap](#roadmap)
27
+ - [Contributing](#contributing)
24
28
  - [Acknowledgements](#acknowledgements)
25
29
 
26
30
  ---
27
- ## Description
28
- Building UIs for SDLs is challenging because flexibility and modularity make them unpredictable yet accessibility is essential for **democratisation** of AI-driven scientific discovery.
29
-
30
- **IvoryOS** bridges the gap by:
31
- - Dynamically inspecting initialized Python modules (hardware APIs, high-level functions, or workflows)
32
- - Automatically displaying functions and parameters in a web UI
33
- - Allowing users to **design**, **manage**, and **execute** experimental workflows with minimal changes to existing scripts
34
- - Providing natural language support for workflow design and execution, check [IvoryOS MCP](https://gitlab.com/heingroup/ivoryos-suite/ivoryos-mcp) for more details.
31
+ ## What IvoryOS Does
32
+ - Turns Python modules into UIs by dynamically inspecting your hardware APIs, functions, and workflows.
33
+ - Standardizes optimization inputs/outputs, making any optimizer plug-and-play.
34
+ - Provides a visual workflow builder for designing and running experiments.
35
+ - Adds natural-language control for creating and executing workflows, see [IvoryOS MCP](https://gitlab.com/heingroup/ivoryos-suite/ivoryos-mcp) for more details.
35
36
 
36
37
  ----
37
38
  ## System Requirements
@@ -53,10 +54,13 @@ Building UIs for SDLs is challenging because flexibility and modularity make the
53
54
  - SQLAlchemy-Utils~=0.41
54
55
  - Flask-WTF~=1.2
55
56
  - python-dotenv==1.0.1
57
+ - pandas
56
58
 
57
59
  **Optional:**
58
- - ax-platform (≥1.0, Python≥3.10)
59
- - baybe
60
+ - ax-platform==1.1.2
61
+ - baybe==0.14.0
62
+ - nimo
63
+ - slack-sdk
60
64
  </details>
61
65
 
62
66
  ---
@@ -67,16 +71,22 @@ From PyPI:
67
71
  ```bash
68
72
  pip install ivoryos
69
73
  ```
70
- From source:
71
- ```bash
72
- git clone https://gitlab.com/heingroup/ivoryos.git
73
- cd ivoryos
74
- pip install -e .
75
- ```
74
+
75
+ [//]: # (From source:)
76
+
77
+ [//]: # (```bash)
78
+
79
+ [//]: # (git clone https://gitlab.com/heingroup/ivoryos.git)
80
+
81
+ [//]: # (cd ivoryos)
82
+
83
+ [//]: # (pip install -e .)
84
+
85
+ [//]: # (```)
76
86
 
77
87
 
78
88
  ## Quick start
79
- In your SDL script,
89
+ In your script, where you initialize or import your robot:
80
90
  ```python
81
91
  my_robot = Robot()
82
92
 
@@ -84,8 +94,8 @@ import ivoryos
84
94
 
85
95
  ivoryos.run(__name__)
86
96
  ```
87
- You can now access the web UI at http://127.0.0.1:8000,
88
- create an account, login, and start designing workflows!
97
+ Then run the script and visit `http://localhost:8000` in your browser.
98
+ Use `admin` for both username and password, and start building workflows!
89
99
 
90
100
  ----
91
101
  ## Features
@@ -108,7 +118,8 @@ ivoryos.run(__name__, logger="logger name")
108
118
  ivoryos.run(__name__, logger=["logger 1", "logger 2"])
109
119
  ```
110
120
  ### Human-in-the-loop
111
- Add single or multiple notification handlers for `pause` feature in flow control:
121
+ Use `pause` in flow control to pause the workflow and send a notification with custom message handler(s).
122
+ When run into `pause`, it will pause, send a message, and wait for human's response. Example of a Slack bot:
112
123
  ```python
113
124
 
114
125
  def slack_bot(msg: str = "Hi"):
@@ -131,24 +142,24 @@ ivoryos.run(__name__, notification_handler=slack_bot)
131
142
 
132
143
  ### Directory Structure
133
144
 
134
- Created automatically on first run:
145
+ Created automatically in the same working directory on the first run:
146
+ <details>
147
+ <summary>click to see the data folder structure</summary>
148
+
135
149
  - **`ivoryos_data/`**:
136
- - **`ivoryos_data/config_csv/`**: Batch configuration `csv`
137
- - **`ivoryos_data/pseudo_deck/`**: Offline deck `.pkl`
138
- - **`ivoryos_data/results/`**: Execution results
139
- - **`ivoryos_data/scripts/`**: Compiled workflows Python scripts
140
- - **`default.log`**: Application logs
141
- - **`ivoryos.db`**: Local database
150
+ - **`config_csv/`**: Batch configuration `csv`
151
+ - **`pseudo_deck/`**: Offline deck `.pkl`
152
+ - **`results/`**: Execution results
153
+ - **`scripts/`**: Compiled workflows Python scripts
154
+ - **`default.log`**: Application logs
155
+ - **`ivoryos.db`**: Local database
156
+ </details>
157
+
142
158
  ---
143
- ## Demo
144
- In the [abstract_sdl.py](https://gitlab.com/heingroup/ivoryos/-/blob/main/example/abstract_sdl_example/abstract_sdl.py)
145
- ```Python
146
- ivoryos.run(__name__)
147
- ```
148
159
 
149
- * Running on all addresses (0.0.0.0)
150
- * Running on http://127.0.0.1:8000
151
- * Running on http://0.0.0.0:8000
160
+ ## Demo
161
+ Online demo at [demo.ivoryos.ai](https://demo.ivoryos.ai).
162
+ Local version in [abstract_sdl.py](https://gitlab.com/heingroup/ivoryos/-/blob/main/community/examples/abstract_sdl_example/abstract_sdl.py)
152
163
 
153
164
  ---
154
165
 
@@ -156,14 +167,22 @@ ivoryos.run(__name__)
156
167
 
157
168
  - [ ] dropdown input
158
169
  - [ ] snapshot version control
159
- - [ ] optimizer-agnostic
160
- - [ ] prefect compatibility
161
170
  - [ ] check batch-config file compatibility
162
171
 
163
172
  ---
164
173
 
174
+ ## Contributing
175
+
176
+ We welcome all contributions — from core improvements to new drivers, plugins, and real-world use cases.
177
+ See `CONTRIBUTING.md` for details and let us know you're interested: https://forms.gle/fPSvw5LEGrweUQUH8
178
+
179
+ ---
180
+
165
181
  ## Citing
166
182
 
183
+ <details>
184
+ <summary>Click to see citations</summary>
185
+
167
186
  If you find this project useful, please consider citing the following manuscript:
168
187
 
169
188
  > Zhang, W., Hao, L., Lai, V. et al. [IvoryOS: an interoperable web interface for orchestrating Python-based self-driving laboratories.](https://www.nature.com/articles/s41467-025-60514-w) Nat Commun 16, 5182 (2025).
@@ -197,6 +216,8 @@ For an additional perspective related to the development of the tool, please see
197
216
  url = {https://communities.springernature.com/posts/behind-ivoryos-empowering-scientists-to-harness-self-driving-labs-for-accelerated-discovery}
198
217
  }
199
218
  ```
219
+ </details>
220
+
200
221
  ---
201
222
  ## Acknowledgements
202
223
  Authors acknowledge Telescope Innovations Corp., UBC Hein Lab, and Acceleration Consortium members for their valuable suggestions and contributions.
@@ -0,0 +1,84 @@
1
+ # Configuration file for the Sphinx documentation builder.
2
+ import os
3
+ import sys
4
+ import urllib
5
+
6
+ import requests
7
+
8
+ # -- General configuration
9
+ sys.path.insert(0, os.path.abspath('../../'))
10
+ from ivoryos.version import __version__
11
+
12
+
13
+ # appending suite readme.rst to doc
14
+
15
+ external_readme = [
16
+ {
17
+ "name": 'plugin.rst',
18
+ "url": "https://gitlab.com/heingroup/ivoryos-suite/ivoryos-plugin-template/-/raw/main/README.rst"
19
+ },
20
+ {
21
+ "name": 'client.rst',
22
+ "url": "https://gitlab.com/heingroup/ivoryos-suite/ivoryos-client/-/raw/main/README.rst"
23
+ },
24
+ {
25
+ "name": 'mcp.rst',
26
+ "url": "https://gitlab.com/heingroup/ivoryos-suite/ivoryos-mcp/-/raw/main/README.rst"
27
+ }
28
+ ]
29
+
30
+ for item in external_readme:
31
+ readme_url = item['url']
32
+ name = item['name']
33
+ output_path = os.path.join(os.path.dirname(__file__), name)
34
+ r = requests.get(readme_url, verify=False)
35
+ if not os.path.exists(output_path):
36
+ with open(output_path, "wb") as f:
37
+ f.write(r.content)
38
+
39
+ # -- Project information
40
+ project = 'ivoryOS'
41
+ copyright = '2024, Ivory Zhang'
42
+ author = 'Ivory Zhang, Lucy Hao'
43
+ version = __version__
44
+
45
+ extensions = [
46
+ 'sphinx.ext.duration',
47
+ 'sphinx.ext.doctest',
48
+ 'sphinx.ext.autosummary',
49
+ 'sphinx.ext.intersphinx',
50
+ 'sphinxcontrib.httpdomain',
51
+ 'sphinxcontrib.autohttp.flask',
52
+ 'sphinxcontrib.autohttp.flaskqref'
53
+ ]
54
+
55
+ install_requires = [
56
+ 'sphinx-autodoc-typehints'
57
+ ]
58
+ autodoc_mock_imports = ["flask_sqlalchemy", "another_hard_to_import_lib"]
59
+
60
+
61
+ intersphinx_mapping = {
62
+ 'python': ('https://docs.python.org/3/', None),
63
+ 'sphinx': ('https://www.sphinx-doc.org/en/master/', None),
64
+ }
65
+ intersphinx_disabled_domains = ['std']
66
+
67
+ templates_path = ['_templates']
68
+
69
+ html_static_path = ['_static']
70
+ html_css_files = [
71
+ 'custom.css',
72
+ ]
73
+
74
+ html_allow_raw_html = True
75
+
76
+ # -- Options for HTML output
77
+
78
+ html_theme = 'sphinx_rtd_theme'
79
+
80
+ # -- Options for EPUB output
81
+ epub_show_urls = 'footnote'
82
+
83
+ # The master toctree document.
84
+ master_doc = 'index'
@@ -1,24 +1,22 @@
1
1
  import os
2
2
  import uuid
3
3
 
4
+ import bcrypt
4
5
  from flask import Flask, session, g, redirect, url_for
5
6
  from flask_login import AnonymousUserMixin
6
7
 
7
8
  from ivoryos.utils import utils
8
- from ivoryos.utils.db_models import db
9
- from ivoryos.config import Config, get_config
9
+ from ivoryos.utils.db_models import db, User
10
10
  from ivoryos.routes.auth.auth import auth, login_manager
11
11
  from ivoryos.routes.control.control import control
12
12
  from ivoryos.routes.data.data import data
13
13
  from ivoryos.routes.library.library import library
14
14
  from ivoryos.routes.design.design import design
15
15
  from ivoryos.routes.execute.execute import execute
16
- from ivoryos.routes.api.api import api
17
16
  from ivoryos.socket_handlers import socketio
18
17
  from ivoryos.routes.main.main import main
19
18
  from ivoryos.version import __version__ as ivoryos_version
20
19
  from sqlalchemy import inspect, text
21
- from flask import current_app
22
20
 
23
21
  url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
24
22
  app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
@@ -29,7 +27,7 @@ app.register_blueprint(control, url_prefix=f'{url_prefix}/instruments')
29
27
  app.register_blueprint(design, url_prefix=f'{url_prefix}')
30
28
  app.register_blueprint(execute, url_prefix=f'{url_prefix}')
31
29
  app.register_blueprint(data, url_prefix=f'{url_prefix}')
32
- app.register_blueprint(api, url_prefix=f'{url_prefix}/{api.name}')
30
+ # app.register_blueprint(api, url_prefix=f'{url_prefix}/{api.name}')
33
31
 
34
32
  def reset_old_schema(engine, db_dir):
35
33
  inspector = inspect(engine)
@@ -60,11 +58,36 @@ def reset_old_schema(engine, db_dir):
60
58
  conn.execute(text("DROP TABLE IF EXISTS workflow_steps"))
61
59
  if old_workflow_run:
62
60
  conn.execute(text("DROP TABLE IF EXISTS workflow_runs"))
61
+ with engine.begin() as conn:
62
+ try:
63
+ conn.execute(
64
+ text("ALTER TABLE user ADD COLUMN settings TEXT")
65
+ )
66
+ except Exception:
67
+ pass
63
68
 
64
69
  # Recreate new schema
65
70
  db.create_all() # creates workflow_runs, workflow_phases, workflow_steps
66
71
 
67
72
 
73
+ def create_admin():
74
+ """
75
+ Create an admin user with username 'admin' and password 'admin' if it doesn't exist.
76
+ """
77
+ with app.app_context():
78
+ admin_user = User.query.filter_by(username='admin').first()
79
+ if not admin_user:
80
+ print("Creating default admin user...")
81
+ admin_user = User(
82
+ username='admin',
83
+ password=bcrypt.hashpw("admin".encode('utf-8'), bcrypt.gensalt()),
84
+ )
85
+ db.session.add(admin_user)
86
+ db.session.commit()
87
+ else:
88
+ print("Admin user already exists.")
89
+
90
+
68
91
  def create_app(config_class=None):
69
92
  """
70
93
  create app, init database
@@ -82,6 +105,7 @@ def create_app(config_class=None):
82
105
  with app.app_context():
83
106
  # db.create_all()
84
107
  reset_old_schema(db.engine, app.config['OUTPUT_FOLDER'])
108
+ create_admin()
85
109
 
86
110
  # Additional setup
87
111
  utils.create_gui_dir(app.config['OUTPUT_FOLDER'])