ivoryos 0.1.23__tar.gz → 0.1.25__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.

Potentially problematic release.


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

Files changed (57) hide show
  1. {ivoryos-0.1.23/ivoryos.egg-info → ivoryos-0.1.25}/PKG-INFO +5 -6
  2. {ivoryos-0.1.23 → ivoryos-0.1.25}/README.md +4 -5
  3. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/__init__.py +16 -6
  4. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/design/design.py +5 -0
  5. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/utils/script_runner.py +11 -1
  6. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/utils/utils.py +53 -8
  7. ivoryos-0.1.25/ivoryos/version.py +1 -0
  8. {ivoryos-0.1.23 → ivoryos-0.1.25/ivoryos.egg-info}/PKG-INFO +5 -6
  9. ivoryos-0.1.23/ivoryos/version.py +0 -1
  10. {ivoryos-0.1.23 → ivoryos-0.1.25}/LICENSE +0 -0
  11. {ivoryos-0.1.23 → ivoryos-0.1.25}/MANIFEST.in +0 -0
  12. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/config.py +0 -0
  13. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/__init__.py +0 -0
  14. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/auth/__init__.py +0 -0
  15. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/auth/auth.py +0 -0
  16. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/auth/templates/auth/login.html +0 -0
  17. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/auth/templates/auth/signup.html +0 -0
  18. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/control/__init__.py +0 -0
  19. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/control/control.py +0 -0
  20. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/control/templates/control/controllers.html +0 -0
  21. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/control/templates/control/controllers_home.html +0 -0
  22. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/control/templates/control/controllers_new.html +0 -0
  23. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/database/__init__.py +0 -0
  24. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/database/database.py +0 -0
  25. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/database/templates/database/experiment_database.html +0 -0
  26. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/database/templates/database/experiment_step_view.html +0 -0
  27. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/database/templates/database/step_card.html +0 -0
  28. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/database/templates/database/workflow_run_database.html +0 -0
  29. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/design/__init__.py +0 -0
  30. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/design/templates/design/experiment_builder.html +0 -0
  31. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/design/templates/design/experiment_run.html +0 -0
  32. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/main/__init__.py +0 -0
  33. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/main/main.py +0 -0
  34. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/main/templates/main/help.html +0 -0
  35. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/routes/main/templates/main/home.html +0 -0
  36. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/static/favicon.ico +0 -0
  37. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/static/gui_annotation/Slide1.png +0 -0
  38. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/static/gui_annotation/Slide2.PNG +0 -0
  39. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/static/js/overlay.js +0 -0
  40. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/static/js/socket_handler.js +0 -0
  41. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/static/js/sortable_card.js +0 -0
  42. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/static/js/sortable_design.js +0 -0
  43. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/static/logo.webp +0 -0
  44. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/static/style.css +0 -0
  45. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/templates/base.html +0 -0
  46. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/utils/__init__.py +0 -0
  47. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/utils/client_proxy.py +0 -0
  48. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/utils/db_models.py +0 -0
  49. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/utils/form.py +0 -0
  50. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/utils/global_config.py +0 -0
  51. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos/utils/llm_agent.py +0 -0
  52. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos.egg-info/SOURCES.txt +0 -0
  53. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos.egg-info/dependency_links.txt +0 -0
  54. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos.egg-info/requires.txt +0 -0
  55. {ivoryos-0.1.23 → ivoryos-0.1.25}/ivoryos.egg-info/top_level.txt +0 -0
  56. {ivoryos-0.1.23 → ivoryos-0.1.25}/setup.cfg +0 -0
  57. {ivoryos-0.1.23 → ivoryos-0.1.25}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ivoryos
