ivoryos 0.1.13__tar.gz → 0.1.15__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.
- {ivoryos-0.1.13/ivoryos.egg-info → ivoryos-0.1.15}/PKG-INFO +1 -1
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/__init__.py +24 -7
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/control/templates/control/controllers.html +3 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/design/design.py +17 -22
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/design/templates/design/experiment_builder.html +3 -1
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/main/main.py +1 -1
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/main/templates/main/home.html +19 -17
- ivoryos-0.1.15/ivoryos/routes/monitor/monitor.py +21 -0
- ivoryos-0.1.15/ivoryos/routes/monitor/templates/monitor/monitor.html +24 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/templates/base.html +17 -10
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/utils/db_models.py +22 -39
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/utils/form.py +81 -41
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/utils/utils.py +2 -32
- {ivoryos-0.1.13 → ivoryos-0.1.15/ivoryos.egg-info}/PKG-INFO +1 -1
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos.egg-info/SOURCES.txt +2 -1
- {ivoryos-0.1.13 → ivoryos-0.1.15}/setup.py +1 -1
- ivoryos-0.1.13/ivoryos/version.py +0 -1
- {ivoryos-0.1.13 → ivoryos-0.1.15}/LICENSE +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/MANIFEST.in +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/README.md +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/config.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/__init__.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/auth/__init__.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/auth/auth.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/auth/templates/auth/login.html +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/auth/templates/auth/signup.html +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/control/__init__.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/control/control.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/control/templates/control/controllers_home.html +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/control/templates/control/controllers_new.html +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/database/__init__.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/database/database.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/database/templates/database/experiment_database.html +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/design/__init__.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/design/templates/design/experiment_run.html +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/main/__init__.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/main/templates/main/help.html +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/static/favicon.ico +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/static/gui_annotation/Slide1.png +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/static/gui_annotation/Slide2.PNG +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/static/js/overlay.js +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/static/js/socket_handler.js +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/static/js/sortable_card.js +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/static/js/sortable_design.js +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/static/logo.webp +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/static/style.css +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/utils/__init__.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/utils/global_config.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/utils/llm_agent.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/utils/script_runner.py +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos.egg-info/dependency_links.txt +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos.egg-info/requires.txt +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos.egg-info/top_level.txt +0 -0
- {ivoryos-0.1.13 → ivoryos-0.1.15}/setup.cfg +0 -0
|
@@ -10,21 +10,17 @@ from ivoryos.routes.control.control import control
|
|
|
10
10
|
from ivoryos.routes.database.database import database
|
|
11
11
|
from ivoryos.routes.design.design import design, socketio
|
|
12
12
|
from ivoryos.routes.main.main import main
|
|
13
|
+
from ivoryos.routes.monitor.monitor import monitor
|
|
13
14
|
from ivoryos.utils import utils
|
|
14
15
|
from ivoryos.utils.db_models import db
|
|
15
16
|
from ivoryos.utils.global_config import GlobalConfig
|
|
16
17
|
from ivoryos.utils.script_runner import ScriptRunner
|
|
17
|
-
from
|
|
18
|
+
from version import __version__ as ivoryos_version
|
|
18
19
|
|
|
19
20
|
global_config = GlobalConfig()
|
|
20
21
|
|
|
21
22
|
url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
|
|
22
23
|
app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
|
|
23
|
-
app.register_blueprint(main, url_prefix=url_prefix)
|
|
24
|
-
app.register_blueprint(auth, url_prefix=url_prefix)
|
|
25
|
-
app.register_blueprint(design, url_prefix=url_prefix)
|
|
26
|
-
app.register_blueprint(database, url_prefix=url_prefix)
|
|
27
|
-
app.register_blueprint(control, url_prefix=url_prefix)
|
|
28
24
|
|
|
29
25
|
|
|
30
26
|
def create_app(config_class=None):
|
|
@@ -70,6 +66,7 @@ def run(module=None, host="0.0.0.0", port=None, debug=None, llm_server=None, mod
|
|
|
70
66
|
config: Config = None,
|
|
71
67
|
logger: Union[str, list] = None,
|
|
72
68
|
logger_output_name: str = None,
|
|
69
|
+
enable_design=True, stream_address=None
|
|
73
70
|
):
|
|
74
71
|
"""
|
|
75
72
|
Start ivoryOS app server.
|
|
@@ -83,9 +80,29 @@ def run(module=None, host="0.0.0.0", port=None, debug=None, llm_server=None, mod
|
|
|
83
80
|
:param config: config class, defaults to None
|
|
84
81
|
:param logger: logger name of list of logger names, defaults to None
|
|
85
82
|
:param logger_output_name: log file save name of logger, defaults to None, and will use "default.log"
|
|
86
|
-
|
|
83
|
+
:param enable_design:
|
|
84
|
+
:param stream_address:
|
|
87
85
|
"""
|
|
88
86
|
app = create_app(config_class=config or get_config()) # Create app instance using factory function
|
|
87
|
+
enable_monitor = stream_address is not None
|
|
88
|
+
|
|
89
|
+
def inject_nav_config():
|
|
90
|
+
"""Make NAV_CONFIG available globally to all templates."""
|
|
91
|
+
return dict(
|
|
92
|
+
enable_design=enable_design,
|
|
93
|
+
enable_monitor=enable_monitor,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# todo modular page
|
|
97
|
+
app.context_processor(inject_nav_config)
|
|
98
|
+
app.register_blueprint(main, url_prefix=url_prefix)
|
|
99
|
+
app.register_blueprint(auth, url_prefix=url_prefix)
|
|
100
|
+
if enable_design:
|
|
101
|
+
app.register_blueprint(design, url_prefix=url_prefix)
|
|
102
|
+
app.register_blueprint(database, url_prefix=url_prefix)
|
|
103
|
+
if enable_monitor:
|
|
104
|
+
app.register_blueprint(monitor, url_prefix=url_prefix)
|
|
105
|
+
app.register_blueprint(control, url_prefix=url_prefix)
|
|
89
106
|
|
|
90
107
|
port = port or int(os.environ.get("PORT", 8000))
|
|
91
108
|
debug = debug if debug is not None else app.config.get('DEBUG', True)
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
{% if function not in hidden_instrument %}
|
|
17
17
|
<div class="card" id="{{function}}">
|
|
18
18
|
<div class="bg-white rounded shadow-sm flex-fill">
|
|
19
|
+
<i class="bi bi-info-circle ms-2" data-bs-toggle="tooltip" data-bs-placement="top" title='{{ form.hidden_name.description or "Docstring is not available" }}' ></i>
|
|
19
20
|
<a style="float: right" aria-label="Close" href="{{ url_for('control.hide_function', instrument=instrument, function=function) }}"><i class="bi bi-eye-slash-fill"></i></a>
|
|
20
21
|
<div class="form-control" style="border: none">
|
|
21
22
|
<form role="form" method='POST' name="{{function}}" id="{{function}}">
|
|
@@ -38,7 +39,9 @@
|
|
|
38
39
|
</div>
|
|
39
40
|
<div class="input-group mb-3">
|
|
40
41
|
<button type="submit" name="{{ function }}" id="{{ function }}" class="form-control" style="background-color: #a5cece;">{{format_name(function)}} </button>
|
|
42
|
+
|
|
41
43
|
</div>
|
|
44
|
+
|
|
42
45
|
</form>
|
|
43
46
|
</div>
|
|
44
47
|
</div>
|
|
@@ -100,22 +100,25 @@ def experiment_builder(instrument=None):
|
|
|
100
100
|
|
|
101
101
|
deck_list = utils.available_pseudo_deck(current_app.config["DUMMY_DECK"])
|
|
102
102
|
|
|
103
|
-
functions =
|
|
103
|
+
functions = {}
|
|
104
104
|
if deck:
|
|
105
105
|
deck_variables = global_config.deck_snapshot.keys()
|
|
106
106
|
else:
|
|
107
107
|
deck_variables = list(pseudo_deck.keys()) if pseudo_deck else []
|
|
108
108
|
deck_variables.remove("deck_name") if len(deck_variables) > 0 else deck_variables
|
|
109
|
-
|
|
110
|
-
if
|
|
109
|
+
edit_action_info = session.get("edit_action")
|
|
110
|
+
if edit_action_info:
|
|
111
|
+
forms = create_form_from_action(edit_action_info, script=script)
|
|
112
|
+
elif instrument:
|
|
111
113
|
if instrument in ['if', 'while', 'variable', 'wait', 'repeat']:
|
|
112
|
-
forms = create_builtin_form(instrument,
|
|
114
|
+
forms = create_builtin_form(instrument, script=script)
|
|
113
115
|
else:
|
|
114
116
|
if deck:
|
|
115
|
-
|
|
117
|
+
functions = global_config.deck_snapshot.get(instrument, {})
|
|
116
118
|
elif pseudo_deck:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
functions = pseudo_deck.get(instrument, {})
|
|
120
|
+
# print(function_metadata)
|
|
121
|
+
# functions = {key: data.get('signature', {}) for key, data in function_metadata.items()}
|
|
119
122
|
forms = create_form_from_pseudo(pseudo=functions, autofill=autofill, script=script)
|
|
120
123
|
if request.method == 'POST' and "hidden_name" in request.form:
|
|
121
124
|
# all_kwargs = request.form.copy()
|
|
@@ -128,21 +131,14 @@ def experiment_builder(instrument=None):
|
|
|
128
131
|
function_name = kwargs.pop("hidden_name")
|
|
129
132
|
save_data = kwargs.pop('return', '')
|
|
130
133
|
|
|
131
|
-
|
|
132
|
-
|
|
133
134
|
primitive_arg_types = utils.get_arg_type(kwargs, functions[function_name])
|
|
134
135
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
# arg_types.update(variable_kwargs_types)
|
|
138
|
-
arg_types.update(primitive_arg_types)
|
|
139
|
-
# all_kwargs.update(variable_kwargs)
|
|
140
|
-
script.eval_list(kwargs, arg_types)
|
|
141
|
-
kwargs = script.eval_variables(kwargs)
|
|
136
|
+
script.eval_list(kwargs, primitive_arg_types)
|
|
137
|
+
kwargs = script.validate_variables(kwargs)
|
|
142
138
|
action = {"instrument": instrument, "action": function_name,
|
|
143
|
-
"args":
|
|
139
|
+
"args": kwargs,
|
|
144
140
|
"return": save_data,
|
|
145
|
-
'arg_types':
|
|
141
|
+
'arg_types': primitive_arg_types}
|
|
146
142
|
script.add_action(action=action)
|
|
147
143
|
else:
|
|
148
144
|
flash(form.errors)
|
|
@@ -167,14 +163,13 @@ def experiment_builder(instrument=None):
|
|
|
167
163
|
autofill = not autofill
|
|
168
164
|
forms = create_form_from_pseudo(functions, autofill=autofill, script=script)
|
|
169
165
|
session['autofill'] = autofill
|
|
170
|
-
|
|
171
|
-
forms = create_form_from_action(edit_action, script=script)
|
|
166
|
+
|
|
172
167
|
utils.post_script_file(script)
|
|
173
168
|
design_buttons = create_action_button(script)
|
|
174
169
|
return render_template('experiment_builder.html', off_line=off_line, instrument=instrument, history=deck_list,
|
|
175
170
|
script=script, defined_variables=deck_variables,
|
|
176
171
|
local_variables=global_config.defined_variables,
|
|
177
|
-
|
|
172
|
+
forms=forms, buttons=design_buttons, format_name=format_name,
|
|
178
173
|
use_llm=enable_llm)
|
|
179
174
|
|
|
180
175
|
|
|
@@ -505,7 +500,7 @@ def edit_action(uuid: str):
|
|
|
505
500
|
# print(kwargs)
|
|
506
501
|
if forms and forms.validate_on_submit():
|
|
507
502
|
save_as = kwargs.pop('return', '')
|
|
508
|
-
kwargs = script.
|
|
503
|
+
kwargs = script.validate_variables(kwargs)
|
|
509
504
|
# try:
|
|
510
505
|
script.update_by_uuid(uuid=uuid, args=kwargs, output=save_as)
|
|
511
506
|
# except Exception as e:
|
{ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/design/templates/design/experiment_builder.html
RENAMED
|
@@ -150,12 +150,12 @@
|
|
|
150
150
|
{{ format_name(name) }}
|
|
151
151
|
</button>
|
|
152
152
|
</h2>
|
|
153
|
+
|
|
153
154
|
<div id="{{name}}" class="accordion-collapse collapse" data-bs-parent="#accordionActions">
|
|
154
155
|
<div class="accordion-body">
|
|
155
156
|
<form role="form" method='POST' name="add" id="add">
|
|
156
157
|
<div class="form-group">
|
|
157
158
|
{{ form.hidden_tag() }}
|
|
158
|
-
{# {{ form.hidden_name() }}#}
|
|
159
159
|
{% for field in form %}
|
|
160
160
|
{% if field.type not in ['CSRFTokenField', 'HiddenField'] %}
|
|
161
161
|
<div class="input-group mb-3">
|
|
@@ -172,6 +172,8 @@
|
|
|
172
172
|
{% endfor %}
|
|
173
173
|
</div>
|
|
174
174
|
<button type="submit" class="btn btn-dark">Add </button>
|
|
175
|
+
<i class="bi bi-info-circle ms-2" data-bs-toggle="tooltip" data-bs-placement="top" title='{{ form.hidden_name.description or "Docstring is not available" }}' ></i>
|
|
176
|
+
|
|
175
177
|
</form>
|
|
176
178
|
|
|
177
179
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from flask import Blueprint, render_template, current_app
|
|
2
2
|
from flask_login import login_required
|
|
3
|
-
from
|
|
3
|
+
from version import __version__ as ivoryos_version
|
|
4
4
|
|
|
5
5
|
main = Blueprint('main', __name__, template_folder='templates/main')
|
|
6
6
|
|
|
@@ -9,32 +9,32 @@
|
|
|
9
9
|
</h1>
|
|
10
10
|
<p>Version: {{ version }}</p>
|
|
11
11
|
<div class="row">
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
{% if enable_design %}
|
|
13
|
+
<div class="col-lg-6 mb-4 d-flex align-items-stretch">
|
|
14
|
+
<div class="card rounded shadow-sm flex-fill">
|
|
15
|
+
<div class="card-body">
|
|
16
|
+
<h5 class="card-title">Browse designs</h5>
|
|
17
|
+
<p class="card-text">Browse all workflows saved in the database.</p>
|
|
18
|
+
<a href="{{ url_for('database.load_from_database') }}" class="stretched-link"></a>
|
|
19
|
+
</div>
|
|
19
20
|
</div>
|
|
20
21
|
</div>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
<div class="col-lg-6 mb-4 d-flex align-items-stretch">
|
|
23
|
+
<div class="card rounded shadow-sm flex-fill">
|
|
24
|
+
<div class="card-body">
|
|
25
|
+
<h5 class="card-title">Edit designs</h5>
|
|
26
|
+
<p class="card-text">Build your workflow from current deck functions.</p>
|
|
27
|
+
<a href="{{ url_for('design.experiment_builder') }}" class="stretched-link"></a>
|
|
28
|
+
</div>
|
|
28
29
|
</div>
|
|
29
30
|
</div>
|
|
30
|
-
|
|
31
|
+
{% endif %}
|
|
31
32
|
</div>
|
|
32
33
|
|
|
33
34
|
<br><br><br>
|
|
34
35
|
{% if not off_line %}
|
|
35
|
-
{# <h5>Only available in online mode</h5>#}
|
|
36
|
-
{# <hr>#}
|
|
37
36
|
<div class="row">
|
|
37
|
+
{% if enable_design %}
|
|
38
38
|
<div class="col-lg-6 mb-4 d-flex align-items-stretch">
|
|
39
39
|
<div class="card rounded shadow-sm flex-fill">
|
|
40
40
|
<div class="card-body">
|
|
@@ -44,6 +44,8 @@
|
|
|
44
44
|
</div>
|
|
45
45
|
</div>
|
|
46
46
|
</div>
|
|
47
|
+
{% endif %}
|
|
48
|
+
|
|
47
49
|
<div class="col-lg-6 mb-4 d-flex align-items-stretch">
|
|
48
50
|
<div class="card rounded shadow-sm flex-fill">
|
|
49
51
|
<div class="card-body">
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from flask import Blueprint, flash, render_template
|
|
2
|
+
from flask_login import login_required
|
|
3
|
+
|
|
4
|
+
from ivoryos.utils.global_config import GlobalConfig
|
|
5
|
+
|
|
6
|
+
global_config = GlobalConfig()
|
|
7
|
+
|
|
8
|
+
monitor = Blueprint('monitor', __name__, template_folder='templates/monitor')
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@monitor.route("/stream_feed")
|
|
12
|
+
@login_required
|
|
13
|
+
def stream_feed():
|
|
14
|
+
"""
|
|
15
|
+
.. :quickref: Monitor; stream feed
|
|
16
|
+
|
|
17
|
+
display feed by ip address
|
|
18
|
+
e.g. HeinSight output feed
|
|
19
|
+
.. http:get:: /my_deck
|
|
20
|
+
"""
|
|
21
|
+
return render_template('monitor.html', stream_address="http://127.0.0.1:8001/frame")
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{% extends 'base.html' %}
|
|
2
|
+
{% block title %}IvoryOS | Monitor {% endblock %}
|
|
3
|
+
|
|
4
|
+
{% block body %}
|
|
5
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.js"></script>
|
|
6
|
+
|
|
7
|
+
<h1>Live Stream</h1>
|
|
8
|
+
<img src="{{ stream_address }}" width="800" height="600">
|
|
9
|
+
|
|
10
|
+
{% if no_deck_warning and not dismiss %}
|
|
11
|
+
{# auto pop import when there is no deck#}
|
|
12
|
+
<script type="text/javascript">
|
|
13
|
+
function OpenBootstrapPopup() {
|
|
14
|
+
$("#importModal").modal('show');
|
|
15
|
+
}
|
|
16
|
+
window.onload = function () {
|
|
17
|
+
OpenBootstrapPopup();
|
|
18
|
+
};
|
|
19
|
+
</script>
|
|
20
|
+
{% endif %}
|
|
21
|
+
|
|
22
|
+
<script src="{{ url_for('static', filename='js/socket_handler.js') }}"></script>
|
|
23
|
+
|
|
24
|
+
{% endblock %}
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
<body>
|
|
24
24
|
<nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top">
|
|
25
25
|
<div class= "container">
|
|
26
|
-
|
|
26
|
+
{# {{ module_config }}#}
|
|
27
27
|
<a class="navbar-brand" href="{{ url_for('main.index') }}">
|
|
28
28
|
<img src="{{url_for('static', filename='logo.webp')}}" alt="Logo" height="60" class="d-inline-block align-text-bottom">
|
|
29
29
|
</a>
|
|
@@ -36,15 +36,22 @@
|
|
|
36
36
|
<li class="nav-item">
|
|
37
37
|
<a class="nav-link" href="{{ url_for('main.index') }}" aria-current="page">Home</a>
|
|
38
38
|
</li>
|
|
39
|
-
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<
|
|
47
|
-
|
|
39
|
+
{% if enable_design %}
|
|
40
|
+
<li class="nav-item">
|
|
41
|
+
<a class="nav-link" href="{{ url_for('database.load_from_database') }}" aria-current="page">Library</a>
|
|
42
|
+
</li>
|
|
43
|
+
<li class="nav-item">
|
|
44
|
+
<a class="nav-link" href="{{ url_for('design.experiment_builder') }}">Design</a>
|
|
45
|
+
</li>
|
|
46
|
+
<li class="nav-item">
|
|
47
|
+
<a class="nav-link" href="{{ url_for('design.experiment_run') }}">Compile/Run</a>
|
|
48
|
+
</li>
|
|
49
|
+
{% endif %}
|
|
50
|
+
{% if enable_monitor %}
|
|
51
|
+
<li class="nav-item">
|
|
52
|
+
<a class="nav-link" href="{{ url_for('monitor.stream_feed') }}">Monitor</a></li>
|
|
53
|
+
</li>
|
|
54
|
+
{% endif %}
|
|
48
55
|
<li class="nav-item">
|
|
49
56
|
<a class="nav-link" href="{{ url_for('control.deck_controllers') }}">Devices</a></li>
|
|
50
57
|
</li>
|
|
@@ -32,16 +32,6 @@ class User(db.Model, UserMixin):
|
|
|
32
32
|
return self.username
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
class Variable:
|
|
36
|
-
def __init__(self, name: str = None, data_type=str, value=None):
|
|
37
|
-
self.name = name
|
|
38
|
-
self.data_type = data_type
|
|
39
|
-
self.value = value
|
|
40
|
-
|
|
41
|
-
def __str__(self):
|
|
42
|
-
return self.name
|
|
43
|
-
|
|
44
|
-
|
|
45
35
|
class Script(db.Model):
|
|
46
36
|
__tablename__ = 'script'
|
|
47
37
|
# id = db.Column(db.Integer, primary_key=True)
|
|
@@ -128,20 +118,8 @@ class Script(db.Model):
|
|
|
128
118
|
if type(action['args']) is dict:
|
|
129
119
|
# pass
|
|
130
120
|
self.eval_list(args, arg_types)
|
|
131
|
-
|
|
132
121
|
else:
|
|
133
122
|
pass
|
|
134
|
-
# """handle"""
|
|
135
|
-
# args = list(args.values())[0]
|
|
136
|
-
# if not args.startswith("#"):
|
|
137
|
-
# if args in bool_dict.keys():
|
|
138
|
-
# args = bool_dict[args]
|
|
139
|
-
#
|
|
140
|
-
# else:
|
|
141
|
-
# if 'arg_types' in action:
|
|
142
|
-
# arg_types = action['arg_types']
|
|
143
|
-
# self._convert_type(args, arg_types)
|
|
144
|
-
|
|
145
123
|
action['args'] = args
|
|
146
124
|
action['return'] = output
|
|
147
125
|
|
|
@@ -186,14 +164,6 @@ class Script(db.Model):
|
|
|
186
164
|
def currently_editing_order(self, script):
|
|
187
165
|
self.id_order[self.editing_type] = script
|
|
188
166
|
|
|
189
|
-
# @property
|
|
190
|
-
# def editing_type(self):
|
|
191
|
-
# return self.editing_type
|
|
192
|
-
|
|
193
|
-
# @editing_type.setter
|
|
194
|
-
# def editing_type(self, change_type):
|
|
195
|
-
# self.editing_type = change_type
|
|
196
|
-
|
|
197
167
|
def update_time_stamp(self):
|
|
198
168
|
self.last_modified = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
199
169
|
|
|
@@ -236,6 +206,7 @@ class Script(db.Model):
|
|
|
236
206
|
self.update_time_stamp()
|
|
237
207
|
|
|
238
208
|
def add_variable(self, statement, variable, type):
|
|
209
|
+
variable = self.validate_function_name(variable)
|
|
239
210
|
convert_type = getattr(builtins, type)
|
|
240
211
|
statement = convert_type(statement)
|
|
241
212
|
current_len = len(self.currently_editing_script)
|
|
@@ -266,17 +237,20 @@ class Script(db.Model):
|
|
|
266
237
|
|
|
267
238
|
return output_variables
|
|
268
239
|
|
|
269
|
-
def
|
|
240
|
+
def validate_variables(self, kwargs):
|
|
241
|
+
"""
|
|
242
|
+
Validates the kwargs passed to the Script
|
|
243
|
+
"""
|
|
270
244
|
output_variables: Dict[str, str] = self.get_variables()
|
|
271
245
|
# print(output_variables)
|
|
272
246
|
for key, value in kwargs.items():
|
|
273
247
|
if type(value) is str and value in output_variables:
|
|
274
248
|
var_type = output_variables[value]
|
|
275
|
-
kwargs[key] = {value:var_type}
|
|
276
|
-
|
|
249
|
+
kwargs[key] = {value: var_type}
|
|
250
|
+
if isinstance(value, str) and value.startswith("#"):
|
|
251
|
+
kwargs[key] = f"#{self.validate_function_name(value[1:])}"
|
|
277
252
|
return kwargs
|
|
278
253
|
|
|
279
|
-
|
|
280
254
|
def add_logic_action(self, logic_type: str, statement):
|
|
281
255
|
current_len = len(self.currently_editing_script)
|
|
282
256
|
uid = uuid.uuid4().fields[-1]
|
|
@@ -294,7 +268,8 @@ class Script(db.Model):
|
|
|
294
268
|
"while":
|
|
295
269
|
[
|
|
296
270
|
{"id": current_len + 1, "instrument": 'while', "action": 'while',
|
|
297
|
-
"args": {"statement": 'False' if statement == '' else statement}, "return": '', "uuid": uid,
|
|
271
|
+
"args": {"statement": 'False' if statement == '' else statement}, "return": '', "uuid": uid,
|
|
272
|
+
"arg_types": {"statement": ''}},
|
|
298
273
|
{"id": current_len + 2, "instrument": 'while', "action": 'endwhile', "args": {}, "return": '',
|
|
299
274
|
"uuid": uid},
|
|
300
275
|
],
|
|
@@ -308,7 +283,8 @@ class Script(db.Model):
|
|
|
308
283
|
"repeat":
|
|
309
284
|
[
|
|
310
285
|
{"id": current_len + 1, "instrument": 'repeat', "action": "repeat",
|
|
311
|
-
"args": {"statement": 1 if statement == '' else statement}, "return": '', "uuid": uid,
|
|
286
|
+
"args": {"statement": 1 if statement == '' else statement}, "return": '', "uuid": uid,
|
|
287
|
+
"arg_types": {"statement": "int"}},
|
|
312
288
|
{"id": current_len + 2, "instrument": 'repeat', "action": 'endrepeat',
|
|
313
289
|
"args": {}, "return": '', "uuid": uid},
|
|
314
290
|
],
|
|
@@ -319,7 +295,9 @@ class Script(db.Model):
|
|
|
319
295
|
self.update_time_stamp()
|
|
320
296
|
|
|
321
297
|
def delete_action(self, id: int):
|
|
322
|
-
|
|
298
|
+
"""
|
|
299
|
+
Delete the action by id (step number)
|
|
300
|
+
"""
|
|
323
301
|
uid = next((action['uuid'] for action in self.currently_editing_script if action['id'] == int(id)), None)
|
|
324
302
|
id_to_be_removed = [action['id'] for action in self.currently_editing_script if action['uuid'] == uid]
|
|
325
303
|
order = self.currently_editing_order
|
|
@@ -330,6 +308,9 @@ class Script(db.Model):
|
|
|
330
308
|
self.update_time_stamp()
|
|
331
309
|
|
|
332
310
|
def duplicate_action(self, id: int):
|
|
311
|
+
"""
|
|
312
|
+
duplicate action by id (step number), available only for non logic actions
|
|
313
|
+
"""
|
|
333
314
|
action_to_duplicate = next((action for action in self.currently_editing_script if action['id'] == int(id)),
|
|
334
315
|
None)
|
|
335
316
|
insert_id = action_to_duplicate.get("id")
|
|
@@ -392,15 +373,18 @@ class Script(db.Model):
|
|
|
392
373
|
return output_str, return_list
|
|
393
374
|
|
|
394
375
|
def finalize(self):
|
|
376
|
+
"""finalize script, disable editing"""
|
|
395
377
|
self.status = "finalized"
|
|
396
378
|
self.update_time_stamp()
|
|
397
379
|
|
|
398
380
|
def save_as(self, name):
|
|
381
|
+
"""resave script, enable editing"""
|
|
399
382
|
self.name = name
|
|
400
383
|
self.status = "editing"
|
|
401
384
|
self.update_time_stamp()
|
|
402
385
|
|
|
403
386
|
def indent(self, unit=0):
|
|
387
|
+
"""helper: create _ unit of indent in code string"""
|
|
404
388
|
string = "\n"
|
|
405
389
|
for _ in range(unit):
|
|
406
390
|
string += "\t"
|
|
@@ -489,7 +473,6 @@ class Script(db.Model):
|
|
|
489
473
|
return f"{self.indent(indent_unit)}time.sleep({statement})", indent_unit
|
|
490
474
|
elif instrument == 'repeat':
|
|
491
475
|
return self._process_repeat(indent_unit, action_name, statement, next_action)
|
|
492
|
-
|
|
493
476
|
else:
|
|
494
477
|
return self._process_instrument_action(indent_unit, instrument, action_name, args, save_data)
|
|
495
478
|
|
|
@@ -578,7 +561,7 @@ class Script(db.Model):
|
|
|
578
561
|
if isinstance(args[arg], str) and args[arg].startswith("#"):
|
|
579
562
|
args_str = args_str.replace(f"'#{args[arg][1:]}'", args[arg][1:])
|
|
580
563
|
elif isinstance(args[arg], dict):
|
|
581
|
-
print(args[arg])
|
|
564
|
+
# print(args[arg])
|
|
582
565
|
variables = self.get_variables()
|
|
583
566
|
value = next(iter(args[arg]))
|
|
584
567
|
if value not in variables:
|
|
@@ -7,24 +7,17 @@ from flask_wtf import FlaskForm
|
|
|
7
7
|
from wtforms import StringField, FloatField, HiddenField, BooleanField, IntegerField
|
|
8
8
|
import inspect
|
|
9
9
|
|
|
10
|
-
from ivoryos.utils.db_models import Variable, Script
|
|
11
|
-
|
|
12
10
|
|
|
13
11
|
def find_variable(data, script):
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
# ]
|
|
22
|
-
added_variables.update(output_variables)
|
|
23
|
-
for variable_name, variable_type in added_variables.items():
|
|
12
|
+
"""
|
|
13
|
+
find user defined variables and return values in the script:Script
|
|
14
|
+
:param data: string of input variable name
|
|
15
|
+
:param script:Script object
|
|
16
|
+
"""
|
|
17
|
+
variables: dict[str, str] = script.get_variables()
|
|
18
|
+
for variable_name, variable_type in variables.items():
|
|
24
19
|
if variable_name == data:
|
|
25
20
|
return data, variable_type # variable_type int float str or "function_output"
|
|
26
|
-
# if added_variable["return"] == data:
|
|
27
|
-
# return data, None
|
|
28
21
|
return None, None
|
|
29
22
|
|
|
30
23
|
|
|
@@ -45,7 +38,7 @@ class VariableOrStringField(Field):
|
|
|
45
38
|
if self.script:
|
|
46
39
|
variable, variable_type = find_variable(self.data, self.script)
|
|
47
40
|
if variable:
|
|
48
|
-
return
|
|
41
|
+
return variable
|
|
49
42
|
|
|
50
43
|
return str(self.data) if self.data is not None else ""
|
|
51
44
|
|
|
@@ -61,7 +54,7 @@ class VariableOrFloatField(Field):
|
|
|
61
54
|
if self.script:
|
|
62
55
|
variable, variable_type = find_variable(self.data, self.script)
|
|
63
56
|
if variable:
|
|
64
|
-
return
|
|
57
|
+
return variable
|
|
65
58
|
|
|
66
59
|
if self.raw_data:
|
|
67
60
|
return self.raw_data[0]
|
|
@@ -109,7 +102,7 @@ class VariableOrIntField(Field):
|
|
|
109
102
|
if self.script:
|
|
110
103
|
variable, variable_type = find_variable(self.data, self.script)
|
|
111
104
|
if variable:
|
|
112
|
-
return
|
|
105
|
+
return variable
|
|
113
106
|
|
|
114
107
|
if self.raw_data:
|
|
115
108
|
return self.raw_data[0]
|
|
@@ -158,7 +151,7 @@ class VariableOrBoolField(BooleanField):
|
|
|
158
151
|
if variable:
|
|
159
152
|
if not variable_type == "function_output":
|
|
160
153
|
raise ValueError("Not accepting boolean variables")
|
|
161
|
-
return
|
|
154
|
+
return variable
|
|
162
155
|
|
|
163
156
|
self.data = bool(value)
|
|
164
157
|
|
|
@@ -183,7 +176,7 @@ class VariableOrBoolField(BooleanField):
|
|
|
183
176
|
if self.script:
|
|
184
177
|
variable, variable_type = find_variable(self.raw_data, self.script)
|
|
185
178
|
if variable:
|
|
186
|
-
return
|
|
179
|
+
return variable
|
|
187
180
|
|
|
188
181
|
if self.raw_data:
|
|
189
182
|
return str(self.raw_data[0])
|
|
@@ -197,7 +190,15 @@ def format_name(name):
|
|
|
197
190
|
return text.capitalize()
|
|
198
191
|
|
|
199
192
|
|
|
200
|
-
def create_form_for_method(method,
|
|
193
|
+
def create_form_for_method(method, autofill, script=None, design=True):
|
|
194
|
+
"""
|
|
195
|
+
Create forms for each method or signature
|
|
196
|
+
:param method: dict(docstring, signature)
|
|
197
|
+
:param autofill:bool if autofill is enabled
|
|
198
|
+
:param script:Script object
|
|
199
|
+
:param design: if design is enabled
|
|
200
|
+
"""
|
|
201
|
+
|
|
201
202
|
class DynamicForm(FlaskForm):
|
|
202
203
|
pass
|
|
203
204
|
|
|
@@ -233,32 +234,60 @@ def create_form_for_method(method, method_name, autofill, script=None, design=Tr
|
|
|
233
234
|
return DynamicForm
|
|
234
235
|
|
|
235
236
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
237
|
+
def create_add_form(attr, attr_name, autofill: bool, script=None, design: bool = True):
|
|
238
|
+
"""
|
|
239
|
+
Create forms for each method or signature
|
|
240
|
+
:param attr: dict(docstring, signature)
|
|
241
|
+
:param attr_name: method name
|
|
242
|
+
:param autofill:bool if autofill is enabled
|
|
243
|
+
:param script:Script object
|
|
244
|
+
:param design: if design is enabled. Design allows string input for parameter names ("#param") for all fields
|
|
245
|
+
"""
|
|
246
|
+
signature = attr.get('signature', {})
|
|
247
|
+
docstring = attr.get('docstring', "")
|
|
248
|
+
dynamic_form = create_form_for_method(signature, autofill, script, design)
|
|
239
249
|
if design:
|
|
240
250
|
return_value = StringField(label='Save value as', render_kw={"placeholder": "Optional"})
|
|
241
251
|
setattr(dynamic_form, 'return', return_value)
|
|
242
|
-
hidden_method_name = HiddenField(name=f'hidden_name', render_kw={"value": f'{attr_name}'})
|
|
252
|
+
hidden_method_name = HiddenField(name=f'hidden_name', description=docstring, render_kw={"value": f'{attr_name}'})
|
|
243
253
|
setattr(dynamic_form, 'hidden_name', hidden_method_name)
|
|
244
254
|
return dynamic_form
|
|
245
255
|
|
|
246
256
|
|
|
247
|
-
def create_form_from_module(sdl_module, autofill: bool, script=None, design=
|
|
248
|
-
|
|
257
|
+
def create_form_from_module(sdl_module, autofill: bool = False, script=None, design: bool = False):
|
|
258
|
+
"""
|
|
259
|
+
Create forms for each method, used for control routes
|
|
260
|
+
:param sdl_module: method module
|
|
261
|
+
:param autofill:bool if autofill is enabled
|
|
262
|
+
:param script:Script object
|
|
263
|
+
:param design: if design is enabled
|
|
264
|
+
"""
|
|
249
265
|
method_forms = {}
|
|
250
266
|
for attr_name in dir(sdl_module):
|
|
251
|
-
|
|
252
|
-
if inspect.ismethod(
|
|
267
|
+
method = getattr(sdl_module, attr_name)
|
|
268
|
+
if inspect.ismethod(method) and not attr_name.startswith('_'):
|
|
269
|
+
signature = inspect.signature(method)
|
|
270
|
+
docstring = inspect.getdoc(method)
|
|
271
|
+
attr = dict(signature=signature, docstring=docstring)
|
|
253
272
|
form_class = create_add_form(attr, attr_name, autofill, script, design)
|
|
254
273
|
method_forms[attr_name] = form_class()
|
|
255
274
|
return method_forms
|
|
256
275
|
|
|
257
276
|
|
|
258
277
|
def create_form_from_pseudo(pseudo: dict, autofill: bool, script=None, design=True):
|
|
259
|
-
|
|
278
|
+
"""
|
|
279
|
+
Create forms for pseudo method, used for design routes
|
|
280
|
+
:param pseudo:{'dose_liquid': {
|
|
281
|
+
"docstring": "some docstring",
|
|
282
|
+
"signature": Signature(amount_in_ml: float, rate_ml_per_minute: float) }
|
|
283
|
+
}
|
|
284
|
+
:param autofill:bool if autofill is enabled
|
|
285
|
+
:param script:Script object
|
|
286
|
+
:param design: if design is enabled
|
|
287
|
+
"""
|
|
260
288
|
method_forms = {}
|
|
261
289
|
for attr_name, signature in pseudo.items():
|
|
290
|
+
# signature = info.get('signature', {})
|
|
262
291
|
form_class = create_add_form(signature, attr_name, autofill, script, design)
|
|
263
292
|
method_forms[attr_name] = form_class()
|
|
264
293
|
return method_forms
|
|
@@ -266,15 +295,18 @@ def create_form_from_pseudo(pseudo: dict, autofill: bool, script=None, design=Tr
|
|
|
266
295
|
|
|
267
296
|
def create_form_from_action(action: dict, script=None, design=True):
|
|
268
297
|
'''
|
|
269
|
-
|
|
270
|
-
|
|
298
|
+
Create forms for single action, used for design routes
|
|
299
|
+
:param action: {'action': 'dose_solid', 'arg_types': {'amount_in_mg': 'float', 'bring_in': 'bool'},
|
|
300
|
+
'args': {'amount_in_mg': 5.0, 'bring_in': False}, 'id': 9,
|
|
301
|
+
'instrument': 'deck.sdl', 'return': '', 'uuid': 266929188668995}
|
|
302
|
+
:param script:Script object
|
|
303
|
+
:param design: if design is enabled
|
|
304
|
+
|
|
271
305
|
'''
|
|
272
|
-
# print(action)
|
|
273
306
|
|
|
274
307
|
arg_types = action.get("arg_types", {})
|
|
275
308
|
args = action.get("args", {})
|
|
276
309
|
save_as = action.get("return")
|
|
277
|
-
action = action.get("action")
|
|
278
310
|
|
|
279
311
|
class DynamicForm(FlaskForm):
|
|
280
312
|
pass
|
|
@@ -314,7 +346,10 @@ def create_form_from_action(action: dict, script=None, design=True):
|
|
|
314
346
|
return DynamicForm()
|
|
315
347
|
|
|
316
348
|
|
|
317
|
-
def create_builtin_form(logic_type,
|
|
349
|
+
def create_builtin_form(logic_type, script):
|
|
350
|
+
"""
|
|
351
|
+
Create a builtin form {if, while, variable, repeat, wait}
|
|
352
|
+
"""
|
|
318
353
|
class BuiltinFunctionForm(FlaskForm):
|
|
319
354
|
pass
|
|
320
355
|
|
|
@@ -355,12 +390,22 @@ def create_builtin_form(logic_type, autofill, script):
|
|
|
355
390
|
|
|
356
391
|
|
|
357
392
|
def create_action_button(script, stype=None):
|
|
393
|
+
"""
|
|
394
|
+
Creates action buttons for design route (design canvas)
|
|
395
|
+
:param script: Script object
|
|
396
|
+
:param stype: script type (script, prep, cleanup)
|
|
397
|
+
"""
|
|
358
398
|
stype = stype or script.editing_type
|
|
359
399
|
variables = script.get_variables()
|
|
360
400
|
return [_action_button(i, variables) for i in script.get_script(stype)]
|
|
361
401
|
|
|
362
402
|
|
|
363
403
|
def _action_button(action: dict, variables: dict):
|
|
404
|
+
"""
|
|
405
|
+
Creates action button for one action
|
|
406
|
+
:param action: Action dict
|
|
407
|
+
:param variables: created variable dict
|
|
408
|
+
"""
|
|
364
409
|
style = {
|
|
365
410
|
"repeat": "background-color: lightsteelblue",
|
|
366
411
|
"if": "background-color: salmon",
|
|
@@ -368,7 +413,7 @@ def _action_button(action: dict, variables: dict):
|
|
|
368
413
|
}.get(action['instrument'], "")
|
|
369
414
|
|
|
370
415
|
if action['instrument'] in ['if', 'while', 'repeat']:
|
|
371
|
-
text = f"{action['action']} {action['args']}"
|
|
416
|
+
text = f"{action['action']} {action['args'].get('statement', '')}"
|
|
372
417
|
elif action['instrument'] == 'variable':
|
|
373
418
|
text = f"{action['action']} = {action['args'].get('statement')}"
|
|
374
419
|
else:
|
|
@@ -382,18 +427,13 @@ def _action_button(action: dict, variables: dict):
|
|
|
382
427
|
for k, v in action['args'].items():
|
|
383
428
|
if isinstance(v, dict):
|
|
384
429
|
value = next(iter(v)) # Extract the first key if it's a dict
|
|
385
|
-
|
|
430
|
+
# show warning color for variable calling when there is no definition
|
|
386
431
|
style = "background-color: khaki" if value not in variables.keys() else ""
|
|
387
|
-
|
|
388
432
|
else:
|
|
389
433
|
value = v # Keep the original value if not a dict
|
|
390
|
-
|
|
391
434
|
arg_list.append(f"{k} = {value}") # Format the key-value pair
|
|
392
|
-
|
|
393
435
|
arg_string = "(" + ", ".join(arg_list) + ")"
|
|
394
436
|
else:
|
|
395
437
|
arg_string = f"= {action['args']}"
|
|
396
|
-
|
|
397
438
|
text = f"{prefix}{action_text} {arg_string}"
|
|
398
|
-
|
|
399
439
|
return dict(label=text, style=style, uuid=action["uuid"], id=action["id"], instrument=action['instrument'])
|
|
@@ -7,7 +7,6 @@ import pickle
|
|
|
7
7
|
import subprocess
|
|
8
8
|
import sys
|
|
9
9
|
from collections import Counter
|
|
10
|
-
from typing import Optional, Dict, Tuple
|
|
11
10
|
|
|
12
11
|
from flask import session
|
|
13
12
|
from flask_socketio import SocketIO
|
|
@@ -102,20 +101,9 @@ def _inspect_class(class_object=None, debug=False):
|
|
|
102
101
|
if not function.startswith(under_score) and not function.isupper():
|
|
103
102
|
try:
|
|
104
103
|
annotation = inspect.signature(method)
|
|
105
|
-
# if doc_string:
|
|
106
104
|
docstring = inspect.getdoc(method)
|
|
107
105
|
functions[function] = dict(signature=annotation, docstring=docstring)
|
|
108
106
|
|
|
109
|
-
# handle getter setters todo
|
|
110
|
-
# if callable(att):
|
|
111
|
-
# functions[function] = inspect.signature(att)
|
|
112
|
-
# else:
|
|
113
|
-
# att = getattr(class_object.__class__, function)
|
|
114
|
-
# if isinstance(att, property) and att.fset is not None:
|
|
115
|
-
# setter = att.fset.__annotations__
|
|
116
|
-
# setter.pop('return', None)
|
|
117
|
-
# if setter:
|
|
118
|
-
# functions[function] = setter
|
|
119
107
|
except Exception:
|
|
120
108
|
pass
|
|
121
109
|
return functions
|
|
@@ -146,23 +134,6 @@ def _get_type_from_parameters(arg, parameters):
|
|
|
146
134
|
arg_type = annotation.__name__
|
|
147
135
|
return arg_type
|
|
148
136
|
|
|
149
|
-
# # moved to script
|
|
150
|
-
# def find_variable_in_script(script: Script, args: Dict[str, str]) -> Optional[Tuple[Dict[str, str], Dict[str, str]]]:
|
|
151
|
-
# # TODO: need to search for if the variable exists
|
|
152
|
-
# added_variables: list[Dict[str, str]] = [action for action in script.currently_editing_script if
|
|
153
|
-
# action["instrument"] == "variable"]
|
|
154
|
-
#
|
|
155
|
-
# possible_variable_arguments = {}
|
|
156
|
-
# possible_variable_types = {}
|
|
157
|
-
#
|
|
158
|
-
# for arg_name, arg_val in args.items():
|
|
159
|
-
# for added_variable in added_variables:
|
|
160
|
-
# if added_variable["action"] == arg_val:
|
|
161
|
-
# possible_variable_arguments[arg_name] = added_variable["action"]
|
|
162
|
-
# possible_variable_types[arg_name] = "variable"
|
|
163
|
-
#
|
|
164
|
-
# return possible_variable_arguments, possible_variable_types
|
|
165
|
-
|
|
166
137
|
|
|
167
138
|
def _convert_by_str(args, arg_types):
|
|
168
139
|
"""
|
|
@@ -203,9 +174,6 @@ def convert_config_type(args, arg_types, is_class: bool = False):
|
|
|
203
174
|
"""
|
|
204
175
|
Converts an argument from str to an arg type
|
|
205
176
|
"""
|
|
206
|
-
bool_dict = {"True": True, "False": False}
|
|
207
|
-
# print(args, arg_types)
|
|
208
|
-
# print(globals())
|
|
209
177
|
if args:
|
|
210
178
|
for arg in args:
|
|
211
179
|
if arg not in arg_types.keys():
|
|
@@ -340,8 +308,10 @@ def ax_initiation(data, arg_types):
|
|
|
340
308
|
|
|
341
309
|
|
|
342
310
|
def get_arg_type(args, parameters):
|
|
311
|
+
"""get argument type from signature"""
|
|
343
312
|
arg_types = {}
|
|
344
313
|
# print(args, parameters)
|
|
314
|
+
parameters = parameters.get("signature")
|
|
345
315
|
if args:
|
|
346
316
|
for arg in args:
|
|
347
317
|
arg_types[arg] = _get_type_from_parameters(arg, parameters)
|
|
@@ -4,7 +4,6 @@ README.md
|
|
|
4
4
|
setup.py
|
|
5
5
|
ivoryos/__init__.py
|
|
6
6
|
ivoryos/config.py
|
|
7
|
-
ivoryos/version.py
|
|
8
7
|
ivoryos.egg-info/PKG-INFO
|
|
9
8
|
ivoryos.egg-info/SOURCES.txt
|
|
10
9
|
ivoryos.egg-info/dependency_links.txt
|
|
@@ -31,6 +30,8 @@ ivoryos/routes/main/__init__.py
|
|
|
31
30
|
ivoryos/routes/main/main.py
|
|
32
31
|
ivoryos/routes/main/templates/main/help.html
|
|
33
32
|
ivoryos/routes/main/templates/main/home.html
|
|
33
|
+
ivoryos/routes/monitor/monitor.py
|
|
34
|
+
ivoryos/routes/monitor/templates/monitor/monitor.html
|
|
34
35
|
ivoryos/static/favicon.ico
|
|
35
36
|
ivoryos/static/logo.webp
|
|
36
37
|
ivoryos/static/style.css
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.13"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/control/templates/control/controllers_home.html
RENAMED
|
File without changes
|
{ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/control/templates/control/controllers_new.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ivoryos-0.1.13 → ivoryos-0.1.15}/ivoryos/routes/design/templates/design/experiment_run.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|