ivoryos 0.1.6__py3-none-any.whl → 0.1.7__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.
ivoryos/__init__.py CHANGED
@@ -2,7 +2,7 @@ import os
2
2
  import sys
3
3
  from typing import Union
4
4
 
5
- from flask import Flask
5
+ from flask import Flask, redirect, url_for
6
6
 
7
7
  from ivoryos.config import Config, get_config
8
8
  from ivoryos.routes.auth.auth import auth, login_manager
@@ -19,7 +19,8 @@ global_config = GlobalConfig()
19
19
 
20
20
 
21
21
  def create_app(config_class=None):
22
- app = Flask(__name__)
22
+ url_prefix = os.getenv('URL_PREFIX', None)
23
+ app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
23
24
  app.config.from_object(config_class or 'config.get_config()')
24
25
 
25
26
  # Initialize extensions
@@ -45,11 +46,15 @@ def create_app(config_class=None):
45
46
  g.logger = logger
46
47
  g.socketio = socketio
47
48
 
48
- app.register_blueprint(main)
49
- app.register_blueprint(auth)
50
- app.register_blueprint(design)
51
- app.register_blueprint(database)
52
- app.register_blueprint(control)
49
+ app.register_blueprint(main, url_prefix=url_prefix)
50
+ app.register_blueprint(auth, url_prefix=url_prefix)
51
+ app.register_blueprint(design, url_prefix=url_prefix)
52
+ app.register_blueprint(database, url_prefix=url_prefix)
53
+ app.register_blueprint(control, url_prefix=url_prefix)
54
+
55
+ @app.route('/')
56
+ def redirect_to_prefix():
57
+ return redirect(url_for('main.index')) # Assuming 'index' is a route in your blueprint
53
58
 
54
59
  return app
55
60
 
@@ -13,10 +13,10 @@ from werkzeug.utils import secure_filename
13
13
  from ivoryos.utils import utils
14
14
  from ivoryos.utils.global_config import GlobalConfig
15
15
  from ivoryos.utils.form import create_builtin_form, create_action_button, format_name, create_form_from_pseudo
16
+ from ivoryos.utils.llm_agent import LlmAgent
16
17
  from ivoryos.utils.db_models import Script
17
18
  from ivoryos.utils.script_runner import ScriptRunner
18
19
 
19
-
20
20
  socketio = SocketIO()
21
21
  design = Blueprint('design', __name__, template_folder='templates/design')
22
22
 
@@ -165,7 +165,6 @@ def generate_code():
165
165
  model = current_app.config["LLM_MODEL"]
166
166
  server = current_app.config["LLM_SERVER"]
167
167
  module = current_app.config["MODULE"]
168
- from ivoryos.utils.llm_agent import LlmAgent
169
168
  agent = LlmAgent(host=server, model=model, output_path=os.path.dirname(os.path.abspath(module)))
170
169
  except Exception as e:
171
170
  flash(e.__str__())