3
- Version: 0.1.23
3
+ Version: 0.1.25
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
@@ -14,7 +14,7 @@ License-File: LICENSE
14
14
  [![PyPI version](https://img.shields.io/pypi/v/ivoryos)](https://pypi.org/project/ivoryos/)
15
15
  ![License](https://img.shields.io/pypi/l/ivoryos)
16
16
  [![YouTube](https://img.shields.io/badge/YouTube-video-red?logo=youtube)](https://youtu.be/dFfJv9I2-1g)
17
- [![Research Square](https://img.shields.io/badge/Preprint-blue)](https://www.researchsquare.com/article/rs-5307798/v1)
17
+ [![Published](https://img.shields.io/badge/Nature_Communications-paper-blue)](https://www.nature.com/articles/s41467-025-60514-w)
18
18
 
19
19
 
20
20
  ![](https://gitlab.com/heingroup/ivoryos/raw/main/docs/source/_static/ivoryos.png)
@@ -163,11 +163,10 @@ When you run the application for the first time, it will automatically create th
163
163
  ## Roadmap
164
164
 
165
165
  - [x] Allow plugin pages ✅
166
- - [x] pause, resume, abort current and pending workflows ✅
166
+ - [x] pause, resume, abort current and pending workflows ✅
167
+ - [x] dropdown input ✅
168
+ - [x] show line number option ✅
167
169
  - [ ] snapshot version control
168
- - [ ] dropdown input
169
- - [ ] show line number option
170
-
171
170
 
172
171
  ## Authors and Acknowledgement
173
172
  Ivory Zhang, Lucy Hao
@@ -2,7 +2,7 @@
2
2
  [![PyPI version](https://img.shields.io/pypi/v/ivoryos)](https://pypi.org/project/ivoryos/)
3
3
  ![License](https://img.shields.io/pypi/l/ivoryos)
4
4
  [![YouTube](https://img.shields.io/badge/YouTube-video-red?logo=youtube)](https://youtu.be/dFfJv9I2-1g)
5
- [![Research Square](https://img.shields.io/badge/Preprint-blue)](https://www.researchsquare.com/article/rs-5307798/v1)
5
+ [![Published](https://img.shields.io/badge/Nature_Communications-paper-blue)](https://www.nature.com/articles/s41467-025-60514-w)
6
6
 
7
7
 
8
8
  ![](https://gitlab.com/heingroup/ivoryos/raw/main/docs/source/_static/ivoryos.png)
@@ -151,11 +151,10 @@ When you run the application for the first time, it will automatically create th
151
151
  ## Roadmap
152
152
 
153
153
  - [x] Allow plugin pages ✅
154
- - [x] pause, resume, abort current and pending workflows ✅
154
+ - [x] pause, resume, abort current and pending workflows ✅
155
+ - [x] dropdown input ✅
156
+ - [x] show line number option ✅
155
157
  - [ ] snapshot version control
156
- - [ ] dropdown input
157
- - [ ] show line number option
158
-
159
158
 
160
159
  ## Authors and Acknowledgement
161
160
  Ivory Zhang, Lucy Hao
@@ -17,11 +17,13 @@ from ivoryos.utils.global_config import GlobalConfig
17
17
  from ivoryos.utils.script_runner import ScriptRunner
18
18
  from ivoryos.version import __version__ as ivoryos_version
19
19
  from importlib.metadata import entry_points
20
+
20
21
  global_config = GlobalConfig()
21
22
  from sqlalchemy import event
22
23
  from sqlalchemy.engine import Engine
23
24
  import sqlite3
24
25
 
26
+
25
27
  @event.listens_for(Engine, "connect")
26
28
  def enforce_sqlite_foreign_keys(dbapi_connection, connection_record):
27
29
  if isinstance(dbapi_connection, sqlite3.Connection):
@@ -29,6 +31,7 @@ def enforce_sqlite_foreign_keys(dbapi_connection, connection_record):
29
31
  cursor.execute("PRAGMA foreign_keys=ON")
30
32
  cursor.close()
31
33
 
34
+
32
35
  url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
33
36
  app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
34
37
  app.register_blueprint(main, url_prefix=url_prefix)
@@ -81,8 +84,9 @@ def run(module=None, host="0.0.0.0", port=None, debug=None, llm_server=None, mod
81
84
  config: Config = None,
82
85
  logger: Union[str, list] = None,
83
86
  logger_output_name: str = None,
84
- enable_design=True,
85
- blueprint_plugins=None,
87
+ enable_design: bool = True,
88
+ blueprint_plugins: Union[list[Blueprint], Blueprint] = [],
89
+ exclude_names: list[str] = [],
86
90
  ):
87
91
  """
88
92
  Start ivoryOS app server.
@@ -97,11 +101,13 @@ def run(module=None, host="0.0.0.0", port=None, debug=None, llm_server=None, mod
97
101
  :param logger: logger name of list of logger names, defaults to None
98
102
  :param logger_output_name: log file save name of logger, defaults to None, and will use "default.log"
99
103
  :param enable_design: enable design canvas, database and workflow execution
104
+ :param blueprint_plugins: custom Blueprint pages
105
+ :param exclude_names: module names to exclude from parsing
100
106
  """
101
107
  app = create_app(config_class=config or get_config()) # Create app instance using factory function
102
108
 
103
- plugins = load_installed_plugins(app, socketio)
104
-
109
+ # plugins = load_installed_plugins(app, socketio)
110
+ plugins = []
105
111
  if blueprint_plugins:
106
112
  config_plugins = load_plugins(blueprint_plugins, app, socketio)
107
113
  plugins.extend(config_plugins)
@@ -126,7 +132,10 @@ def run(module=None, host="0.0.0.0", port=None, debug=None, llm_server=None, mod
126
132
  app.config["OFF_LINE"] = False
127
133
  global_config.deck = sys.modules[module]
128
134
  global_config.deck_snapshot = utils.create_deck_snapshot(global_config.deck,
129
- output_path=app.config["DUMMY_DECK"], save=True)
135
+ output_path=app.config["DUMMY_DECK"],
136
+ save=True,
137
+ exclude_names=exclude_names
138
+ )
130
139
  else:
131
140
  app.config["OFF_LINE"] = True
132
141
  if model:
@@ -165,7 +174,8 @@ def load_installed_plugins(app, socketio):
165
174
 
166
175
  return plugin_names
167
176
 
168
- def load_plugins(blueprints:list[Blueprint], app, socketio):
177
+
178
+ def load_plugins(blueprints: Union[list[Blueprint], Blueprint], app, socketio):
169
179
  """
170
180
  Dynamically load installed plugins and attach Flask-SocketIO.
171
181
  """
@@ -627,3 +627,8 @@ def duplicate_action(id: int):
627
627
  script.duplicate_action(id)
628
628
  utils.post_script_file(script)
629
629
  return redirect(back)
630
+
631
+
632
+ @design.route("/backend/status", methods=["GET"])
633
+ def runner_status():
634
+ return jsonify(runner.get_status())
@@ -307,4 +307,14 @@ class ScriptRunner:
307
307
  while time.time() < end_time:
308
308
  if self.stop_current_event.is_set():
309
309
  return # Exit early if stop is requested
310
- time.sleep(min(interval, end_time - time.time()))
310
+ time.sleep(min(interval, end_time - time.time()))
311
+
312
+ def get_status(self):
313
+ """Returns current status of the script runner."""
314
+ with self.lock:
315
+ return {
316
+ "is_running": self.is_running,
317
+ "paused": self.paused,
318
+ "stop_pending": self.stop_pending_event.is_set(),
319
+ "stop_current": self.stop_current_event.is_set(),
320
+ }
@@ -8,6 +8,7 @@ import subprocess
8
8
  import sys
9
9
  from collections import Counter
10
10
 
11
+ import flask
11
12
  from flask import session
12
13
  from flask_socketio import SocketIO
13
14
 
@@ -239,7 +240,7 @@ def start_logger(socketio: SocketIO, logger_name: str, log_filename: str = None)
239
240
  return logger
240
241
 
241
242
 
242
- def ax_wrapper(data: dict, arg_types:list):
243
+ def ax_wrapper(data: dict, arg_types: list):
243
244
  """
244
245
  Ax platform wrapper function for creating optimization campaign parameters and objective from the web form input
245
246
  :param data: e.g.,
@@ -363,17 +364,62 @@ def web_config_entry_wrapper(data: dict, config_type: list):
363
364
  return filtered_rows
364
365
 
365
366
 
366
- def create_deck_snapshot(deck, save: bool = False, output_path: str = ''):
367
+ def create_deck_snapshot(deck, save: bool = False, output_path: str = '', exclude_names: list[str] = []):
367
368
  """
368
369
  Create a deck snapshot of the given script
369
370
  :param deck: python module name to create the deck snapshot from e.g. __main__
370
371
  :param save: save the deck snapshot into pickle file
371
372
  :param output_path: path to save the pickle file
372
- """
373
- deck_snapshot = {f"deck.{name}": _inspect_class(val) for name, val in vars(deck).items()
374
- if not type(val).__module__ == 'builtins'
375
- and not name[0].isupper()
376
- and not name.startswith("_")}
373
+ :param exclude_names: module names to exclude from deck snapshot
374
+ """
375
+ exclude_classes = (flask.Blueprint, logging.Logger)
376
+
377
+ deck_snapshot = {}
378
+ included = {}
379
+ excluded = {}
380
+ failed = {}
381
+
382
+ for name, val in vars(deck).items():
383
+ qualified_name = f"deck.{name}"
384
+
385
+ # Exclusion checks
386
+ if (
387
+ type(val).__module__ == 'builtins'
388
+ or name[0].isupper()
389
+ or name.startswith("_")
390
+ or isinstance(val, exclude_classes)
391
+ or name in exclude_names
392
+ ):
393
+ excluded[qualified_name] = type(val).__name__
394
+ continue
395
+
396
+ try:
397
+ deck_snapshot[qualified_name] = _inspect_class(val)
398
+ included[qualified_name] = type(val).__name__
399
+ except Exception as e:
400
+ failed[qualified_name] = str(e)
401
+
402
+ # Final result
403
+ deck_summary = {
404
+ "included": included,
405
+ # "excluded": excluded,
406
+ "failed": failed
407
+ }
408
+
409
+ def print_deck_snapshot(deck_summary):
410
+ def print_section(title, items):
411
+ print(f"\n=== {title} ({len(items)}) ===")
412
+ if not items:
413
+ return
414
+ for name, class_type in items.items():
415
+ print(f" {name}: {class_type}")
416
+
417
+ print_section("✅ INCLUDED", deck_summary["included"])
418
+ print_section("❌ FAILED", deck_summary["failed"])
419
+ print("\n")
420
+
421
+ print_deck_snapshot(deck_summary)
422
+
377
423
  if deck_snapshot and save:
378
424
  # pseudo_deck = parse_dict
379
425
  parse_dict = deck_snapshot.copy()
@@ -418,7 +464,6 @@ def get_method_from_workflow(function_string, func_name="workflow"):
418
464
  # Get the function name dynamically
419
465
  return namespace[func_name]
420
466
 
421
-
422
467
  # def load_workflows(script):
423
468
  #
424
469
  # class RegisteredWorkflows:
@@ -0,0 +1 @@
1
+ __version__ = "0.1.25"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ivoryos
3
- Version: 0.1.23
3
+ Version: 0.1.25
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
@@ -14,7 +14,7 @@ License-File: LICENSE
14
14
  [![PyPI version](https://img.shields.io/pypi/v/ivoryos)](https://pypi.org/project/ivoryos/)
15
15
  ![License](https://img.shields.io/pypi/l/ivoryos)
16
16
  [![YouTube](https://img.shields.io/badge/YouTube-video-red?logo=youtube)](https://youtu.be/dFfJv9I2-1g)
17
- [![Research Square](https://img.shields.io/badge/Preprint-blue)](https://www.researchsquare.com/article/rs-5307798/v1)
17
+ [![Published](https://img.shields.io/badge/Nature_Communications-paper-blue)](https://www.nature.com/articles/s41467-025-60514-w)
18
18
 
19
19
 
20
20
  ![](https://gitlab.com/heingroup/ivoryos/raw/main/docs/source/_static/ivoryos.png)
@@ -163,11 +163,10 @@ When you run the application for the first time, it will automatically create th
163
163
  ## Roadmap
164
164
 
165
165
  - [x] Allow plugin pages ✅
166
- - [x] pause, resume, abort current and pending workflows ✅
166
+ - [x] pause, resume, abort current and pending workflows ✅
167
+ - [x] dropdown input ✅
168
+ - [x] show line number option ✅
167
169
  - [ ] snapshot version control
168
- - [ ] dropdown input
169
- - [ ] show line number option
170
-
171
170
 
172
171
  ## Authors and Acknowledgement
173
172
  Ivory Zhang, Lucy Hao
@@ -1 +0,0 @@
1
- __version__ = "0.1.23"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes