zrb 1.5.16__py3-none-any.whl → 1.6.0__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.
- zrb/__init__.py +2 -2
- zrb/__main__.py +12 -12
- zrb/builtin/__init__.py +2 -2
- zrb/builtin/llm/chat_session.py +202 -0
- zrb/builtin/llm/history.py +6 -6
- zrb/builtin/llm/llm_ask.py +142 -0
- zrb/builtin/llm/tool/rag.py +39 -23
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/default/script.js +1 -1
- zrb/builtin/todo.py +21 -19
- zrb/callback/any_callback.py +1 -1
- zrb/callback/callback.py +69 -7
- zrb/config.py +261 -91
- zrb/context/shared_context.py +4 -2
- zrb/input/text_input.py +9 -6
- zrb/llm_config.py +65 -74
- zrb/runner/cli.py +13 -4
- zrb/runner/web_app.py +3 -3
- zrb/runner/web_config/config_factory.py +11 -22
- zrb/runner/web_route/error_page/show_error_page.py +16 -6
- zrb/runner/web_route/home_page/home_page_route.py +23 -7
- zrb/runner/web_route/home_page/view.html +19 -33
- zrb/runner/web_route/login_page/login_page_route.py +14 -4
- zrb/runner/web_route/login_page/view.html +33 -51
- zrb/runner/web_route/logout_page/logout_page_route.py +15 -5
- zrb/runner/web_route/logout_page/view.html +23 -41
- zrb/runner/web_route/node_page/group/show_group_page.py +26 -10
- zrb/runner/web_route/node_page/group/view.html +22 -37
- zrb/runner/web_route/node_page/task/show_task_page.py +34 -19
- zrb/runner/web_route/node_page/task/view.html +74 -88
- zrb/runner/web_route/static/global_template.html +27 -0
- zrb/runner/web_route/static/resources/common.css +21 -0
- zrb/runner/web_route/static/resources/common.js +28 -0
- zrb/runner/web_route/task_session_api_route.py +3 -1
- zrb/session_state_logger/session_state_logger_factory.py +2 -2
- zrb/task/base_task.py +4 -1
- zrb/task/base_trigger.py +47 -2
- zrb/task/cmd_task.py +3 -3
- zrb/task/llm/agent.py +10 -1
- zrb/task/llm/print_node.py +5 -6
- zrb/task/llm_task.py +1 -1
- zrb/util/git_subtree.py +1 -1
- {zrb-1.5.16.dist-info → zrb-1.6.0.dist-info}/METADATA +1 -1
- {zrb-1.5.16.dist-info → zrb-1.6.0.dist-info}/RECORD +45 -42
- zrb/builtin/llm/llm_chat.py +0 -124
- {zrb-1.5.16.dist-info → zrb-1.6.0.dist-info}/WHEEL +0 -0
- {zrb-1.5.16.dist-info → zrb-1.6.0.dist-info}/entry_points.txt +0 -0
@@ -1,41 +1,23 @@
|
|
1
|
-
|
2
|
-
<
|
3
|
-
|
4
|
-
<
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
</
|
13
|
-
|
14
|
-
<
|
15
|
-
|
16
|
-
<
|
17
|
-
|
18
|
-
<
|
19
|
-
<
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
</nav>
|
25
|
-
</hgroup>
|
26
|
-
</header>
|
27
|
-
<main class="container">
|
28
|
-
<article>
|
29
|
-
<h2>Ready to log out?</h2>
|
30
|
-
<p>You are currently logged in as <strong>{user.username}</strong>.</p>
|
31
|
-
<div class="button-group">
|
32
|
-
<button class="primary" onclick="logout()">🚪 Logout</button>
|
33
|
-
<button class="secondary" onclick="window.history.back()">🔙 Cancel</button>
|
34
|
-
</div>
|
35
|
-
</article>
|
36
|
-
</main>
|
37
|
-
<script src="/static/logout/event.js"></script>
|
38
|
-
<script src="/refresh-token.js"></script>
|
39
|
-
</body>
|
40
|
-
|
41
|
-
</html>
|
1
|
+
<header class="container">
|
2
|
+
<hgroup>
|
3
|
+
<h1>{name}</h1>
|
4
|
+
<p>{description}</p>
|
5
|
+
<nav>
|
6
|
+
<ul>
|
7
|
+
<li><a href="/">🏠 Home</a></li>
|
8
|
+
<li><a href="/docs">💻 API Documentation</a></li>
|
9
|
+
</ul>
|
10
|
+
</nav>
|
11
|
+
</hgroup>
|
12
|
+
</header>
|
13
|
+
<main class="container">
|
14
|
+
<article>
|
15
|
+
<h2>Ready to log out?</h2>
|
16
|
+
<p>You are currently logged in as <strong>{user.username}</strong>.</p>
|
17
|
+
<div class="button-group">
|
18
|
+
<button class="primary" onclick="logout()">🚪 Logout</button>
|
19
|
+
<button class="secondary" onclick="window.history.back()">🔙 Cancel</button>
|
20
|
+
</div>
|
21
|
+
</article>
|
22
|
+
</main>
|
23
|
+
<script src="/static/logout/event.js"></script>
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import os
|
2
2
|
|
3
|
+
from zrb.config import CFG
|
3
4
|
from zrb.group.any_group import AnyGroup
|
4
5
|
from zrb.runner.web_schema.user import User
|
5
6
|
from zrb.runner.web_util.html import (
|
@@ -15,7 +16,16 @@ def show_group_page(user: User, root_group: AnyGroup, group: AnyGroup, url: str)
|
|
15
16
|
from fastapi.responses import HTMLResponse
|
16
17
|
|
17
18
|
_DIR = os.path.dirname(__file__)
|
19
|
+
_GLOBAL_TEMPLATE = read_file(
|
20
|
+
os.path.join(
|
21
|
+
os.path.dirname(os.path.dirname(_DIR)), "static", "global_template.html"
|
22
|
+
)
|
23
|
+
)
|
18
24
|
_VIEW_TEMPLATE = read_file(os.path.join(_DIR, "view.html"))
|
25
|
+
web_title = CFG.WEB_TITLE if CFG.WEB_TITLE.strip() != "" else root_group.name
|
26
|
+
web_jargon = (
|
27
|
+
CFG.WEB_JARGON if CFG.WEB_JARGON.strip() != "" else root_group.description
|
28
|
+
)
|
19
29
|
url_parts = url.split("/")
|
20
30
|
parent_url_parts = url_parts[:-2] + [""]
|
21
31
|
parent_url = "/".join(parent_url_parts)
|
@@ -24,17 +34,23 @@ def show_group_page(user: User, root_group: AnyGroup, group: AnyGroup, url: str)
|
|
24
34
|
auth_link = get_html_auth_link(user)
|
25
35
|
return HTMLResponse(
|
26
36
|
fstring_format(
|
27
|
-
|
37
|
+
_GLOBAL_TEMPLATE,
|
28
38
|
{
|
29
|
-
"
|
30
|
-
"
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
39
|
+
"web_title": f"{web_title} | {group.name}",
|
40
|
+
"content": fstring_format(
|
41
|
+
_VIEW_TEMPLATE,
|
42
|
+
{
|
43
|
+
"web_title": web_title,
|
44
|
+
"web_jargon": web_jargon,
|
45
|
+
"group_info": group_info,
|
46
|
+
"task_info": task_info,
|
47
|
+
"name": group.name,
|
48
|
+
"description": group.description,
|
49
|
+
"auth_link": auth_link,
|
50
|
+
"url": url,
|
51
|
+
"parent_url": parent_url,
|
52
|
+
},
|
53
|
+
),
|
38
54
|
},
|
39
55
|
)
|
40
56
|
)
|
@@ -1,37 +1,22 @@
|
|
1
|
-
|
2
|
-
<
|
3
|
-
|
4
|
-
<
|
5
|
-
<
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
<ul>
|
24
|
-
<li>{auth_link}</li>
|
25
|
-
</ul>
|
26
|
-
</nav>
|
27
|
-
</hgroup>
|
28
|
-
</header>
|
29
|
-
<main class="container">
|
30
|
-
<h3>{name}</h3>
|
31
|
-
<p>{description}</p>
|
32
|
-
{group_info}
|
33
|
-
{task_info}
|
34
|
-
</main>
|
35
|
-
</body>
|
36
|
-
<script src="/refresh-token.js"></script>
|
37
|
-
</html>
|
1
|
+
<header class="container">
|
2
|
+
<hgroup>
|
3
|
+
<h1>{web_title}</h1>
|
4
|
+
<p>{web_jargon}</p>
|
5
|
+
<nav>
|
6
|
+
<ul>
|
7
|
+
<li><a href="/">🏠 Home</a></li>
|
8
|
+
<li><a href="{parent_url}">🔙 Parent</a></li>
|
9
|
+
<li><a href="/docs">💻 API Documentation</a></li>
|
10
|
+
</ul>
|
11
|
+
<ul>
|
12
|
+
<li>{auth_link}</li>
|
13
|
+
</ul>
|
14
|
+
</nav>
|
15
|
+
</hgroup>
|
16
|
+
</header>
|
17
|
+
<main class="container">
|
18
|
+
<h3>{name}</h3>
|
19
|
+
<p>{description}</p>
|
20
|
+
{group_info}
|
21
|
+
{task_info}
|
22
|
+
</main>
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import json
|
2
2
|
import os
|
3
3
|
|
4
|
+
from zrb.config import CFG
|
4
5
|
from zrb.group.any_group import AnyGroup
|
5
6
|
from zrb.runner.web_schema.user import User
|
6
7
|
from zrb.runner.web_util.html import get_html_auth_link
|
@@ -21,10 +22,18 @@ def show_task_page(
|
|
21
22
|
from fastapi.responses import HTMLResponse
|
22
23
|
|
23
24
|
_DIR = os.path.dirname(__file__)
|
25
|
+
_GLOBAL_TEMPLATE = read_file(
|
26
|
+
os.path.join(
|
27
|
+
os.path.dirname(os.path.dirname(_DIR)), "static", "global_template.html"
|
28
|
+
)
|
29
|
+
)
|
24
30
|
_VIEW_TEMPLATE = read_file(os.path.join(_DIR, "view.html"))
|
25
31
|
_TASK_INPUT_TEMPLATE = read_file(os.path.join(_DIR, "partial", "input.html"))
|
32
|
+
web_title = CFG.WEB_TITLE if CFG.WEB_TITLE.strip() != "" else root_group.name
|
33
|
+
web_jargon = (
|
34
|
+
CFG.WEB_JARGON if CFG.WEB_JARGON.strip() != "" else root_group.description
|
35
|
+
)
|
26
36
|
auth_link = get_html_auth_link(user)
|
27
|
-
|
28
37
|
session.register_task(task)
|
29
38
|
ctx = task.get_ctx(session)
|
30
39
|
url_parts = url.split("/")
|
@@ -53,26 +62,32 @@ def show_task_page(
|
|
53
62
|
session_name = args[0] if len(args) > 0 else ""
|
54
63
|
return HTMLResponse(
|
55
64
|
fstring_format(
|
56
|
-
|
65
|
+
_GLOBAL_TEMPLATE,
|
57
66
|
{
|
58
|
-
"
|
59
|
-
"
|
60
|
-
|
61
|
-
"root_name": root_group.name,
|
62
|
-
"root_description": root_group.description,
|
63
|
-
"url": url,
|
64
|
-
"parent_url": parent_url,
|
65
|
-
"task_inputs": "\n".join(input_html_list),
|
66
|
-
"ui_url": ui_url,
|
67
|
-
"json_cfg": json.dumps(
|
67
|
+
"web_title": f"{web_title} | {task.name}",
|
68
|
+
"content": fstring_format(
|
69
|
+
_VIEW_TEMPLATE,
|
68
70
|
{
|
69
|
-
"
|
70
|
-
"
|
71
|
-
"
|
72
|
-
"
|
73
|
-
"
|
74
|
-
"
|
75
|
-
|
71
|
+
"web_title": web_title,
|
72
|
+
"web_jargon": web_jargon,
|
73
|
+
"name": task.name,
|
74
|
+
"description": task.description,
|
75
|
+
"auth_link": auth_link,
|
76
|
+
"url": url,
|
77
|
+
"parent_url": parent_url,
|
78
|
+
"task_inputs": "\n".join(input_html_list),
|
79
|
+
"ui_url": ui_url,
|
80
|
+
"json_cfg": json.dumps(
|
81
|
+
{
|
82
|
+
"CURRENT_URL": url,
|
83
|
+
"SESSION_API_URL": session_api_url,
|
84
|
+
"INPUT_API_URL": input_api_url,
|
85
|
+
"UI_URL": ui_url,
|
86
|
+
"SESSION_NAME": session_name,
|
87
|
+
"PAGE": 0,
|
88
|
+
}
|
89
|
+
),
|
90
|
+
},
|
76
91
|
),
|
77
92
|
},
|
78
93
|
)
|
@@ -1,92 +1,78 @@
|
|
1
|
-
|
2
|
-
<
|
3
|
-
|
4
|
-
<
|
5
|
-
<
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
<header class="container">
|
2
|
+
<hgroup>
|
3
|
+
<h1>{web_title}</h1>
|
4
|
+
<p>{web_jargon}</p>
|
5
|
+
<nav>
|
6
|
+
<ul>
|
7
|
+
<li><a href="/">🏠 Home</a></li>
|
8
|
+
<li><a href="{parent_url}">🔙 Parent</a></li>
|
9
|
+
<li><a href="/docs">💻 API Documentation</a></li>
|
10
|
+
<li><a href="{ui_url}">🆕 New Session</a></li>
|
11
|
+
<li><a href="#" onclick="openPastSessionDialog(event)">📂 Existing Session</a></li>
|
12
|
+
</ul>
|
13
|
+
<ul>
|
14
|
+
<li>{auth_link}</li>
|
15
|
+
</ul>
|
16
|
+
</nav>
|
17
|
+
</hgroup>
|
18
|
+
</header>
|
12
19
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
<li><a href="{parent_url}">🔙 Parent</a></li>
|
21
|
-
<li><a href="/docs">💻 API Documentation</a></li>
|
22
|
-
<li><a href="{ui_url}">🆕 New Session</a></li>
|
23
|
-
<li><a href="#" onclick="openPastSessionDialog(event)">📂 Existing Session</a></li>
|
24
|
-
</ul>
|
25
|
-
<ul>
|
26
|
-
<li>{auth_link}</li>
|
27
|
-
</ul>
|
28
|
-
</nav>
|
29
|
-
</hgroup>
|
20
|
+
<dialog id="past-session-dialog">
|
21
|
+
<article>
|
22
|
+
<header>
|
23
|
+
<button aria-label="Close" rel="prev" onclick="closePastSessionDialog(event)"></button>
|
24
|
+
<p>
|
25
|
+
<strong>📂 Existing Session</strong>
|
26
|
+
</p>
|
30
27
|
</header>
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
<
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
</header>
|
40
|
-
<main>
|
41
|
-
<form>
|
42
|
-
<fieldset class="grid">
|
43
|
-
<input type="datetime-local" id="min-start-at-input" placeholder="Minimum Start Time" aria-label="Minimum Start Time" />
|
44
|
-
<input type="datetime-local" id="max-start-at-input" placeholder="Maximum Start Time" aria-label="Maximum Start Time" />
|
45
|
-
</fieldset>
|
46
|
-
</form>
|
47
|
-
<ul id="past-session-ul" style="font-family:monospace;"></ul>
|
48
|
-
</main>
|
49
|
-
<footer>
|
50
|
-
<nav>
|
51
|
-
<ul id="past-session-pagination-ul"></ul>
|
52
|
-
</nav>
|
53
|
-
</footer>
|
54
|
-
</article>
|
55
|
-
</dialog>
|
56
|
-
|
57
|
-
<main class="container">
|
58
|
-
<article>
|
59
|
-
<h2>{name}</h2>
|
60
|
-
<p>{description}</p>
|
61
|
-
<canvas id="history-canvas" height="0" width="1000" style="width: 100%;"></canvas>
|
62
|
-
</article>
|
63
|
-
<article>
|
64
|
-
<form id="submit-task-form" onsubmit="submitNewSessionForm(event)">
|
65
|
-
{task_inputs}
|
66
|
-
<button>🚀 Run New Session</button>
|
67
|
-
</form>
|
68
|
-
</article>
|
69
|
-
<article>
|
70
|
-
<label>
|
71
|
-
Result
|
72
|
-
<textarea id="result-textarea" rows="1" readonly style="font-family:monospace;">
|
73
|
-
</textarea>
|
74
|
-
</label>
|
75
|
-
<label>
|
76
|
-
Log
|
77
|
-
<textarea id="log-textarea" rows="5" readonly style="font-family:monospace;">
|
78
|
-
</textarea>
|
79
|
-
</label>
|
80
|
-
</article>
|
28
|
+
<main>
|
29
|
+
<form>
|
30
|
+
<fieldset class="grid">
|
31
|
+
<input type="datetime-local" id="min-start-at-input" placeholder="Minimum Start Time" aria-label="Minimum Start Time" />
|
32
|
+
<input type="datetime-local" id="max-start-at-input" placeholder="Maximum Start Time" aria-label="Maximum Start Time" />
|
33
|
+
</fieldset>
|
34
|
+
</form>
|
35
|
+
<ul id="past-session-ul" style="font-family:monospace;"></ul>
|
81
36
|
</main>
|
37
|
+
<footer>
|
38
|
+
<nav>
|
39
|
+
<ul id="past-session-pagination-ul"></ul>
|
40
|
+
</nav>
|
41
|
+
</footer>
|
42
|
+
</article>
|
43
|
+
</dialog>
|
44
|
+
|
45
|
+
<main class="container">
|
46
|
+
<article>
|
47
|
+
<h2>{name}</h2>
|
48
|
+
<p>{description}</p>
|
49
|
+
<canvas id="history-canvas" height="0" width="1000" style="width: 100%;"></canvas>
|
50
|
+
</article>
|
51
|
+
<article>
|
52
|
+
<form id="submit-task-form" onsubmit="submitNewSessionForm(event)">
|
53
|
+
{task_inputs}
|
54
|
+
<button>🚀 Run New Session</button>
|
55
|
+
</form>
|
56
|
+
</article>
|
57
|
+
<article>
|
58
|
+
<label>
|
59
|
+
Result
|
60
|
+
<textarea id="result-textarea" rows="1" readonly style="font-family:monospace;">
|
61
|
+
</textarea>
|
62
|
+
</label>
|
63
|
+
<label>
|
64
|
+
Log
|
65
|
+
<textarea id="log-textarea" rows="5" readonly style="font-family:monospace;">
|
66
|
+
</textarea>
|
67
|
+
</label>
|
68
|
+
</article>
|
69
|
+
</main>
|
82
70
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
<script src="/refresh-token.js"></script>
|
92
|
-
</html>
|
71
|
+
<script>
|
72
|
+
const cfg = {json_cfg};
|
73
|
+
</script>
|
74
|
+
<script src="/static/session/common-util.js"></script>
|
75
|
+
<script src="/static/session/past-session.js"></script>
|
76
|
+
<script src="/static/session/current-session.js"></script>
|
77
|
+
<script src="/static/session/event.js"></script>
|
78
|
+
<script src="/refresh-token.js"></script>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
6
|
+
<meta name="color-scheme" content="light dark">
|
7
|
+
<link rel="stylesheet" href="/static/pico.min.css">
|
8
|
+
<link rel="icon" href="/static/favicon-32x32.png" sizes="32x32" type="image/png">
|
9
|
+
<title>{web_title}</title>
|
10
|
+
<link rel="stylesheet" href="/static/common.css">
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<div class="theme-switcher">
|
14
|
+
<label for="theme-select">Theme:</label>
|
15
|
+
<select id="theme-select">
|
16
|
+
<option value="auto">🌗 Auto</option>
|
17
|
+
<option value="light">☀️ Light</option>
|
18
|
+
<option value="dark">🌙 Dark</option>
|
19
|
+
</select>
|
20
|
+
</div>
|
21
|
+
<div class="layout-container">
|
22
|
+
{content}
|
23
|
+
</div>
|
24
|
+
</body>
|
25
|
+
<script src="/refresh-token.js"></script>
|
26
|
+
<script src="/static/common.js"></script>
|
27
|
+
</html>
|
@@ -8,4 +8,25 @@ header hgroup {
|
|
8
8
|
}
|
9
9
|
nav ul {
|
10
10
|
padding: 0;
|
11
|
+
}
|
12
|
+
.theme-switcher {
|
13
|
+
position: fixed;
|
14
|
+
top: 1rem;
|
15
|
+
right: 1rem;
|
16
|
+
display: flex;
|
17
|
+
align-items: center;
|
18
|
+
gap: 0.5rem;
|
19
|
+
z-index: 1000;
|
20
|
+
}
|
21
|
+
|
22
|
+
.theme-switcher select {
|
23
|
+
padding: 0.25rem 2rem 0.25rem 0.25rem;
|
24
|
+
font-size: 0.875rem;
|
25
|
+
margin: 0;
|
26
|
+
height: auto;
|
27
|
+
}
|
28
|
+
|
29
|
+
.theme-switcher label {
|
30
|
+
font-size: 0.875rem;
|
31
|
+
margin: 0 0.5rem 0 0;
|
11
32
|
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
const themeSelect = document.getElementById('theme-select');
|
2
|
+
|
3
|
+
function setTheme(theme) {
|
4
|
+
document.documentElement.setAttribute('data-theme', theme);
|
5
|
+
localStorage.setItem('theme', theme);
|
6
|
+
}
|
7
|
+
|
8
|
+
function getSavedTheme() {
|
9
|
+
return localStorage.getItem('theme') || 'auto';
|
10
|
+
}
|
11
|
+
|
12
|
+
const savedTheme = getSavedTheme();
|
13
|
+
setTheme(savedTheme);
|
14
|
+
themeSelect.value = savedTheme;
|
15
|
+
|
16
|
+
themeSelect.addEventListener('change', (e) => {
|
17
|
+
setTheme(e.target.value);
|
18
|
+
});
|
19
|
+
|
20
|
+
function updateAutoTheme() {
|
21
|
+
if (getSavedTheme() === 'auto') {
|
22
|
+
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
23
|
+
document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
updateAutoTheme();
|
28
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateAutoTheme);
|
@@ -50,7 +50,9 @@ def serve_task_session_api(
|
|
50
50
|
return JSONResponse(content={"detail": "Forbidden"}, status_code=403)
|
51
51
|
session_name = residual_args[0] if residual_args else None
|
52
52
|
if not session_name:
|
53
|
-
shared_ctx = SharedContext(
|
53
|
+
shared_ctx = SharedContext(
|
54
|
+
env={**dict(os.environ), "_ZRB_WEB_ENV": "1"}
|
55
|
+
)
|
54
56
|
session = Session(shared_ctx=shared_ctx, root_group=root_group)
|
55
57
|
coro = asyncio.create_task(task.async_run(session, str_kwargs=inputs))
|
56
58
|
coroutines.append(coro)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from zrb.config import
|
1
|
+
from zrb.config import CFG
|
2
2
|
from zrb.session_state_logger.file_session_state_logger import FileSessionStateLogger
|
3
3
|
|
4
|
-
session_state_logger = FileSessionStateLogger(SESSION_LOG_DIR)
|
4
|
+
session_state_logger = FileSessionStateLogger(CFG.SESSION_LOG_DIR)
|
zrb/task/base_task.py
CHANGED
@@ -270,7 +270,10 @@ class BaseTask(AnyTask):
|
|
270
270
|
additional_error_note = (
|
271
271
|
f"Task: {self.name} ({self.__decl_file}:{self.__decl_line})"
|
272
272
|
)
|
273
|
-
|
273
|
+
if not isinstance(e, KeyboardInterrupt):
|
274
|
+
# if error is KeyboardInterrupt, don't print anything
|
275
|
+
ctx.log_error(additional_error_note)
|
276
|
+
# Add definition location to the error
|
274
277
|
if hasattr(e, "add_note"):
|
275
278
|
e.add_note(additional_error_note)
|
276
279
|
else:
|
zrb/task/base_trigger.py
CHANGED
@@ -19,6 +19,13 @@ from zrb.xcom.xcom import Xcom
|
|
19
19
|
|
20
20
|
|
21
21
|
class BaseTrigger(BaseTask):
|
22
|
+
"""
|
23
|
+
A base class for tasks that act as triggers or schedulers.
|
24
|
+
|
25
|
+
It extends BaseTask and adds functionality for handling callbacks
|
26
|
+
and managing a queue for data exchange.
|
27
|
+
"""
|
28
|
+
|
22
29
|
def __init__(
|
23
30
|
self,
|
24
31
|
name: str,
|
@@ -44,6 +51,37 @@ class BaseTrigger(BaseTask):
|
|
44
51
|
fallback: list[AnyTask] | AnyTask | None = None,
|
45
52
|
successor: list[AnyTask] | AnyTask | None = None,
|
46
53
|
):
|
54
|
+
"""
|
55
|
+
Initializes a new instance of the BaseTrigger class.
|
56
|
+
|
57
|
+
Args:
|
58
|
+
name: The name of the trigger task.
|
59
|
+
color: The color to use for the task in the CLI output.
|
60
|
+
icon: The icon to display for the task.
|
61
|
+
description: A brief description of the task.
|
62
|
+
cli_only: If True, the task is only available in the CLI.
|
63
|
+
input: The input definition for the task.
|
64
|
+
env: The environment variable definition for the task.
|
65
|
+
action: The action to be performed by the task.
|
66
|
+
execute_condition: A condition that must be met for the task to execute.
|
67
|
+
queue_name: The name of the XCom queue used for data
|
68
|
+
exchange with callbacks. Whenever any data is added
|
69
|
+
to xcom[queue_name], the callback will be triggered.
|
70
|
+
callback: A single or list of callbacks to be executed after the trigger action.
|
71
|
+
retries: The number of times to retry the task on failure.
|
72
|
+
retry_period: The time to wait between retries.
|
73
|
+
readiness_check: A single or list of tasks to check for readiness before execution.
|
74
|
+
readiness_check_delay: The initial delay before starting
|
75
|
+
readiness checks.
|
76
|
+
readiness_check_period: The time to wait between readiness checks.
|
77
|
+
readiness_failure_threshold: The number of consecutive readiness
|
78
|
+
check failures before the task fails.
|
79
|
+
readiness_timeout: The maximum time to wait for readiness checks to pass.
|
80
|
+
monitor_readiness: If True, monitor readiness checks during execution.
|
81
|
+
upstream: A single or list of tasks that must complete before this task starts.
|
82
|
+
fallback: A single or list of tasks to run if this task fails.
|
83
|
+
successor: A single or list of tasks to run after this task completes successfully.
|
84
|
+
"""
|
47
85
|
super().__init__(
|
48
86
|
name=name,
|
49
87
|
color=color if color is not None else CYAN,
|
@@ -104,11 +142,18 @@ class BaseTrigger(BaseTask):
|
|
104
142
|
for callback in self.callbacks:
|
105
143
|
xcom_dict = DotDict({self.queue_name: Xcom([data])})
|
106
144
|
callback_session = Session(
|
107
|
-
shared_ctx=SharedContext(
|
145
|
+
shared_ctx=SharedContext(
|
146
|
+
input=dict(session.shared_ctx.input),
|
147
|
+
xcom=xcom_dict,
|
148
|
+
),
|
108
149
|
parent=session,
|
109
150
|
root_group=session.root_group,
|
110
151
|
)
|
111
|
-
coros.append(
|
152
|
+
coros.append(
|
153
|
+
asyncio.create_task(
|
154
|
+
callback.async_run(parent_session=session, session=callback_session)
|
155
|
+
)
|
156
|
+
)
|
112
157
|
await asyncio.gather(*coros)
|
113
158
|
|
114
159
|
def get_exchange_xcom(self, session: AnySession) -> Xcom:
|
zrb/task/cmd_task.py
CHANGED
@@ -4,7 +4,7 @@ from functools import partial
|
|
4
4
|
from zrb.attr.type import BoolAttr, IntAttr, StrAttr
|
5
5
|
from zrb.cmd.cmd_result import CmdResult
|
6
6
|
from zrb.cmd.cmd_val import AnyCmdVal, CmdVal, SingleCmdVal
|
7
|
-
from zrb.config import
|
7
|
+
from zrb.config import CFG
|
8
8
|
from zrb.context.any_context import AnyContext
|
9
9
|
from zrb.env.any_env import AnyEnv
|
10
10
|
from zrb.input.any_input import AnyInput
|
@@ -149,7 +149,7 @@ class CmdTask(BaseTask):
|
|
149
149
|
|
150
150
|
def _get_should_warn_unrecommended_commands(self):
|
151
151
|
if self._should_warn_unrecommended_command is None:
|
152
|
-
return WARN_UNRECOMMENDED_COMMAND
|
152
|
+
return CFG.WARN_UNRECOMMENDED_COMMAND
|
153
153
|
return self._should_warn_unrecommended_command
|
154
154
|
|
155
155
|
def _check_unrecommended_commands(
|
@@ -170,7 +170,7 @@ class CmdTask(BaseTask):
|
|
170
170
|
|
171
171
|
def _get_shell(self, ctx: AnyContext) -> str:
|
172
172
|
return get_str_attr(
|
173
|
-
ctx, self._shell, DEFAULT_SHELL, auto_render=self._render_shell
|
173
|
+
ctx, self._shell, CFG.DEFAULT_SHELL, auto_render=self._render_shell
|
174
174
|
)
|
175
175
|
|
176
176
|
def _get_shell_flag(self, ctx: AnyContext) -> str:
|