@@ -6,7 +6,16 @@ document.addEventListener("DOMContentLoaded", function() {
6
6
  socket.on('progress', function(data) {
7
7
  var progress = data.progress;
8
8
  console.log(progress);
9
- $('#progress-bar-inner').css('width', progress + '%')
9
+ // Update the progress bar's width and appearance
10
+ var progressBar = document.getElementById('progress-bar-inner');
11
+ progressBar.style.width = progress + '%';
12
+ progressBar.setAttribute('aria-valuenow', progress);
13
+
14
+ if (progress === 100) {
15
+ // Remove animation and set green color when 100% is reached
16
+ progressBar.classList.remove('progress-bar-animated');
17
+ progressBar.classList.add('bg-success'); // Bootstrap class for green color
18
+ }
10
19
  });
11
20
  socket.on('log', function(data) {
12
21
  var logMessage = data.message;
Binary file
@@ -25,7 +25,7 @@
25
25
  <div class= "container">
26
26
 
27
27
  <a class="navbar-brand" href="{{ url_for('main.index') }}">
28
- <img src="{{url_for('static', filename='logo.png')}}" alt="Logo" height="60" class="d-inline-block align-text-bottom">
28
+ <img src="{{url_for('static', filename='logo.webp')}}" alt="Logo" height="60" class="d-inline-block align-text-bottom">
29
29
  </a>
30
30
  <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
31
31
  <span class="navbar-toggler-icon"></span>
@@ -33,6 +33,9 @@
33
33
 
34
34
  <div class="collapse navbar-collapse" id="navbarSupportedContent">
35
35
  <ul class="navbar-nav mr-auto">
36
+ <li class="nav-item">
37
+ <a class="nav-link" href="{{ url_for('main.index') }}" aria-current="page">Home</a>
38
+ </li>
36
39
  <li class="nav-item">
37
40
  <a class="nav-link" href="{{ url_for('database.load_from_database') }}" aria-current="page">Library</a>
38
41
  </li>
ivoryos/utils/form.py CHANGED
@@ -255,7 +255,7 @@ def create_form_from_module(sdl_module, autofill: bool, script=None, design=True
255
255
  attr = getattr(sdl_module, attr_name)
256
256
  if inspect.ismethod(attr) and not attr_name.startswith('_'):
257
257
  form_class = create_add_form(attr, attr_name, autofill, script, design)
258
- method_forms[attr_name] = form_class()
258
+ method_forms[format_name(attr_name)] = form_class()
259
259
  return method_forms
260
260
 
261
261
 
@@ -3,7 +3,7 @@ import json
3
3
  import os
4
4
  import re
5
5
 
6
- from openai import OpenAI, BaseModel
6
+ from openai import OpenAI
7
7
 
8
8
 
9
9
  # from dotenv import load_dotenv
@@ -53,6 +53,7 @@ class ScriptRunner:
53
53
  def _run_with_stop_check(self, script: Script, repeat_count, run_name, logger, socketio, config, bo_args,
54
54
  output_path):
55
55
  time.sleep(1)
56
+ self._emit_progress(socketio, 1)
56
57
  try:
57
58
  # Run "prep" section once
58
59
  script_dict = script.script_dict
@@ -75,6 +76,7 @@ class ScriptRunner:
75
76
  finally:
76
77
  with self.lock:
77
78
  self.is_running = False # Reset the running flag when done
79
+ self._emit_progress(socketio, 100)
78
80
 
79
81
  def _run_actions(self, actions, section_name="", run_name=None, logger=None):
80
82
  logger.info(f'Executing {section_name} steps') if actions else logger.info(f'No {section_name} steps')
@@ -104,7 +106,7 @@ class ScriptRunner:
104
106
  break
105
107
  logger.info(f'Executing {i + 1} of {len(config)} with kwargs = {kwargs}')
106
108
  progress = (i + 1) * 100 / len(config)
107
- socketio.emit('progress', {'progress': progress})
109
+ self._emit_progress(socketio, progress)
108
110
  fname = f"{run_name}_script"
109
111
  function = self.globals_dict[fname]
110
112
  output = function(**kwargs)
@@ -121,8 +123,8 @@ class ScriptRunner:
121
123
  logger.info(f'Stopping execution during {run_name}: {i + 1}/{int(repeat_count)}')
122
124
  break
123
125
  logger.info(f'Executing {run_name} experiment: {i + 1}/{int(repeat_count)}')
124
- progress = (i + 1) * 100 / int(repeat_count)
125
- socketio.emit('progress', {'progress': progress})
126
+ progress = (i + 1) * 100 / int(repeat_count) - 0.1
127
+ self._emit_progress(socketio, progress)
126
128
  if bo_args:
127
129
  try:
128
130
  parameters, trial_index = ax_client.get_next_trial()
@@ -156,3 +158,7 @@ class ScriptRunner:
156
158
  writer.writeheader()
157
159
  writer.writerows(output_list)
158
160
  logger.info(f'Results saved to {file_path}')
161
+
162
+ @staticmethod
163
+ def _emit_progress(socketio, progress):
164
+ socketio.emit('progress', {'progress': progress})
ivoryos/utils/utils.py CHANGED
@@ -1,3 +1,4 @@
1
+ import ast
1
2
  import importlib
2
3
  import inspect
3
4
  import logging
@@ -124,23 +125,22 @@ def _get_type_from_parameters(arg, parameters):
124
125
  """get argument types from inspection"""
125
126
  arg_type = ''
126
127
  if type(parameters) is inspect.Signature:
127
- p = parameters.parameters
128
+ annotation = parameters.parameters[arg].annotation
129
+ elif type(parameters) is dict:
130
+ annotation = parameters[arg]
131
+ if annotation is not inspect._empty:
128
132
  # print(p[arg].annotation)
129
- if p[arg].annotation is not inspect._empty:
130
- # print(p[arg].annotation)
131
- if p[arg].annotation.__module__ == 'typing':
133
+ if annotation.__module__ == 'typing':
134
+ if hasattr(annotation, '_name') and annotation._name in ["Optional", "Union"]:
132
135
  # print(p[arg].annotation.__args__)
133
- arg_type = [i.__name__ for i in p[arg].annotation.__args__]
134
- else:
135
- arg_type = p[arg].annotation.__name__
136
- # print(arg_type)
137
- elif type(parameters) is dict:
138
- if parameters[arg]:
139
-
140
- if parameters[arg].__module__ == 'typing':
141
- arg_type = [i.__name__ for i in parameters[arg].__args__]
136
+ arg_type = [i.__name__ for i in annotation.__args__]
137
+ elif hasattr(annotation, '__origin__'):
138
+ arg_type = annotation.__origin__.__name__
142
139
  else:
143
- arg_type = parameters[arg].__name__
140
+ # TODO
141
+ pass
142
+ else:
143
+ arg_type = annotation.__name__
144
144
  return arg_type
145
145
 
146
146
 
@@ -168,17 +168,12 @@ def _convert_by_str(args, arg_types):
168
168
  if type(arg_types) is not list:
169
169
  arg_types = [arg_types]
170
170
  for arg_type in arg_types:
171
- if arg_type == "any":
171
+ if not arg_type == "any":
172
172
  try:
173
- args = eval(args)
173
+ args = eval(f'{arg_type}("{args}")') if type(args) is str else eval(f'{arg_type}({args})')
174
+ return args
174
175
  except Exception:
175
- pass
176
- return args
177
- try:
178
- args = eval(f'{arg_type}("{args}")')
179
- return args
180
- except Exception:
181
- raise TypeError(f"Input type error: cannot convert '{args}' to {arg_type}.")
176
+ raise TypeError(f"Input type error: cannot convert '{args}' to {arg_type}.")
182
177
 
183
178
 
184
179
  def _convert_by_class(args, arg_types):
@@ -214,16 +209,20 @@ def convert_config_type(args, arg_types, is_class: bool = False):
214
209
  raise ValueError("config file format not supported.")
215
210
  if args[arg] == '' or args[arg] == "None":
216
211
  args[arg] = None
217
- elif args[arg] == "True" or args[arg] == "False":
218
- args[arg] = bool_dict[args[arg]]
212
+ # elif args[arg] == "True" or args[arg] == "False":
213
+ # args[arg] = bool_dict[args[arg]]
219
214
  else:
220
215
  arg_type = arg_types[arg]
221
-
222
- if is_class:
223
- # if arg_type.__module__ == 'builtins':
224
- args[arg] = _convert_by_class(args[arg], arg_type)
225
- else:
226
- args[arg] = _convert_by_str(args[arg], arg_type)
216
+ try:
217
+ args[arg] = ast.literal_eval(args[arg])
218
+ except ValueError:
219
+ pass
220
+ if type(args[arg]) is not arg_type and not type(args[arg]).__name__ == arg_type:
221
+ if is_class:
222
+ # if arg_type.__module__ == 'builtins':
223
+ args[arg] = _convert_by_class(args[arg], arg_type)
224
+ else:
225
+ args[arg] = _convert_by_str(args[arg], arg_type)
227
226
  return args
228
227
 
229
228
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ivoryos
3
- Version: 0.1.6
3
+ Version: 0.1.7
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,4 +1,4 @@
1
- ivoryos/__init__.py,sha256=prqANp0lD5gqHOsvVEhnuAgaCvKg2BcC3zWiXZbJS_U,3535
1
+ ivoryos/__init__.py,sha256=HuYhPOMFGkQ_f9s1dZXaknAylKXds0jYK0nmdf1I6Z8,3932
2
2
  ivoryos/config.py,sha256=K03jdGmbUfJ9o4kK6NOtDGJtydGHFq8-oU8nvCyq5zQ,1358
3
3
  ivoryos/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  ivoryos/routes/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -14,7 +14,7 @@ ivoryos/routes/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
14
14
  ivoryos/routes/database/database.py,sha256=e1OpmQayM0KYUTPiYQzXHo-zLVd5yHtS0EYNce7vcmQ,4357
15
15
  ivoryos/routes/database/templates/database/experiment_database.html,sha256=x9zf4u4KbG6BEICnH_TOVNNUkp5oAmGBB12OUX0PPl4,3506
16
16
  ivoryos/routes/design/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- ivoryos/routes/design/design.py,sha256=g1V4HYLldD7O6K5brtdxV8uoyOVGTpM3rC1lOmw91AA,16913
17
+ ivoryos/routes/design/design.py,sha256=FUuO-1iSeKhrLQ5Qz4zQwZiFRC5rax7RwhJBH9Wt42U,16895
18
18
  ivoryos/routes/design/templates/design/experiment_builder.html,sha256=IAU9XvtbcEWDlnCqf2Z81gcBB7bNDFOfod3xLJfRbQc,27371
19
19
  ivoryos/routes/design/templates/design/experiment_run.html,sha256=xoEHH8CC83KCWTPavwP9JWUI8SE5HX9bkEfJN6vMg5s,22845
20
20
  ivoryos/routes/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -23,24 +23,25 @@ ivoryos/routes/main/templates/main/help.html,sha256=TY6uD-v8MXpiZlGucchko1Bas5jH
23
23
  ivoryos/routes/main/templates/main/home.html,sha256=fjeSSXkuVDr2y-CQmskNHf1yYFFdrPPI4wn6_XPb6AY,3252
24
24
  ivoryos/static/favicon.ico,sha256=RhlrPtfITOkzC9BjP1UB1V5L9Oyp6NwNtWeMcGOnpyc,15406
25
25
  ivoryos/static/logo.png,sha256=7lNyToDllflGPUK2sj7IBR8FkHLC-6gi-OVSL9o4jrs,63464
26
+ ivoryos/static/logo.webp,sha256=lXgfQR-4mHTH83k7VV9iB54-oC2ipe6uZvbwdOnLETc,14974
26
27
  ivoryos/static/style.css,sha256=rY6n2mbP_xNavtVin_yUqtcvNm6uqAF82t7ONE2Sx9E,3918
27
28
  ivoryos/static/gui_annotation/Slide1.png,sha256=Lm4gdOkUF5HIUFaB94tl6koQVkzpitKj43GXV_XYMMc,121727
28
29
  ivoryos/static/gui_annotation/Slide2.PNG,sha256=z3wQ9oVgg4JTWVLQGKK_KhtepRHUYP1e05XUWGT2A0I,118761
29
30
  ivoryos/static/js/overlay.js,sha256=44l9THVKYZfa7HX6siyqY7EdFWKBk5pyyKgN0_7ZnrM,495
30
- ivoryos/static/js/socket_handler.js,sha256=HduGphUyyZq8GE1-5ZmDgHGTzcWDRa6oXBNrWWMnxwM,989
31
+ ivoryos/static/js/socket_handler.js,sha256=2936CldW6Po_saWh1aL_EV-VydJVIvikrNfTaSfU1sE,1449
31
32
  ivoryos/static/js/sortable_card.js,sha256=mDVd2YjhusLokUw3xL6YOZLXIzty9yKDsC1U5yR8aC8,831
32
33
  ivoryos/static/js/sortable_design.js,sha256=BxNXzqET_yY0xpS1Fc0iwPCnkkDwYMiuVqkgOPMb6JY,1156
33
- ivoryos/templates/base.html,sha256=cu6MZMlfOR0IhuNrMin_pWYtm1_TpJLHI6KH5NomopI,7763
34
+ ivoryos/templates/base.html,sha256=KcKMjITaaC23yzIRN535uMhzv5x96nJl245Y2GaqdsM,7943
34
35
  ivoryos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
36
  ivoryos/utils/db_models.py,sha256=umEATdxDP-sR_AMaLrOW2PBUcmBf1w38DLeFkBvVjJE,19280
36
- ivoryos/utils/form.py,sha256=W8fSGybeWSCfPqySEfH1mKJbdoYmRb3vwpy15w2rj_Q,12226
37
+ ivoryos/utils/form.py,sha256=mqNDuaxniaGnKcJ26N9dcXpHQ6TabXTqPVbcrcDvM4s,12239
37
38
  ivoryos/utils/global_config.py,sha256=JCQvmZB0pNC-EjveRu48Tp4uvcNwn9DP3Ema6Xd9fJY,1656
38
- ivoryos/utils/llm_agent.py,sha256=pxiaiIVHzbGA_Tq4yOZY3iyIDikx6-_chIvPEjlywLg,6607
39
- ivoryos/utils/script_runner.py,sha256=jlJMCFLmcS6GOlOfEmLXAzG47sU18nNtRPtojjdN018,6919
39
+ ivoryos/utils/llm_agent.py,sha256=z0DIpZzc-z09p-diUZIOE5L9zfFW8RwseFjbfUvEqoQ,6596
40
+ ivoryos/utils/script_runner.py,sha256=gtqiHy4-40j5FMERXrmGb4jb9RAPzjCR345PMPduDno,7120
40
41
  ivoryos/utils/task_manager.py,sha256=xfQ1s9ywWDrCYYpdgliVvoWED0s2xARmo3LXvAy6fgY,2517
41
- ivoryos/utils/utils.py,sha256=8GMuMwKUKKMjz8hvilavNlV4RANcQWsJy8hZpbXanRg,15042
42
- ivoryos-0.1.6.dist-info/LICENSE,sha256=psyqat4GJkzi42551i0kH-bXLbEzrQEnjPDwy2TVhv8,1105
43
- ivoryos-0.1.6.dist-info/METADATA,sha256=QTek7bK8bAPqXCo0RIY6w_YTUeisTWFcg2ythkjqYc4,6101
44
- ivoryos-0.1.6.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
45
- ivoryos-0.1.6.dist-info/top_level.txt,sha256=FRIWWdiEvRKqw-XfF_UK3XV0CrnNb6EmVbEgjaVazRM,8
46
- ivoryos-0.1.6.dist-info/RECORD,,
42
+ ivoryos/utils/utils.py,sha256=BMmvyBNo8PYs-MiBiiHjYPvSwrHORofbNwhPYpaVnfI,15249
43
+ ivoryos-0.1.7.dist-info/LICENSE,sha256=psyqat4GJkzi42551i0kH-bXLbEzrQEnjPDwy2TVhv8,1105
44
+ ivoryos-0.1.7.dist-info/METADATA,sha256=SgV11aX0JSQjJRsn_1vDlt15DrdAEWKM7DSs5dU6cjE,6101
45
+ ivoryos-0.1.7.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
46
+ ivoryos-0.1.7.dist-info/top_level.txt,sha256=FRIWWdiEvRKqw-XfF_UK3XV0CrnNb6EmVbEgjaVazRM,8
47
+ ivoryos-0.1.7.dist-info/RECORD,,