ivoryos 0.1.7__py3-none-any.whl → 0.1.9__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.
Potentially problematic release.
This version of ivoryos might be problematic. Click here for more details.
- ivoryos/__init__.py +1 -1
- ivoryos/routes/control/templates/control/controllers.html +1 -1
- ivoryos/routes/database/database.py +0 -9
- ivoryos/routes/design/design.py +22 -1
- ivoryos/routes/design/templates/design/experiment_builder.html +5 -2
- ivoryos/templates/base.html +1 -1
- ivoryos/utils/db_models.py +21 -3
- ivoryos/utils/form.py +4 -3
- {ivoryos-0.1.7.dist-info → ivoryos-0.1.9.dist-info}/METADATA +4 -1
- {ivoryos-0.1.7.dist-info → ivoryos-0.1.9.dist-info}/RECORD +13 -15
- ivoryos/static/logo.png +0 -0
- ivoryos/utils/task_manager.py +0 -80
- {ivoryos-0.1.7.dist-info → ivoryos-0.1.9.dist-info}/LICENSE +0 -0
- {ivoryos-0.1.7.dist-info → ivoryos-0.1.9.dist-info}/WHEEL +0 -0
- {ivoryos-0.1.7.dist-info → ivoryos-0.1.9.dist-info}/top_level.txt +0 -0
ivoryos/__init__.py
CHANGED
|
@@ -19,7 +19,7 @@ global_config = GlobalConfig()
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def create_app(config_class=None):
|
|
22
|
-
url_prefix = os.getenv('URL_PREFIX',
|
|
22
|
+
url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
|
|
23
23
|
app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
|
|
24
24
|
app.config.from_object(config_class or 'config.get_config()')
|
|
25
25
|
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
{% endfor %}
|
|
38
38
|
</div>
|
|
39
39
|
<div class="input-group mb-3">
|
|
40
|
-
<button type="submit" name="{{ function }}" id="{{ function }}" class="form-control" style="background-color: #a5cece;">{{function}} </button>
|
|
40
|
+
<button type="submit" name="{{ function }}" id="{{ function }}" class="form-control" style="background-color: #a5cece;">{{format_name(function)}} </button>
|
|
41
41
|
</div>
|
|
42
42
|
</form>
|
|
43
43
|
</div>
|
|
@@ -7,15 +7,6 @@ from ivoryos.utils.utils import get_script_file, post_script_file
|
|
|
7
7
|
database = Blueprint('database', __name__, template_folder='templates/database')
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
@database.route("/delete/<id>")
|
|
11
|
-
@login_required
|
|
12
|
-
def delete_action(id):
|
|
13
|
-
back = request.referrer
|
|
14
|
-
script = get_script_file()
|
|
15
|
-
script.delete_action(id)
|
|
16
|
-
post_script_file(script)
|
|
17
|
-
return redirect(back)
|
|
18
|
-
|
|
19
10
|
|
|
20
11
|
@database.route("/edit_workflow/<workflow_name>")
|
|
21
12
|
@login_required
|
ivoryos/routes/design/design.py
CHANGED
|
@@ -13,7 +13,7 @@ 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
|
-
|
|
16
|
+
|
|
17
17
|
from ivoryos.utils.db_models import Script
|
|
18
18
|
from ivoryos.utils.script_runner import ScriptRunner
|
|
19
19
|
|
|
@@ -165,6 +165,7 @@ 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
|
|
168
169
|
agent = LlmAgent(host=server, model=model, output_path=os.path.dirname(os.path.abspath(module)))
|
|
169
170
|
except Exception as e:
|
|
170
171
|
flash(e.__str__())
|
|
@@ -394,3 +395,23 @@ def edit_action(uuid):
|
|
|
394
395
|
flash(e.__str__())
|
|
395
396
|
session.pop('edit_action')
|
|
396
397
|
return redirect(url_for('design.experiment_builder'))
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
@design.route("/delete/<id>", methods=['GET', 'POST'])
|
|
401
|
+
@login_required
|
|
402
|
+
def delete_action(id):
|
|
403
|
+
back = request.referrer
|
|
404
|
+
script = utils.get_script_file()
|
|
405
|
+
script.delete_action(id)
|
|
406
|
+
utils.post_script_file(script)
|
|
407
|
+
return redirect(back)
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
@design.route("/duplicate/<id>", methods=['GET', 'POST'])
|
|
411
|
+
@login_required
|
|
412
|
+
def duplicate_action(id):
|
|
413
|
+
back = request.referrer
|
|
414
|
+
script = utils.get_script_file()
|
|
415
|
+
script.duplicate_action(id)
|
|
416
|
+
utils.post_script_file(script)
|
|
417
|
+
return redirect(back)
|
|
@@ -301,8 +301,11 @@
|
|
|
301
301
|
<ul class="reorder">
|
|
302
302
|
{% for button in buttons %}
|
|
303
303
|
<li id="{{ button['id'] }}" style="list-style-type: none;">
|
|
304
|
-
|
|
305
|
-
|
|
304
|
+
<a href="{{ url_for('design.edit_action', uuid=button['uuid']) }}" type="button" class="btn btn-light" style="{{ button['style'] }}">{{ button['label'] }}</a>
|
|
305
|
+
{% if not button["instrument"] in ["if","while"] %}
|
|
306
|
+
<a href="{{ url_for('design.duplicate_action', id=button['id']) }}" type="button" class="btn btn-light"><span class="bi bi-copy"></span></a>
|
|
307
|
+
{% endif %}
|
|
308
|
+
<a href="{{ url_for('design.delete_action', id=button['id']) }}" type="button" class="btn btn-light"><span class="bi bi-trash"></span></a>
|
|
306
309
|
</li>
|
|
307
310
|
{% endfor %}
|
|
308
311
|
</ul>
|
ivoryos/templates/base.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>{% block title %}{% endblock %}</title>
|
|
7
7
|
{#bootstrap#}
|
|
8
8
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/css/bootstrap.min.css" integrity="sha384-aFq/bzH65dt+w6FI2ooMVUpc+21e0SRygnTpmBvdBgSdnuTN7QbdgL+OapgHtvPp" crossorigin="anonymous">
|
|
9
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.
|
|
9
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
|
|
10
10
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
11
11
|
{#static#}
|
|
12
12
|
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
ivoryos/utils/db_models.py
CHANGED
|
@@ -197,9 +197,10 @@ class Script(db.Model):
|
|
|
197
197
|
|
|
198
198
|
def add_action(self, action: dict):
|
|
199
199
|
current_len = len(self.currently_editing_script)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
action_to_add = action.copy()
|
|
201
|
+
action_to_add['id'] = current_len + 1
|
|
202
|
+
action_to_add['uuid'] = uuid.uuid4().fields[-1]
|
|
203
|
+
self.currently_editing_script.append(action_to_add)
|
|
203
204
|
self.currently_editing_order.append(str(current_len + 1))
|
|
204
205
|
self.update_time_stamp()
|
|
205
206
|
|
|
@@ -257,6 +258,23 @@ class Script(db.Model):
|
|
|
257
258
|
self.sort_actions()
|
|
258
259
|
self.update_time_stamp()
|
|
259
260
|
|
|
261
|
+
def duplicate_action(self, id: int):
|
|
262
|
+
action_to_duplicate = next((action for action in self.currently_editing_script if action['id'] == int(id)), None)
|
|
263
|
+
insert_id = action_to_duplicate.get("id")
|
|
264
|
+
self.add_action(action_to_duplicate)
|
|
265
|
+
# print(self.currently_editing_script)
|
|
266
|
+
if action_to_duplicate is not None:
|
|
267
|
+
# Update IDs for all subsequent actions
|
|
268
|
+
for action in self.currently_editing_script:
|
|
269
|
+
if action['id'] > insert_id:
|
|
270
|
+
action['id'] += 1
|
|
271
|
+
self.currently_editing_script[-1]['id'] = insert_id + 1
|
|
272
|
+
# Sort actions if necessary and update the time stamp
|
|
273
|
+
self.sort_actions()
|
|
274
|
+
self.update_time_stamp()
|
|
275
|
+
else:
|
|
276
|
+
raise ValueError("Action not found: Unable to duplicate the action with ID", id)
|
|
277
|
+
|
|
260
278
|
def config(self, stype):
|
|
261
279
|
"""
|
|
262
280
|
take the global script_dict
|
ivoryos/utils/form.py
CHANGED
|
@@ -220,7 +220,8 @@ def create_form_for_method(method, method_name, autofill, script=None, design=Tr
|
|
|
220
220
|
formatted_param_name = format_name(param.name)
|
|
221
221
|
field_kwargs = {
|
|
222
222
|
"label": formatted_param_name,
|
|
223
|
-
"default": f'#{param.name}' if autofill else (param.default if param.default is not param.empty else
|
|
223
|
+
"default": f'#{param.name}' if autofill else (param.default if param.default is not param.empty else None),
|
|
224
|
+
"validators": [InputRequired()] if param.default is param.empty else None,
|
|
224
225
|
**({"script": script} if (autofill or design) else {})
|
|
225
226
|
}
|
|
226
227
|
field_class, placeholder_text = annotation_mapping.get(
|
|
@@ -255,7 +256,7 @@ def create_form_from_module(sdl_module, autofill: bool, script=None, design=True
|
|
|
255
256
|
attr = getattr(sdl_module, attr_name)
|
|
256
257
|
if inspect.ismethod(attr) and not attr_name.startswith('_'):
|
|
257
258
|
form_class = create_add_form(attr, attr_name, autofill, script, design)
|
|
258
|
-
method_forms[
|
|
259
|
+
method_forms[attr_name] = form_class()
|
|
259
260
|
return method_forms
|
|
260
261
|
|
|
261
262
|
|
|
@@ -312,4 +313,4 @@ def create_action_button(s: dict):
|
|
|
312
313
|
arg_string = f"= {s['args']}"
|
|
313
314
|
|
|
314
315
|
text = f"{prefix}{action_text} {arg_string}"
|
|
315
|
-
return dict(label=text, style=style, uuid=s["uuid"], id=s["id"])
|
|
316
|
+
return dict(label=text, style=style, uuid=s["uuid"], id=s["id"], instrument=s['instrument'])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ivoryos
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9
|
|
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
|
|
@@ -137,6 +137,9 @@ ivoryos.run(__name__)
|
|
|
137
137
|
### Deck function and web form
|
|
138
138
|

|
|
139
139
|
|
|
140
|
+
### Text-to-code demo
|
|
141
|
+

|
|
142
|
+
|
|
140
143
|
### Directory structure
|
|
141
144
|
|
|
142
145
|
When you run the application for the first time, it will automatically create the following folders and files in the same directory:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
ivoryos/__init__.py,sha256=
|
|
1
|
+
ivoryos/__init__.py,sha256=0bjHffTf3m8NWU3zwLz7sZMDqhwNP9FpNXJhxFRliEQ,3938
|
|
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
|
|
@@ -7,22 +7,21 @@ ivoryos/routes/auth/templates/auth/login.html,sha256=1uxYU7NpxVaA4sfwkC6CuzZXJdy
|
|
|
7
7
|
ivoryos/routes/auth/templates/auth/signup.html,sha256=QQ7n4OBnF8TNFS5_4s11n4BCqSePn429rZfA6vO8qw8,1497
|
|
8
8
|
ivoryos/routes/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
ivoryos/routes/control/control.py,sha256=YKM1T_bDIggbW_NF6Ld6-rb3d0KbAjyikJztN-ka_XM,11305
|
|
10
|
-
ivoryos/routes/control/templates/control/controllers.html,sha256=
|
|
10
|
+
ivoryos/routes/control/templates/control/controllers.html,sha256=5LKKlhiGdg2fxs-akAAxtm1AMF5HAiuSlputDBMeTc0,4159
|
|
11
11
|
ivoryos/routes/control/templates/control/controllers_home.html,sha256=IND1T3_mPZd-MzfuyodbedMnmsTowiTVdRp5ez6NoZM,2783
|
|
12
12
|
ivoryos/routes/control/templates/control/controllers_new.html,sha256=Wqn9x9D6K7RWHkLFxvZkzbIJxHJR1zywQ6WDgySXOig,5010
|
|
13
13
|
ivoryos/routes/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
-
ivoryos/routes/database/database.py,sha256=
|
|
14
|
+
ivoryos/routes/database/database.py,sha256=W7axqxlRyIwqdLCuzYzER33obz6PCkevk6NTy-sCOLw,4133
|
|
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=
|
|
18
|
-
ivoryos/routes/design/templates/design/experiment_builder.html,sha256=
|
|
17
|
+
ivoryos/routes/design/design.py,sha256=dPSLY7sCD4tDqeqhGDlnRGdoeM7tUTeQqhWoeYAZrlU,17442
|
|
18
|
+
ivoryos/routes/design/templates/design/experiment_builder.html,sha256=jlRDAaSFY-ExsgdESYdNi_up-hlGqX02414aApbWYIc,27703
|
|
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
|
|
21
21
|
ivoryos/routes/main/main.py,sha256=Zkagtw0E67FaspNJ87jkYpc-wqqoTq99dyyB7qdnOVM,655
|
|
22
22
|
ivoryos/routes/main/templates/main/help.html,sha256=TY6uD-v8MXpiZlGucchko1Bas5jHRzARIgCgneBZ_ok,9511
|
|
23
23
|
ivoryos/routes/main/templates/main/home.html,sha256=fjeSSXkuVDr2y-CQmskNHf1yYFFdrPPI4wn6_XPb6AY,3252
|
|
24
24
|
ivoryos/static/favicon.ico,sha256=RhlrPtfITOkzC9BjP1UB1V5L9Oyp6NwNtWeMcGOnpyc,15406
|
|
25
|
-
ivoryos/static/logo.png,sha256=7lNyToDllflGPUK2sj7IBR8FkHLC-6gi-OVSL9o4jrs,63464
|
|
26
25
|
ivoryos/static/logo.webp,sha256=lXgfQR-4mHTH83k7VV9iB54-oC2ipe6uZvbwdOnLETc,14974
|
|
27
26
|
ivoryos/static/style.css,sha256=rY6n2mbP_xNavtVin_yUqtcvNm6uqAF82t7ONE2Sx9E,3918
|
|
28
27
|
ivoryos/static/gui_annotation/Slide1.png,sha256=Lm4gdOkUF5HIUFaB94tl6koQVkzpitKj43GXV_XYMMc,121727
|
|
@@ -31,17 +30,16 @@ ivoryos/static/js/overlay.js,sha256=44l9THVKYZfa7HX6siyqY7EdFWKBk5pyyKgN0_7ZnrM,
|
|
|
31
30
|
ivoryos/static/js/socket_handler.js,sha256=2936CldW6Po_saWh1aL_EV-VydJVIvikrNfTaSfU1sE,1449
|
|
32
31
|
ivoryos/static/js/sortable_card.js,sha256=mDVd2YjhusLokUw3xL6YOZLXIzty9yKDsC1U5yR8aC8,831
|
|
33
32
|
ivoryos/static/js/sortable_design.js,sha256=BxNXzqET_yY0xpS1Fc0iwPCnkkDwYMiuVqkgOPMb6JY,1156
|
|
34
|
-
ivoryos/templates/base.html,sha256=
|
|
33
|
+
ivoryos/templates/base.html,sha256=qmIF66gGOHtS7mnz5Zg_DnI1WgjBh7FtpMC_utaB49U,7943
|
|
35
34
|
ivoryos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
-
ivoryos/utils/db_models.py,sha256=
|
|
37
|
-
ivoryos/utils/form.py,sha256=
|
|
35
|
+
ivoryos/utils/db_models.py,sha256=mEQVvbJ-qxFM2uN9ciwx5SUvtGZHBc1HDSscTCfxyt0,20209
|
|
36
|
+
ivoryos/utils/form.py,sha256=fFswxZ-b5n_POVZ4IV-SCQ2iO9TK2Yp2AszoDA6bL84,12344
|
|
38
37
|
ivoryos/utils/global_config.py,sha256=JCQvmZB0pNC-EjveRu48Tp4uvcNwn9DP3Ema6Xd9fJY,1656
|
|
39
38
|
ivoryos/utils/llm_agent.py,sha256=z0DIpZzc-z09p-diUZIOE5L9zfFW8RwseFjbfUvEqoQ,6596
|
|
40
39
|
ivoryos/utils/script_runner.py,sha256=gtqiHy4-40j5FMERXrmGb4jb9RAPzjCR345PMPduDno,7120
|
|
41
|
-
ivoryos/utils/task_manager.py,sha256=xfQ1s9ywWDrCYYpdgliVvoWED0s2xARmo3LXvAy6fgY,2517
|
|
42
40
|
ivoryos/utils/utils.py,sha256=BMmvyBNo8PYs-MiBiiHjYPvSwrHORofbNwhPYpaVnfI,15249
|
|
43
|
-
ivoryos-0.1.
|
|
44
|
-
ivoryos-0.1.
|
|
45
|
-
ivoryos-0.1.
|
|
46
|
-
ivoryos-0.1.
|
|
47
|
-
ivoryos-0.1.
|
|
41
|
+
ivoryos-0.1.9.dist-info/LICENSE,sha256=psyqat4GJkzi42551i0kH-bXLbEzrQEnjPDwy2TVhv8,1105
|
|
42
|
+
ivoryos-0.1.9.dist-info/METADATA,sha256=DVCeKpp0iwQQ8WW_Nbdi_yqbdcXHCp9-8fhKexAC5OY,6200
|
|
43
|
+
ivoryos-0.1.9.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
|
44
|
+
ivoryos-0.1.9.dist-info/top_level.txt,sha256=FRIWWdiEvRKqw-XfF_UK3XV0CrnNb6EmVbEgjaVazRM,8
|
|
45
|
+
ivoryos-0.1.9.dist-info/RECORD,,
|
ivoryos/static/logo.png
DELETED
|
Binary file
|
ivoryos/utils/task_manager.py
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import threading
|
|
2
|
-
import queue
|
|
3
|
-
import time
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# A task manager class to manage the queue and tasks
|
|
7
|
-
class TaskManager:
|
|
8
|
-
def __init__(self):
|
|
9
|
-
self.task_queue = queue.Queue()
|
|
10
|
-
self.current_task = None
|
|
11
|
-
self.stop_event = threading.Event()
|
|
12
|
-
|
|
13
|
-
def add_task(self, func, **kwargs):
|
|
14
|
-
# Add the function and its kwargs to the task queue
|
|
15
|
-
self.task_queue.put((func, kwargs))
|
|
16
|
-
|
|
17
|
-
def run_tasks(self):
|
|
18
|
-
# Run the tasks from the queue
|
|
19
|
-
while not self.task_queue.empty():
|
|
20
|
-
func, kwargs = self.task_queue.get()
|
|
21
|
-
thread = threading.Thread(target=self.run_task, args=(func, kwargs))
|
|
22
|
-
self.current_task = thread
|
|
23
|
-
thread.start()
|
|
24
|
-
thread.join() # Wait for the task to finish
|
|
25
|
-
|
|
26
|
-
def run_task(self, func, kwargs):
|
|
27
|
-
# Run the task function with control to stop in the middle
|
|
28
|
-
self.stop_event.clear() # Reset the stop flag
|
|
29
|
-
func(**kwargs)
|
|
30
|
-
if self.stop_event.is_set():
|
|
31
|
-
print("Current task was stopped.")
|
|
32
|
-
|
|
33
|
-
def stop_current_task(self):
|
|
34
|
-
# Stop the current task by setting the stop flag
|
|
35
|
-
if self.current_task and self.current_task.is_alive():
|
|
36
|
-
print("Stopping current task...")
|
|
37
|
-
self.stop_event.set() # Signal to stop the current task
|
|
38
|
-
self.current_task.join() # Wait for the task to stop
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
# Wrapping tasks to allow stopping between them
|
|
42
|
-
def function_to_call(stop_event, **kwargs):
|
|
43
|
-
if stop_event.is_set():
|
|
44
|
-
return
|
|
45
|
-
task1(kwargs['arg1'])
|
|
46
|
-
if stop_event.is_set():
|
|
47
|
-
return
|
|
48
|
-
task2(kwargs['arg2'])
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
# Dummy task functions as provided
|
|
52
|
-
def task1(arg1):
|
|
53
|
-
for i in range(arg1):
|
|
54
|
-
print(f"Task 1 running: {i}")
|
|
55
|
-
time.sleep(1)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def task2(arg2):
|
|
59
|
-
for i in range(arg2):
|
|
60
|
-
print(f"Task 2 running: {i}")
|
|
61
|
-
time.sleep(1)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if __name__ == "__main__":
|
|
65
|
-
manager = TaskManager()
|
|
66
|
-
|
|
67
|
-
# Add tasks to the manager
|
|
68
|
-
manager.add_task(function_to_call, stop_event=manager.stop_event, arg1=3, arg2=5)
|
|
69
|
-
manager.add_task(function_to_call, stop_event=manager.stop_event, arg1=2, arg2=4)
|
|
70
|
-
|
|
71
|
-
# Run tasks in a separate thread
|
|
72
|
-
manager_thread = threading.Thread(target=manager.run_tasks)
|
|
73
|
-
manager_thread.start()
|
|
74
|
-
|
|
75
|
-
# Example: Stop the current workflow while task1 is running
|
|
76
|
-
time.sleep(2) # Let task1 run for a bit
|
|
77
|
-
manager.stop_current_task()
|
|
78
|
-
|
|
79
|
-
# Wait for all tasks to finish
|
|
80
|
-
manager_thread.join()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|