zrb 1.0.0a3__py3-none-any.whl → 1.0.0a4__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 +3 -1
- zrb/builtin/__init__.py +4 -2
- zrb/builtin/base64.py +4 -2
- zrb/builtin/{llm.py → llm/llm_chat.py} +18 -2
- zrb/builtin/llm/tool/cli.py +9 -0
- zrb/builtin/llm/tool/rag.py +189 -0
- zrb/builtin/llm/tool/web.py +74 -0
- zrb/builtin/md5.py +4 -2
- zrb/builtin/project/add/fastapp.py +1 -1
- zrb/builtin/project/add/fastapp_template/_zrb/helper.py +3 -3
- zrb/builtin/project/add/fastapp_template/_zrb/main.py +1 -1
- zrb/builtin/project/create/create.py +1 -1
- zrb/builtin/todo.py +122 -89
- zrb/config.py +12 -2
- zrb/runner/cli.py +8 -7
- zrb/runner/{web_server.py → web_app.py} +13 -13
- zrb/runner/{web_app → web_controller}/group_info_ui/controller.py +2 -2
- zrb/runner/{web_app → web_controller}/home_page/controller.py +2 -2
- zrb/runner/{web_app → web_controller}/task_ui/controller.py +2 -2
- zrb/task/cmd_task.py +24 -26
- zrb/task/http_check.py +5 -5
- zrb/task/llm_task.py +91 -36
- zrb/task/rsync_task.py +18 -18
- zrb/task/scaffolder.py +4 -4
- zrb/task/tcp_check.py +3 -5
- zrb/util/todo.py +139 -15
- {zrb-1.0.0a3.dist-info → zrb-1.0.0a4.dist-info}/METADATA +6 -1
- {zrb-1.0.0a3.dist-info → zrb-1.0.0a4.dist-info}/RECORD +53 -50
- /zrb/runner/{web_app → web_controller}/__init__.py +0 -0
- /zrb/runner/{web_app → web_controller}/group_info_ui/__init__.py +0 -0
- /zrb/runner/{web_app → web_controller}/group_info_ui/partial/group_info.html +0 -0
- /zrb/runner/{web_app → web_controller}/group_info_ui/partial/group_li.html +0 -0
- /zrb/runner/{web_app → web_controller}/group_info_ui/partial/task_info.html +0 -0
- /zrb/runner/{web_app → web_controller}/group_info_ui/partial/task_li.html +0 -0
- /zrb/runner/{web_app → web_controller}/group_info_ui/view.html +0 -0
- /zrb/runner/{web_app → web_controller}/home_page/__init__.py +0 -0
- /zrb/runner/{web_app → web_controller}/home_page/partial/group_info.html +0 -0
- /zrb/runner/{web_app → web_controller}/home_page/partial/group_li.html +0 -0
- /zrb/runner/{web_app → web_controller}/home_page/partial/task_info.html +0 -0
- /zrb/runner/{web_app → web_controller}/home_page/partial/task_li.html +0 -0
- /zrb/runner/{web_app → web_controller}/home_page/view.html +0 -0
- /zrb/runner/{web_app → web_controller}/static/favicon-32x32.png +0 -0
- /zrb/runner/{web_app → web_controller}/static/pico.min.css +0 -0
- /zrb/runner/{web_app → web_controller}/task_ui/__init__.py +0 -0
- /zrb/runner/{web_app → web_controller}/task_ui/partial/common-util.js +0 -0
- /zrb/runner/{web_app → web_controller}/task_ui/partial/input.html +0 -0
- /zrb/runner/{web_app → web_controller}/task_ui/partial/main.js +0 -0
- /zrb/runner/{web_app → web_controller}/task_ui/partial/show-existing-session.js +0 -0
- /zrb/runner/{web_app → web_controller}/task_ui/partial/visualize-history.js +0 -0
- /zrb/runner/{web_app → web_controller}/task_ui/view.html +0 -0
- {zrb-1.0.0a3.dist-info → zrb-1.0.0a4.dist-info}/WHEEL +0 -0
- {zrb-1.0.0a3.dist-info → zrb-1.0.0a4.dist-info}/entry_points.txt +0 -0
zrb/builtin/todo.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
import datetime
|
2
|
+
import json
|
2
3
|
import os
|
4
|
+
from typing import Any
|
3
5
|
|
4
6
|
from zrb.builtin.group import todo_group
|
5
7
|
from zrb.config import TODO_DIR
|
@@ -7,19 +9,16 @@ from zrb.context.any_context import AnyContext
|
|
7
9
|
from zrb.input.str_input import StrInput
|
8
10
|
from zrb.input.text_input import TextInput
|
9
11
|
from zrb.task.make_task import make_task
|
10
|
-
from zrb.util.cli.style import (
|
11
|
-
stylize_bold_green,
|
12
|
-
stylize_cyan,
|
13
|
-
stylize_magenta,
|
14
|
-
stylize_yellow,
|
15
|
-
)
|
16
|
-
from zrb.util.string.name import get_random_name
|
17
12
|
from zrb.util.todo import (
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
TodoTaskModel,
|
14
|
+
add_durations,
|
15
|
+
cascade_todo_task,
|
16
|
+
get_visual_todo_list,
|
17
|
+
line_to_todo_task,
|
18
|
+
load_todo_list,
|
19
|
+
save_todo_list,
|
20
|
+
select_todo_task,
|
21
21
|
todo_task_to_line,
|
22
|
-
write_todo_to_file,
|
23
22
|
)
|
24
23
|
|
25
24
|
|
@@ -54,14 +53,14 @@ from zrb.util.todo import (
|
|
54
53
|
)
|
55
54
|
def todo_add(ctx: AnyContext):
|
56
55
|
todo_file_path = os.path.join(TODO_DIR, "todo.txt")
|
57
|
-
|
56
|
+
todo_list: list[TodoTaskModel] = []
|
58
57
|
if os.path.isfile(todo_file_path):
|
59
|
-
|
58
|
+
todo_list = load_todo_list(todo_file_path)
|
60
59
|
else:
|
61
60
|
os.makedirs(TODO_DIR, exist_ok=True)
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
todo_list.append(
|
62
|
+
cascade_todo_task(
|
63
|
+
TodoTaskModel(
|
65
64
|
priority=ctx.input.priority.upper(),
|
66
65
|
description=ctx.input.description,
|
67
66
|
contexts=[
|
@@ -77,13 +76,111 @@ def todo_add(ctx: AnyContext):
|
|
77
76
|
)
|
78
77
|
)
|
79
78
|
)
|
80
|
-
|
81
|
-
return
|
79
|
+
save_todo_list(todo_file_path, todo_list)
|
80
|
+
return get_visual_todo_list(todo_list)
|
82
81
|
|
83
82
|
|
84
83
|
@make_task(name="todo-list", description="📋 List todo", group=todo_group, alias="list")
|
85
84
|
def todo_list(ctx: AnyContext):
|
86
|
-
|
85
|
+
todo_file_path = os.path.join(TODO_DIR, "todo.txt")
|
86
|
+
todo_tasks: list[TodoTaskModel] = []
|
87
|
+
if os.path.isfile(todo_file_path):
|
88
|
+
todo_tasks = load_todo_list(todo_file_path)
|
89
|
+
return get_visual_todo_list(todo_tasks)
|
90
|
+
|
91
|
+
|
92
|
+
@make_task(
|
93
|
+
name="todo-complete",
|
94
|
+
input=StrInput(name="keyword", prompt="Task keyword", description="Task Keyword"),
|
95
|
+
description="✅ Complete todo",
|
96
|
+
group=todo_group,
|
97
|
+
alias="complete",
|
98
|
+
)
|
99
|
+
def todo_complete(ctx: AnyContext):
|
100
|
+
todo_file_path = os.path.join(TODO_DIR, "todo.txt")
|
101
|
+
todo_list: list[TodoTaskModel] = []
|
102
|
+
if os.path.isfile(todo_file_path):
|
103
|
+
todo_list = load_todo_list(todo_file_path)
|
104
|
+
# Get todo task
|
105
|
+
todo_task = select_todo_task(todo_list, ctx.input.keyword)
|
106
|
+
if todo_task is None:
|
107
|
+
ctx.log_error("Task not found")
|
108
|
+
return get_visual_todo_list(todo_list)
|
109
|
+
# Update todo task
|
110
|
+
todo_task = cascade_todo_task(todo_task)
|
111
|
+
if todo_task.creation_date is not None:
|
112
|
+
todo_task.completion_date = datetime.date.today()
|
113
|
+
todo_task.completed = True
|
114
|
+
# Save todo list
|
115
|
+
save_todo_list(todo_file_path, todo_list)
|
116
|
+
return get_visual_todo_list(todo_list)
|
117
|
+
|
118
|
+
|
119
|
+
@make_task(
|
120
|
+
name="todo-log",
|
121
|
+
input=[
|
122
|
+
StrInput(name="keyword", prompt="Task keyword", description="Task Keyword"),
|
123
|
+
StrInput(
|
124
|
+
name="start",
|
125
|
+
prompt="Working start time (%Y-%m-%d %H:%M:%S)",
|
126
|
+
description="Working start time",
|
127
|
+
default_str=lambda _: _get_default_start(),
|
128
|
+
),
|
129
|
+
StrInput(
|
130
|
+
name="duration",
|
131
|
+
prompt="Working duration",
|
132
|
+
description="Working duration",
|
133
|
+
default_str="30m",
|
134
|
+
),
|
135
|
+
StrInput(
|
136
|
+
name="log",
|
137
|
+
prompt="Working log",
|
138
|
+
description="Working log",
|
139
|
+
),
|
140
|
+
],
|
141
|
+
description="🕒 Log work todo",
|
142
|
+
group=todo_group,
|
143
|
+
alias="log",
|
144
|
+
)
|
145
|
+
def todo_log(ctx: AnyContext):
|
146
|
+
todo_file_path = os.path.join(TODO_DIR, "todo.txt")
|
147
|
+
todo_list: list[TodoTaskModel] = []
|
148
|
+
if os.path.isfile(todo_file_path):
|
149
|
+
todo_list = load_todo_list(todo_file_path)
|
150
|
+
# Get todo task
|
151
|
+
todo_task = select_todo_task(todo_list, ctx.input.keyword)
|
152
|
+
if todo_task is None:
|
153
|
+
ctx.log_error("Task not found")
|
154
|
+
return get_visual_todo_list(todo_list)
|
155
|
+
# Update todo task
|
156
|
+
todo_task = cascade_todo_task(todo_task)
|
157
|
+
current_duration = todo_task.keyval.get("duration", "0")
|
158
|
+
todo_task.keyval["duration"] = add_durations(current_duration, ctx.input.duration)
|
159
|
+
print(current_duration, todo_task.keyval)
|
160
|
+
# Save todo list
|
161
|
+
save_todo_list(todo_file_path, todo_list)
|
162
|
+
# Add log work
|
163
|
+
log_work_dir = os.path.join(TODO_DIR, "log-work")
|
164
|
+
os.makedirs(log_work_dir, exist_ok=True)
|
165
|
+
log_work_file_path = os.path.join(
|
166
|
+
log_work_dir, f"{todo_task.keyval.get('id')}.json"
|
167
|
+
)
|
168
|
+
if os.path.isfile(log_work_file_path):
|
169
|
+
with open(log_work_file_path, "r") as f:
|
170
|
+
log_work_json = f.read()
|
171
|
+
else:
|
172
|
+
log_work_json = "[]"
|
173
|
+
log_work: list[dict[str, Any]] = json.loads(log_work_json)
|
174
|
+
log_work.append(
|
175
|
+
{"log": ctx.input.log, "duration": ctx.input.duration, "start": ctx.input.start}
|
176
|
+
)
|
177
|
+
with open(log_work_file_path, "w") as f:
|
178
|
+
f.write(json.dumps(log_work, indent=2))
|
179
|
+
return get_visual_todo_list(todo_list)
|
180
|
+
|
181
|
+
|
182
|
+
def _get_default_start() -> str:
|
183
|
+
return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
87
184
|
|
88
185
|
|
89
186
|
@make_task(
|
@@ -96,86 +193,22 @@ def todo_list(ctx: AnyContext):
|
|
96
193
|
default_str=lambda _: _get_todo_txt_content(),
|
97
194
|
),
|
98
195
|
],
|
99
|
-
description="
|
196
|
+
description="📝 Edit todo",
|
100
197
|
group=todo_group,
|
101
198
|
alias="edit",
|
102
199
|
)
|
103
200
|
def todo_edit(ctx: AnyContext):
|
104
|
-
|
105
|
-
|
201
|
+
todo_list = [
|
202
|
+
cascade_todo_task(line_to_todo_task(line))
|
106
203
|
for line in ctx.input.text.split("\n")
|
107
204
|
if line.strip() != ""
|
108
205
|
]
|
109
|
-
new_content = "\n".join(todo_task_to_line(todo_task) for todo_task in
|
206
|
+
new_content = "\n".join(todo_task_to_line(todo_task) for todo_task in todo_list)
|
110
207
|
todo_file_path = os.path.join(TODO_DIR, "todo.txt")
|
111
208
|
with open(todo_file_path, "w") as f:
|
112
209
|
f.write(new_content)
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
def _complete_todo_task(todo_task: TodoTask):
|
117
|
-
if todo_task.creation_date is None:
|
118
|
-
todo_task.creation_date = datetime.date.today()
|
119
|
-
if "id" not in todo_task.keyval:
|
120
|
-
todo_task.keyval["id"] = get_random_name()
|
121
|
-
return todo_task
|
122
|
-
|
123
|
-
|
124
|
-
def _get_visual_todo_list() -> str:
|
125
|
-
todo_file_path = os.path.join(TODO_DIR, "todo.txt")
|
126
|
-
if not os.path.isfile(todo_file_path):
|
127
|
-
return "\n".join(["", " Todo.txt not found... 🌵🦖", ""])
|
128
|
-
todo_tasks = read_todo_from_file(todo_file_path)
|
129
|
-
if len(todo_tasks) == 0:
|
130
|
-
return "\n".join(["", " Empty todo list... 🌵🦖", ""])
|
131
|
-
max_desc_name_length = max(len(todo_task.description) for todo_task in todo_tasks)
|
132
|
-
if max_desc_name_length < len("DESCRIPTION"):
|
133
|
-
max_desc_name_length = len("DESCRIPTION")
|
134
|
-
# Headers
|
135
|
-
results = [
|
136
|
-
stylize_bold_green(
|
137
|
-
" ".join(
|
138
|
-
[
|
139
|
-
"".ljust(3), # priority
|
140
|
-
"".ljust(3), # completed
|
141
|
-
"COMPLETED AT".rjust(14), # completed date
|
142
|
-
"CREATED AT".rjust(14), # completed date
|
143
|
-
"DESCRIPTION".ljust(max_desc_name_length),
|
144
|
-
"PROJECT/CONTEXT/OTHERS",
|
145
|
-
]
|
146
|
-
)
|
147
|
-
)
|
148
|
-
]
|
149
|
-
for todo_task in todo_tasks:
|
150
|
-
completed = "[x]" if todo_task.completed else "[ ]"
|
151
|
-
priority = " " if todo_task.priority is None else f"({todo_task.priority})"
|
152
|
-
completion_date = stylize_yellow(_date_to_str(todo_task.completion_date))
|
153
|
-
creation_date = stylize_cyan(_date_to_str(todo_task.creation_date))
|
154
|
-
description = todo_task.description.ljust(max_desc_name_length)
|
155
|
-
additions = ", ".join(
|
156
|
-
[stylize_yellow(f"+{project}") for project in todo_task.projects]
|
157
|
-
+ [stylize_cyan(f"@{context}") for context in todo_task.contexts]
|
158
|
-
+ [stylize_magenta(f"{key}:{val}") for key, val in todo_task.keyval.items()]
|
159
|
-
)
|
160
|
-
results.append(
|
161
|
-
" ".join(
|
162
|
-
[
|
163
|
-
completed,
|
164
|
-
priority,
|
165
|
-
completion_date,
|
166
|
-
creation_date,
|
167
|
-
description,
|
168
|
-
additions,
|
169
|
-
]
|
170
|
-
)
|
171
|
-
)
|
172
|
-
return "\n".join(results)
|
173
|
-
|
174
|
-
|
175
|
-
def _date_to_str(date: datetime.date | None) -> str:
|
176
|
-
if date is None:
|
177
|
-
return "".ljust(14)
|
178
|
-
return date.strftime("%a %Y-%m-%d")
|
210
|
+
todo_list = load_todo_list(todo_file_path)
|
211
|
+
return get_visual_todo_list(todo_list)
|
179
212
|
|
180
213
|
|
181
214
|
def _get_todo_txt_content() -> str:
|
zrb/config.py
CHANGED
@@ -46,9 +46,8 @@ INIT_SCRIPTS = (
|
|
46
46
|
else []
|
47
47
|
)
|
48
48
|
LOGGING_LEVEL = _get_log_level(os.getenv("ZRB_LOGGING_LEVEL", "WARNING"))
|
49
|
-
|
49
|
+
LOAD_BUILTIN = to_boolean(os.getenv("ZRB_LOAD_BUILTIN", "1"))
|
50
50
|
ENV_PREFIX = os.getenv("ZRB_ENV", "")
|
51
|
-
SHOW_ADVERTISEMENT = to_boolean(os.getenv("ZRB_SHOW_ADVERTISEMENT", "1"))
|
52
51
|
SHOW_PROMPT = to_boolean(os.getenv("ZRB_SHOW_PROMPT", "1"))
|
53
52
|
SESSION_LOG_DIR = os.getenv(
|
54
53
|
"ZRB_SESSION_LOG_DIR", os.path.expanduser(os.path.join("~", ".zrb-session"))
|
@@ -58,6 +57,17 @@ VERSION = metadata.version("zrb")
|
|
58
57
|
WEB_HTTP_PORT = int(os.getenv("ZRB_WEB_HTTP_PORT", "21213"))
|
59
58
|
LLM_MODEL = os.getenv("ZRB_LLM_MODEL", "ollama_chat/llama3.1")
|
60
59
|
LLM_SYSTEM_PROMPT = os.getenv("ZRB_LLM_SYSTEM_PROMPT", "You are a helpful assistant")
|
60
|
+
LLM_HISTORY_FILE = os.getenv(
|
61
|
+
"ZRB_LLM_HISTORY_FILE",
|
62
|
+
os.path.expanduser(os.path.join("~", ".zrb-llm-history.json")),
|
63
|
+
)
|
64
|
+
LLM_ALLOW_ACCESS_SHELL = to_boolean(os.getenv("ZRB_LLM_ACCESS_FILE", "1"))
|
65
|
+
LLM_ALLOW_ACCESS_WEB = to_boolean(os.getenv("ZRB_LLM_ACCESS_WEB", "1"))
|
66
|
+
RAG_EMBEDDING_MODEL = os.getenv("ZRB_RAG_EMBEDDING_MODEL", "ollama/nomic-embed-text")
|
67
|
+
RAG_CHUNK_SIZE = int(os.getenv("ZRB_RAG_CHUNK_SIZE", "1024"))
|
68
|
+
RAG_OVERLAP = int(os.getenv("ZRB_RAG_OVERLAP", "128"))
|
69
|
+
RAG_MAX_RESULT_COUNT = int(os.getenv("ZRB_RAG_MAX_RESULT_COUNT", "5"))
|
70
|
+
|
61
71
|
|
62
72
|
BANNER = f"""
|
63
73
|
bb
|
zrb/runner/cli.py
CHANGED
@@ -5,7 +5,7 @@ from zrb.config import BANNER, WEB_HTTP_PORT
|
|
5
5
|
from zrb.context.any_context import AnyContext
|
6
6
|
from zrb.context.shared_context import SharedContext
|
7
7
|
from zrb.group.group import Group
|
8
|
-
from zrb.runner.
|
8
|
+
from zrb.runner.web_app import create_app
|
9
9
|
from zrb.session.session import Session
|
10
10
|
from zrb.task.any_task import AnyTask
|
11
11
|
from zrb.task.make_task import make_task
|
@@ -57,7 +57,7 @@ class Cli(Group):
|
|
57
57
|
return " ".join(parts)
|
58
58
|
|
59
59
|
def _get_run_command_param(self, key: str, val: str) -> str:
|
60
|
-
if '"' in val or "'" in val or " " in val:
|
60
|
+
if '"' in val or "'" in val or " " in val or val == "":
|
61
61
|
return f"--{key} {double_quote(val)}"
|
62
62
|
return f"--{key} {val}"
|
63
63
|
|
@@ -71,10 +71,7 @@ class Cli(Group):
|
|
71
71
|
shared_ctx, run_kwargs[task_input.name]
|
72
72
|
)
|
73
73
|
continue
|
74
|
-
|
75
|
-
return task.run(Session(shared_ctx=shared_ctx, root_group=self))
|
76
|
-
except KeyboardInterrupt:
|
77
|
-
pass
|
74
|
+
return task.run(Session(shared_ctx=shared_ctx, root_group=self))
|
78
75
|
|
79
76
|
def _get_run_kwargs(
|
80
77
|
self, task: AnyTask, args: list[str], kwargs: dict[str, str]
|
@@ -182,5 +179,9 @@ server_group = cli.add_group(
|
|
182
179
|
alias="start",
|
183
180
|
)
|
184
181
|
async def run(_: AnyContext):
|
182
|
+
from uvicorn import Config, Server
|
183
|
+
|
185
184
|
app = create_app(cli, WEB_HTTP_PORT)
|
186
|
-
|
185
|
+
config = Config(app=app, host="0.0.0.0", port=WEB_HTTP_PORT, loop="asyncio")
|
186
|
+
server = Server(config)
|
187
|
+
await server.serve()
|
@@ -1,21 +1,15 @@
|
|
1
1
|
import asyncio
|
2
2
|
import os
|
3
3
|
import sys
|
4
|
-
from contextlib import asynccontextmanager
|
5
4
|
from datetime import datetime, timedelta
|
6
5
|
from typing import Any, Dict, List
|
7
6
|
|
8
|
-
from fastapi import FastAPI, HTTPException, Request
|
9
|
-
from fastapi.responses import FileResponse, HTMLResponse
|
10
|
-
from fastapi.staticfiles import StaticFiles
|
11
|
-
from uvicorn import Config, Server
|
12
|
-
|
13
7
|
from zrb.config import BANNER, WEB_HTTP_PORT
|
14
8
|
from zrb.context.shared_context import SharedContext
|
15
9
|
from zrb.group.any_group import AnyGroup
|
16
|
-
from zrb.runner.
|
17
|
-
from zrb.runner.
|
18
|
-
from zrb.runner.
|
10
|
+
from zrb.runner.web_controller.group_info_ui.controller import handle_group_info_ui
|
11
|
+
from zrb.runner.web_controller.home_page.controller import handle_home_page
|
12
|
+
from zrb.runner.web_controller.task_ui.controller import handle_task_ui
|
19
13
|
from zrb.runner.web_util import NewSessionResponse
|
20
14
|
from zrb.session.session import Session
|
21
15
|
from zrb.session_state_log.session_state_log import SessionStateLog, SessionStateLogList
|
@@ -27,6 +21,12 @@ from zrb.util.group import extract_node_from_args, get_node_path
|
|
27
21
|
|
28
22
|
|
29
23
|
def create_app(root_group: AnyGroup, port: int = WEB_HTTP_PORT):
|
24
|
+
from contextlib import asynccontextmanager
|
25
|
+
|
26
|
+
from fastapi import FastAPI, HTTPException, Request
|
27
|
+
from fastapi.responses import FileResponse, HTMLResponse
|
28
|
+
from fastapi.staticfiles import StaticFiles
|
29
|
+
|
30
30
|
_STATIC_DIR = os.path.join(os.path.dirname(__file__), "web_app", "static")
|
31
31
|
_COROS = []
|
32
32
|
|
@@ -144,7 +144,7 @@ def create_app(root_group: AnyGroup, port: int = WEB_HTTP_PORT):
|
|
144
144
|
return app
|
145
145
|
|
146
146
|
|
147
|
-
async def run_web_server(app: FastAPI, port: int = WEB_HTTP_PORT):
|
148
|
-
|
149
|
-
|
150
|
-
|
147
|
+
# async def run_web_server(app: FastAPI, port: int = WEB_HTTP_PORT):
|
148
|
+
# config = Config(app=app, host="0.0.0.0", port=port, loop="asyncio")
|
149
|
+
# server = Server(config)
|
150
|
+
# await server.serve()
|
@@ -1,7 +1,5 @@
|
|
1
1
|
import os
|
2
2
|
|
3
|
-
from fastapi.responses import HTMLResponse
|
4
|
-
|
5
3
|
from zrb.group.any_group import AnyGroup
|
6
4
|
from zrb.util.group import get_non_empty_subgroups, get_subtasks
|
7
5
|
from zrb.util.string.format import fstring_format
|
@@ -25,6 +23,8 @@ with open(os.path.join(_DIR, "partial", "task_li.html")) as f:
|
|
25
23
|
|
26
24
|
|
27
25
|
def handle_group_info_ui(root_group: AnyGroup, group: AnyGroup, url: str):
|
26
|
+
from fastapi.responses import HTMLResponse
|
27
|
+
|
28
28
|
url_parts = url.split("/")
|
29
29
|
parent_url_parts = url_parts[:-2] + [""]
|
30
30
|
parent_url = "/".join(parent_url_parts)
|
@@ -1,7 +1,5 @@
|
|
1
1
|
import os
|
2
2
|
|
3
|
-
from fastapi.responses import HTMLResponse
|
4
|
-
|
5
3
|
from zrb.group.any_group import AnyGroup
|
6
4
|
from zrb.util.group import get_non_empty_subgroups, get_subtasks
|
7
5
|
from zrb.util.string.format import fstring_format
|
@@ -25,6 +23,8 @@ with open(os.path.join(_DIR, "partial", "task_li.html")) as f:
|
|
25
23
|
|
26
24
|
|
27
25
|
def handle_home_page(root_group: AnyGroup):
|
26
|
+
from fastapi.responses import HTMLResponse
|
27
|
+
|
28
28
|
subgroups = get_non_empty_subgroups(root_group, web_only=True)
|
29
29
|
group_info = (
|
30
30
|
""
|
@@ -1,7 +1,5 @@
|
|
1
1
|
import os
|
2
2
|
|
3
|
-
from fastapi.responses import HTMLResponse
|
4
|
-
|
5
3
|
from zrb.group.any_group import AnyGroup
|
6
4
|
from zrb.session.any_session import AnySession
|
7
5
|
from zrb.task.any_task import AnyTask
|
@@ -31,6 +29,8 @@ with open(os.path.join(_DIR, "partial", "common-util.js")) as f:
|
|
31
29
|
def handle_task_ui(
|
32
30
|
root_group: AnyGroup, task: AnyTask, session: AnySession, url: str, args: list[str]
|
33
31
|
):
|
32
|
+
from fastapi.responses import HTMLResponse
|
33
|
+
|
34
34
|
session.register_task(task)
|
35
35
|
ctx = task.get_ctx(session)
|
36
36
|
url_parts = url.split("/")
|
zrb/task/cmd_task.py
CHANGED
@@ -26,22 +26,22 @@ class CmdTask(BaseTask):
|
|
26
26
|
input: list[AnyInput | None] | AnyInput | None = None,
|
27
27
|
env: list[AnyEnv | None] | AnyEnv | None = None,
|
28
28
|
shell: StrAttr | None = None,
|
29
|
-
|
29
|
+
render_shell: bool = True,
|
30
30
|
shell_flag: StrAttr | None = None,
|
31
|
-
|
31
|
+
render_shell_flag: bool = True,
|
32
32
|
remote_host: StrAttr | None = None,
|
33
|
-
|
33
|
+
render_remote_host: bool = True,
|
34
34
|
remote_port: IntAttr | None = None,
|
35
35
|
remote_user: StrAttr | None = None,
|
36
|
-
|
36
|
+
render_remote_user: bool = True,
|
37
37
|
remote_password: StrAttr | None = None,
|
38
|
-
|
38
|
+
render_remote_password: bool = True,
|
39
39
|
remote_ssh_key: StrAttr | None = None,
|
40
|
-
|
40
|
+
render_remote_ssh_key: bool = True,
|
41
41
|
cmd: CmdVal = "",
|
42
|
-
|
42
|
+
render_cmd: bool = True,
|
43
43
|
cwd: str | None = None,
|
44
|
-
|
44
|
+
render_cwd: bool = True,
|
45
45
|
max_output_line: int = 1000,
|
46
46
|
max_error_line: int = 1000,
|
47
47
|
execute_condition: BoolAttr = True,
|
@@ -77,22 +77,22 @@ class CmdTask(BaseTask):
|
|
77
77
|
fallback=fallback,
|
78
78
|
)
|
79
79
|
self._shell = shell
|
80
|
-
self.
|
80
|
+
self._render_shell = render_shell
|
81
81
|
self._shell_flag = shell_flag
|
82
|
-
self.
|
82
|
+
self._render_shell_flag = render_shell_flag
|
83
83
|
self._remote_host = remote_host
|
84
|
-
self.
|
84
|
+
self._render_remote_host = render_remote_host
|
85
85
|
self._remote_port = remote_port
|
86
86
|
self._remote_user = remote_user
|
87
|
-
self.
|
87
|
+
self._render_remote_user = render_remote_user
|
88
88
|
self._remote_password = remote_password
|
89
|
-
self.
|
89
|
+
self._render_remote_password = render_remote_password
|
90
90
|
self._remote_ssh_key = remote_ssh_key
|
91
|
-
self.
|
91
|
+
self._render_remote_ssh_key = render_remote_ssh_key
|
92
92
|
self._cmd = cmd
|
93
|
-
self.
|
93
|
+
self._render_cmd = render_cmd
|
94
94
|
self._cwd = cwd
|
95
|
-
self.
|
95
|
+
self._render_cwd = render_cwd
|
96
96
|
self._max_output_line = max_output_line
|
97
97
|
self._max_error_line = max_error_line
|
98
98
|
|
@@ -171,7 +171,7 @@ class CmdTask(BaseTask):
|
|
171
171
|
|
172
172
|
def _get_shell(self, ctx: AnyContext) -> str:
|
173
173
|
return get_str_attr(
|
174
|
-
ctx, self._shell, DEFAULT_SHELL, auto_render=self.
|
174
|
+
ctx, self._shell, DEFAULT_SHELL, auto_render=self._render_shell
|
175
175
|
)
|
176
176
|
|
177
177
|
def _get_shell_flag(self, ctx: AnyContext) -> str:
|
@@ -186,12 +186,12 @@ class CmdTask(BaseTask):
|
|
186
186
|
ctx,
|
187
187
|
self._shell_flag,
|
188
188
|
default_shell_flag,
|
189
|
-
auto_render=self.
|
189
|
+
auto_render=self._render_shell_flag,
|
190
190
|
)
|
191
191
|
|
192
192
|
def _get_remote_host(self, ctx: AnyContext) -> str:
|
193
193
|
return get_str_attr(
|
194
|
-
ctx, self._remote_host, "", auto_render=self.
|
194
|
+
ctx, self._remote_host, "", auto_render=self._render_remote_host
|
195
195
|
)
|
196
196
|
|
197
197
|
def _get_remote_port(self, ctx: AnyContext) -> int:
|
@@ -199,7 +199,7 @@ class CmdTask(BaseTask):
|
|
199
199
|
|
200
200
|
def _get_remote_user(self, ctx: AnyContext) -> str:
|
201
201
|
return get_str_attr(
|
202
|
-
ctx, self._remote_user, "", auto_render=self.
|
202
|
+
ctx, self._remote_user, "", auto_render=self._render_remote_user
|
203
203
|
)
|
204
204
|
|
205
205
|
def _get_remote_password(self, ctx: AnyContext) -> str:
|
@@ -207,18 +207,16 @@ class CmdTask(BaseTask):
|
|
207
207
|
ctx,
|
208
208
|
self._remote_password,
|
209
209
|
"",
|
210
|
-
auto_render=self.
|
210
|
+
auto_render=self._render_remote_password,
|
211
211
|
)
|
212
212
|
|
213
213
|
def _get_remote_ssh_key(self, ctx: AnyContext) -> str:
|
214
214
|
return get_str_attr(
|
215
|
-
ctx, self._remote_ssh_key, "", auto_render=self.
|
215
|
+
ctx, self._remote_ssh_key, "", auto_render=self._render_remote_ssh_key
|
216
216
|
)
|
217
217
|
|
218
218
|
def _get_cwd(self, ctx: AnyContext) -> str:
|
219
|
-
cwd = get_str_attr(
|
220
|
-
ctx, self._cwd, os.getcwd(), auto_render=self._auto_render_cwd
|
221
|
-
)
|
219
|
+
cwd = get_str_attr(ctx, self._cwd, os.getcwd(), auto_render=self._render_cwd)
|
222
220
|
if cwd is None:
|
223
221
|
cwd = os.getcwd()
|
224
222
|
return os.path.abspath(cwd)
|
@@ -258,7 +256,7 @@ class CmdTask(BaseTask):
|
|
258
256
|
if callable(single_cmd_val):
|
259
257
|
return single_cmd_val(ctx)
|
260
258
|
if isinstance(single_cmd_val, str):
|
261
|
-
if self.
|
259
|
+
if self._render_cmd:
|
262
260
|
return ctx.render(single_cmd_val)
|
263
261
|
return single_cmd_val
|
264
262
|
if isinstance(single_cmd_val, AnyCmdVal):
|
zrb/task/http_check.py
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
import asyncio
|
2
2
|
from collections.abc import Callable
|
3
3
|
|
4
|
-
import requests
|
5
|
-
|
6
4
|
from zrb.attr.type import StrAttr
|
7
5
|
from zrb.context.any_context import AnyContext
|
8
6
|
from zrb.context.context import Context
|
@@ -24,7 +22,7 @@ class HttpCheck(BaseTask):
|
|
24
22
|
input: list[AnyInput] | AnyInput | None = None,
|
25
23
|
env: list[AnyEnv] | AnyEnv | None = None,
|
26
24
|
url: StrAttr = "http://localhost",
|
27
|
-
|
25
|
+
render_url: bool = True,
|
28
26
|
http_method: StrAttr = "GET",
|
29
27
|
interval: int = 5,
|
30
28
|
execute_condition: bool | str | Callable[[Context], bool] = True,
|
@@ -45,19 +43,21 @@ class HttpCheck(BaseTask):
|
|
45
43
|
fallback=fallback,
|
46
44
|
)
|
47
45
|
self._url = url
|
48
|
-
self.
|
46
|
+
self._render_url = render_url
|
49
47
|
self._http_method = http_method
|
50
48
|
self._interval = interval
|
51
49
|
|
52
50
|
def _get_url(self, ctx: AnyContext) -> str:
|
53
51
|
return get_str_attr(
|
54
|
-
ctx, self._url, "http://localhost", auto_render=self.
|
52
|
+
ctx, self._url, "http://localhost", auto_render=self._render_url
|
55
53
|
)
|
56
54
|
|
57
55
|
def _get_http_method(self, ctx: AnyContext) -> str:
|
58
56
|
return get_str_attr(ctx, self._http_method, "GET", auto_render=True).upper()
|
59
57
|
|
60
58
|
async def _exec_action(self, ctx: AnyContext) -> bool:
|
59
|
+
import requests
|
60
|
+
|
61
61
|
url = self._get_url(ctx)
|
62
62
|
http_method = self._get_http_method(ctx)
|
63
63
|
while True:
|