zrb 1.0.0a2__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 +49 -40
- zrb/__main__.py +5 -3
- zrb/attr/type.py +2 -1
- zrb/builtin/__init__.py +42 -2
- zrb/builtin/base64.py +34 -0
- zrb/builtin/git.py +156 -0
- zrb/builtin/git_subtree.py +88 -0
- zrb/builtin/group.py +34 -0
- zrb/builtin/llm/llm_chat.py +47 -0
- 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 +36 -0
- zrb/builtin/project/add/fastapp.py +72 -0
- zrb/builtin/project/add/fastapp_template/.gitignore +4 -0
- zrb/builtin/project/add/fastapp_template/README.md +7 -0
- zrb/builtin/project/add/fastapp_template/_zrb/config.py +17 -0
- zrb/builtin/project/add/fastapp_template/_zrb/group.py +16 -0
- zrb/builtin/project/add/fastapp_template/_zrb/helper.py +97 -0
- zrb/builtin/project/add/fastapp_template/_zrb/main.py +132 -0
- zrb/builtin/project/add/fastapp_template/_zrb/venv_task.py +22 -0
- zrb/builtin/project/add/fastapp_template/common/app.py +18 -0
- zrb/builtin/project/add/fastapp_template/common/db_engine.py +5 -0
- zrb/builtin/project/add/fastapp_template/common/db_repository.py +134 -0
- zrb/builtin/project/add/fastapp_template/common/error.py +8 -0
- zrb/builtin/project/add/fastapp_template/common/schema.py +5 -0
- zrb/builtin/project/add/fastapp_template/common/usecase.py +232 -0
- zrb/builtin/project/add/fastapp_template/config.py +29 -0
- zrb/builtin/project/add/fastapp_template/main.py +7 -0
- zrb/builtin/project/add/fastapp_template/migrate.py +3 -0
- zrb/builtin/project/add/fastapp_template/module/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/module/auth/alembic.ini +117 -0
- zrb/builtin/project/add/fastapp_template/module/auth/client/api_client.py +7 -0
- zrb/builtin/project/add/fastapp_template/module/auth/client/base_client.py +27 -0
- zrb/builtin/project/add/fastapp_template/module/auth/client/direct_client.py +6 -0
- zrb/builtin/project/add/fastapp_template/module/auth/client/factory.py +9 -0
- zrb/builtin/project/add/fastapp_template/module/auth/migration/README +1 -0
- zrb/builtin/project/add/fastapp_template/module/auth/migration/env.py +108 -0
- zrb/builtin/project/add/fastapp_template/module/auth/migration/script.py.mako +26 -0
- zrb/builtin/project/add/fastapp_template/module/auth/migration/versions/3093c7336477_add_user_table.py +37 -0
- zrb/builtin/project/add/fastapp_template/module/auth/migration_metadata.py +6 -0
- zrb/builtin/project/add/fastapp_template/module/auth/route.py +22 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/db_repository.py +39 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/factory.py +13 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/repository/repository.py +34 -0
- zrb/builtin/project/add/fastapp_template/module/auth/service/user/usecase.py +45 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/alembic.ini +117 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/migration/README +1 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/migration/env.py +108 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/migration/script.py.mako +26 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/migration/versions/.gitkeep +0 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/migration_metadata.py +3 -0
- zrb/builtin/project/add/fastapp_template/module/gateway/route.py +27 -0
- zrb/builtin/project/add/fastapp_template/requirements.txt +6 -0
- zrb/builtin/project/add/fastapp_template/schema/__init__.py +0 -0
- zrb/builtin/project/add/fastapp_template/schema/role.py +31 -0
- zrb/builtin/project/add/fastapp_template/schema/user.py +31 -0
- zrb/builtin/project/add/fastapp_template/template.env +2 -0
- zrb/builtin/project/create/__init__.py +0 -0
- zrb/builtin/project/create/create.py +41 -0
- zrb/builtin/project/create/project-template/README.md +3 -0
- zrb/builtin/project/create/project-template/zrb_init.py +7 -0
- zrb/builtin/python.py +11 -0
- zrb/builtin/shell/__init__.py +0 -5
- zrb/builtin/shell/autocomplete/__init__.py +0 -9
- zrb/builtin/shell/autocomplete/bash.py +5 -6
- zrb/builtin/shell/autocomplete/subcmd.py +7 -8
- zrb/builtin/shell/autocomplete/zsh.py +5 -6
- zrb/builtin/todo.py +219 -0
- zrb/callback/any_callback.py +1 -1
- zrb/callback/callback.py +5 -5
- zrb/cmd/cmd_val.py +2 -2
- zrb/config.py +16 -3
- zrb/content_transformer/any_content_transformer.py +1 -1
- zrb/content_transformer/content_transformer.py +2 -2
- zrb/context/any_context.py +1 -1
- zrb/context/any_shared_context.py +3 -3
- zrb/context/context.py +10 -8
- zrb/context/shared_context.py +9 -8
- zrb/env/__init__.py +0 -3
- zrb/env/any_env.py +1 -1
- zrb/env/env.py +3 -4
- zrb/env/env_file.py +4 -4
- zrb/env/env_map.py +2 -2
- zrb/group/__init__.py +0 -3
- zrb/group/any_group.py +3 -3
- zrb/group/group.py +7 -6
- zrb/input/any_input.py +1 -1
- zrb/input/base_input.py +4 -4
- zrb/input/bool_input.py +5 -5
- zrb/input/float_input.py +3 -3
- zrb/input/int_input.py +3 -3
- zrb/input/option_input.py +51 -0
- zrb/input/password_input.py +2 -2
- zrb/input/str_input.py +1 -1
- zrb/input/text_input.py +12 -10
- zrb/runner/cli.py +80 -45
- zrb/runner/web_app.py +150 -0
- zrb/runner/web_controller/__init__.py +0 -0
- zrb/runner/web_controller/group_info_ui/__init__.py +0 -0
- zrb/runner/{web_app → web_controller}/group_info_ui/controller.py +7 -8
- zrb/runner/{web_app → web_controller}/group_info_ui/view.html +2 -2
- zrb/runner/web_controller/home_page/__init__.py +0 -0
- zrb/runner/{web_app → web_controller}/home_page/controller.py +7 -6
- zrb/runner/{web_app → web_controller}/home_page/view.html +2 -2
- zrb/runner/web_controller/task_ui/__init__.py +0 -0
- zrb/runner/{web_app → web_controller}/task_ui/controller.py +8 -12
- zrb/runner/{web_app → web_controller}/task_ui/view.html +2 -2
- zrb/runner/web_util.py +5 -35
- zrb/session/any_session.py +13 -7
- zrb/session/session.py +78 -40
- zrb/session_state_log/session_state_log.py +7 -5
- zrb/session_state_logger/any_session_state_logger.py +1 -1
- zrb/session_state_logger/default_session_state_logger.py +2 -2
- zrb/session_state_logger/file_session_state_logger.py +19 -27
- zrb/task/any_task.py +4 -4
- zrb/task/base_task.py +33 -23
- zrb/task/base_trigger.py +11 -12
- zrb/task/cmd_task.py +72 -65
- zrb/task/http_check.py +13 -13
- zrb/task/llm_task.py +215 -0
- zrb/task/make_task.py +9 -9
- zrb/task/rsync_task.py +25 -25
- zrb/task/scaffolder.py +18 -15
- zrb/task/scheduler.py +6 -7
- zrb/task/task.py +1 -1
- zrb/task/tcp_check.py +11 -13
- zrb/util/attr.py +19 -3
- zrb/util/cli/style.py +71 -2
- zrb/util/cli/subcommand.py +2 -2
- zrb/util/codemod/__init__.py +0 -0
- zrb/util/codemod/add_code_to_class.py +35 -0
- zrb/util/codemod/add_code_to_function.py +36 -0
- zrb/util/codemod/add_code_to_method.py +55 -0
- zrb/util/codemod/add_key_to_dict.py +51 -0
- zrb/util/codemod/add_param_to_function_call.py +39 -0
- zrb/util/codemod/add_property_to_class.py +55 -0
- zrb/util/git.py +156 -0
- zrb/util/git_subtree.py +94 -0
- zrb/util/group.py +2 -2
- zrb/util/llm/tool.py +63 -0
- zrb/util/string/conversion.py +7 -0
- zrb/util/todo.py +259 -0
- {zrb-1.0.0a2.dist-info → zrb-1.0.0a4.dist-info}/METADATA +13 -5
- zrb-1.0.0a4.dist-info/RECORD +197 -0
- zrb/builtin/shell/_group.py +0 -9
- zrb/builtin/shell/autocomplete/_group.py +0 -6
- zrb/runner/web_app/any_request_handler.py +0 -24
- zrb/runner/web_server.py +0 -224
- zrb-1.0.0a2.dist-info/RECORD +0 -120
- /zrb/{runner/web_app → builtin/project}/__init__.py +0 -0
- /zrb/{runner/web_app/group_info_ui → builtin/project/add}/__init__.py +0 -0
- /zrb/{runner/web_app/home_page → builtin/project/add/fastapp_template}/__init__.py +0 -0
- /zrb/{runner/web_app/task_ui → builtin/project/add/fastapp_template/common}/__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}/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}/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/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-1.0.0a2.dist-info → zrb-1.0.0a4.dist-info}/WHEEL +0 -0
- {zrb-1.0.0a2.dist-info → zrb-1.0.0a4.dist-info}/entry_points.txt +0 -0
@@ -4,8 +4,8 @@
|
|
4
4
|
<meta charset="utf-8">
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
6
6
|
<meta name="color-scheme" content="light dark">
|
7
|
-
<link rel="stylesheet" href="/pico.min.css">
|
8
|
-
<link rel="icon" href="/favicon-32x32.png" sizes="32x32" type="image/png">
|
7
|
+
<link rel="stylesheet" href="/static/pico.min.css">
|
8
|
+
<link rel="icon" href="/static/favicon-32x32.png" sizes="32x32" type="image/png">
|
9
9
|
<title>Zrb</title>
|
10
10
|
</head>
|
11
11
|
<body>
|
File without changes
|
@@ -1,10 +1,9 @@
|
|
1
1
|
import os
|
2
2
|
|
3
|
-
from
|
4
|
-
from
|
5
|
-
from
|
6
|
-
from
|
7
|
-
from ..any_request_handler import AnyRequestHandler
|
3
|
+
from zrb.group.any_group import AnyGroup
|
4
|
+
from zrb.session.any_session import AnySession
|
5
|
+
from zrb.task.any_task import AnyTask
|
6
|
+
from zrb.util.string.format import fstring_format
|
8
7
|
|
9
8
|
_DIR = os.path.dirname(__file__)
|
10
9
|
|
@@ -28,13 +27,10 @@ with open(os.path.join(_DIR, "partial", "common-util.js")) as f:
|
|
28
27
|
|
29
28
|
|
30
29
|
def handle_task_ui(
|
31
|
-
|
32
|
-
root_group: AnyGroup,
|
33
|
-
task: AnyTask,
|
34
|
-
session: AnySession,
|
35
|
-
url: str,
|
36
|
-
args: list[str],
|
30
|
+
root_group: AnyGroup, task: AnyTask, session: AnySession, url: str, args: list[str]
|
37
31
|
):
|
32
|
+
from fastapi.responses import HTMLResponse
|
33
|
+
|
38
34
|
session.register_task(task)
|
39
35
|
ctx = task.get_ctx(session)
|
40
36
|
url_parts = url.split("/")
|
@@ -56,7 +52,7 @@ def handle_task_ui(
|
|
56
52
|
]
|
57
53
|
)
|
58
54
|
session_name = args[0] if len(args) > 0 else ""
|
59
|
-
|
55
|
+
return HTMLResponse(
|
60
56
|
fstring_format(
|
61
57
|
_VIEW_TEMPLATE,
|
62
58
|
{
|
@@ -4,8 +4,8 @@
|
|
4
4
|
<meta charset="utf-8">
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
6
6
|
<meta name="color-scheme" content="light dark">
|
7
|
-
<link rel="stylesheet" href="/pico.min.css">
|
8
|
-
<link rel="icon" href="/favicon-32x32.png" sizes="32x32" type="image/png">
|
7
|
+
<link rel="stylesheet" href="/static/pico.min.css">
|
8
|
+
<link rel="icon" href="/static/favicon-32x32.png" sizes="32x32" type="image/png">
|
9
9
|
<title>Zrb</title>
|
10
10
|
</head>
|
11
11
|
<body>
|
zrb/runner/web_util.py
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
import
|
1
|
+
from pydantic import BaseModel
|
2
|
+
|
3
|
+
|
4
|
+
class NewSessionResponse(BaseModel):
|
5
|
+
session_name: str
|
2
6
|
|
3
7
|
|
4
8
|
def url_to_args(url: str) -> list[str]:
|
@@ -10,37 +14,3 @@ def node_path_to_url(args: list[str]) -> str:
|
|
10
14
|
pruned_args = [part for part in args if part.strip() != ""]
|
11
15
|
stripped_url = "/".join(pruned_args)
|
12
16
|
return f"/{stripped_url}/"
|
13
|
-
|
14
|
-
|
15
|
-
class SessionSnapshotCondition:
|
16
|
-
def __init__(self):
|
17
|
-
self._should_stop = False
|
18
|
-
|
19
|
-
@property
|
20
|
-
def should_stop(self) -> bool:
|
21
|
-
return self._should_stop
|
22
|
-
|
23
|
-
def stop(self):
|
24
|
-
self._should_stop = True
|
25
|
-
|
26
|
-
|
27
|
-
def start_event_loop(event_loop: asyncio.AbstractEventLoop):
|
28
|
-
asyncio.set_event_loop(event_loop)
|
29
|
-
event_loop.run_forever()
|
30
|
-
|
31
|
-
|
32
|
-
async def shutdown_event_loop(event_loop: asyncio.AbstractEventLoop):
|
33
|
-
tasks = [
|
34
|
-
t
|
35
|
-
for t in asyncio.all_tasks(event_loop)
|
36
|
-
if not t.done() and t is not asyncio.current_task(event_loop)
|
37
|
-
]
|
38
|
-
print("TASKS", tasks)
|
39
|
-
for task in tasks:
|
40
|
-
print("CANCEL TASK", task)
|
41
|
-
task.cancel()
|
42
|
-
print("CANCELED", task)
|
43
|
-
await asyncio.gather(*tasks, return_exceptions=True)
|
44
|
-
print("DONE")
|
45
|
-
event_loop.stop()
|
46
|
-
print("LOOP STOP")
|
zrb/session/any_session.py
CHANGED
@@ -3,15 +3,15 @@ from __future__ import annotations # Enables forward references
|
|
3
3
|
from abc import ABC, abstractmethod
|
4
4
|
from typing import TYPE_CHECKING, Any, Coroutine, TypeVar
|
5
5
|
|
6
|
-
from
|
7
|
-
from
|
8
|
-
from
|
9
|
-
from
|
10
|
-
from
|
6
|
+
from zrb.context.any_context import AnyContext
|
7
|
+
from zrb.group.any_group import AnyGroup
|
8
|
+
from zrb.session_state_log.session_state_log import SessionStateLog
|
9
|
+
from zrb.session_state_logger.any_session_state_logger import AnySessionStateLogger
|
10
|
+
from zrb.task_status.task_status import TaskStatus
|
11
11
|
|
12
12
|
if TYPE_CHECKING:
|
13
|
-
from
|
14
|
-
from
|
13
|
+
from zrb.context import any_shared_context
|
14
|
+
from zrb.task import any_task
|
15
15
|
|
16
16
|
TAnySession = TypeVar("TAnySession", bound="AnySession")
|
17
17
|
|
@@ -36,6 +36,12 @@ class AnySession(ABC):
|
|
36
36
|
"""Session root group"""
|
37
37
|
pass
|
38
38
|
|
39
|
+
@property
|
40
|
+
@abstractmethod
|
41
|
+
def task_names(self) -> list[str]:
|
42
|
+
"""Task names in this session"""
|
43
|
+
pass
|
44
|
+
|
39
45
|
@property
|
40
46
|
@abstractmethod
|
41
47
|
def shared_ctx(self) -> any_shared_context.AnySharedContext:
|
zrb/session/session.py
CHANGED
@@ -1,21 +1,37 @@
|
|
1
1
|
import asyncio
|
2
2
|
from typing import Any, Coroutine
|
3
3
|
|
4
|
-
from
|
5
|
-
from
|
6
|
-
from
|
7
|
-
from
|
8
|
-
from
|
9
|
-
|
4
|
+
from zrb.context.any_shared_context import AnySharedContext
|
5
|
+
from zrb.context.context import AnyContext, Context
|
6
|
+
from zrb.group.any_group import AnyGroup
|
7
|
+
from zrb.session.any_session import AnySession
|
8
|
+
from zrb.session_state_log.session_state_log import (
|
9
|
+
SessionStateLog,
|
10
|
+
TaskStatusHistoryStateLog,
|
11
|
+
TaskStatusStateLog,
|
12
|
+
)
|
13
|
+
from zrb.session_state_logger.any_session_state_logger import AnySessionStateLogger
|
14
|
+
from zrb.session_state_logger.default_session_state_logger import (
|
10
15
|
default_session_state_logger,
|
11
16
|
)
|
12
|
-
from
|
13
|
-
from
|
14
|
-
from
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
from zrb.task.any_task import AnyTask
|
18
|
+
from zrb.task_status.task_status import TaskStatus
|
19
|
+
from zrb.util.cli.style import (
|
20
|
+
BLUE,
|
21
|
+
BRIGHT_BLUE,
|
22
|
+
BRIGHT_CYAN,
|
23
|
+
BRIGHT_GREEN,
|
24
|
+
BRIGHT_MAGENTA,
|
25
|
+
BRIGHT_YELLOW,
|
26
|
+
CYAN,
|
27
|
+
GREEN,
|
28
|
+
ICONS,
|
29
|
+
MAGENTA,
|
30
|
+
YELLOW,
|
31
|
+
)
|
32
|
+
from zrb.util.group import get_node_path
|
33
|
+
from zrb.util.string.name import get_random_name
|
34
|
+
from zrb.xcom.xcom import Xcom
|
19
35
|
|
20
36
|
|
21
37
|
class Session(AnySession):
|
@@ -39,7 +55,18 @@ class Session(AnySession):
|
|
39
55
|
self._action_coros: dict[AnyTask, Coroutine] = {}
|
40
56
|
self._monitoring_coros: dict[AnyTask, Coroutine] = {}
|
41
57
|
self._coros: list[Coroutine] = []
|
42
|
-
self._colors = [
|
58
|
+
self._colors = [
|
59
|
+
GREEN,
|
60
|
+
YELLOW,
|
61
|
+
BLUE,
|
62
|
+
MAGENTA,
|
63
|
+
CYAN,
|
64
|
+
BRIGHT_GREEN,
|
65
|
+
BRIGHT_YELLOW,
|
66
|
+
BRIGHT_BLUE,
|
67
|
+
BRIGHT_MAGENTA,
|
68
|
+
BRIGHT_CYAN,
|
69
|
+
]
|
43
70
|
self._icons = ICONS
|
44
71
|
self._color_index = 0
|
45
72
|
self._icon_index = 0
|
@@ -62,6 +89,10 @@ class Session(AnySession):
|
|
62
89
|
def root_group(self) -> AnyGroup | None:
|
63
90
|
return self._root_group
|
64
91
|
|
92
|
+
@property
|
93
|
+
def task_names(self) -> list[str]:
|
94
|
+
return [task.name for task in self._task_status.keys()]
|
95
|
+
|
65
96
|
@property
|
66
97
|
def shared_ctx(self) -> AnySharedContext:
|
67
98
|
return self._shared_ctx
|
@@ -105,35 +136,42 @@ class Session(AnySession):
|
|
105
136
|
|
106
137
|
def as_state_log(self) -> SessionStateLog:
|
107
138
|
task_status_log: dict[str, TaskStatusStateLog] = {}
|
139
|
+
log_start_time = ""
|
108
140
|
for task, task_status in self._task_status.items():
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
"
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
141
|
+
history_log = [
|
142
|
+
TaskStatusHistoryStateLog(
|
143
|
+
status=status,
|
144
|
+
time=status_at.strftime("%Y-%m-%d %H:%M:%S.%f"),
|
145
|
+
)
|
146
|
+
for status, status_at in task_status.history
|
147
|
+
]
|
148
|
+
if len(history_log) > 0 and (
|
149
|
+
log_start_time == "" or history_log[0].time < log_start_time
|
150
|
+
):
|
151
|
+
log_start_time = history_log[0].time
|
152
|
+
task_status_log[task.name] = TaskStatusStateLog(
|
153
|
+
is_started=task_status.is_started,
|
154
|
+
is_ready=task_status.is_ready,
|
155
|
+
is_completed=task_status.is_completed,
|
156
|
+
is_skipped=task_status.is_skipped,
|
157
|
+
is_failed=task_status.is_failed,
|
158
|
+
is_permanently_failed=task_status.is_permanently_failed,
|
159
|
+
is_terminated=task_status.is_terminated,
|
160
|
+
history=history_log,
|
161
|
+
)
|
162
|
+
return SessionStateLog(
|
163
|
+
name=self.name,
|
164
|
+
start_time=log_start_time,
|
165
|
+
main_task_name=self._main_task.name,
|
166
|
+
path=self.task_path,
|
167
|
+
final_result=(
|
130
168
|
f"{self.final_result}" if self.final_result is not None else ""
|
131
169
|
),
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
170
|
+
finished=self.is_terminated,
|
171
|
+
log=self.shared_ctx.shared_log,
|
172
|
+
input=self.shared_ctx.input,
|
173
|
+
task_status=task_status_log,
|
174
|
+
)
|
137
175
|
|
138
176
|
def get_ctx(self, task: AnyTask) -> AnyContext:
|
139
177
|
self._register_single_task(task)
|
@@ -1,12 +1,14 @@
|
|
1
|
-
from typing import Any
|
1
|
+
from typing import Any
|
2
2
|
|
3
|
+
from pydantic import BaseModel
|
3
4
|
|
4
|
-
|
5
|
+
|
6
|
+
class TaskStatusHistoryStateLog(BaseModel):
|
5
7
|
status: str
|
6
8
|
time: str
|
7
9
|
|
8
10
|
|
9
|
-
class TaskStatusStateLog(
|
11
|
+
class TaskStatusStateLog(BaseModel):
|
10
12
|
history: list[TaskStatusHistoryStateLog]
|
11
13
|
is_started: bool
|
12
14
|
is_ready: bool
|
@@ -17,7 +19,7 @@ class TaskStatusStateLog(TypedDict):
|
|
17
19
|
is_terminated: bool
|
18
20
|
|
19
21
|
|
20
|
-
class SessionStateLog(
|
22
|
+
class SessionStateLog(BaseModel):
|
21
23
|
name: str
|
22
24
|
start_time: str
|
23
25
|
main_task_name: str
|
@@ -29,6 +31,6 @@ class SessionStateLog(TypedDict):
|
|
29
31
|
task_status: dict[str, TaskStatusStateLog]
|
30
32
|
|
31
33
|
|
32
|
-
class SessionStateLogList(
|
34
|
+
class SessionStateLogList(BaseModel):
|
33
35
|
total: int
|
34
36
|
data: list[SessionStateLog]
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import datetime
|
2
2
|
from abc import ABC, abstractmethod
|
3
3
|
|
4
|
-
from
|
4
|
+
from zrb.session_state_log.session_state_log import SessionStateLog, SessionStateLogList
|
5
5
|
|
6
6
|
|
7
7
|
class AnySessionStateLogger(ABC):
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from
|
2
|
-
from .file_session_state_logger import FileSessionStateLogger
|
1
|
+
from zrb.config import SESSION_LOG_DIR
|
2
|
+
from zrb.session_state_logger.file_session_state_logger import FileSessionStateLogger
|
3
3
|
|
4
4
|
default_session_state_logger = FileSessionStateLogger(SESSION_LOG_DIR)
|
@@ -1,9 +1,8 @@
|
|
1
1
|
import datetime
|
2
|
-
import json
|
3
2
|
import os
|
4
3
|
|
5
|
-
from
|
6
|
-
from .any_session_state_logger import AnySessionStateLogger
|
4
|
+
from zrb.session_state_log.session_state_log import SessionStateLog, SessionStateLogList
|
5
|
+
from zrb.session_state_logger.any_session_state_logger import AnySessionStateLogger
|
7
6
|
|
8
7
|
|
9
8
|
class FileSessionStateLogger(AnySessionStateLogger):
|
@@ -12,21 +11,24 @@ class FileSessionStateLogger(AnySessionStateLogger):
|
|
12
11
|
self._session_log_dir = session_log_dir
|
13
12
|
|
14
13
|
def write(self, session_log: SessionStateLog):
|
15
|
-
session_file_path = self._get_session_file_path(session_log
|
14
|
+
session_file_path = self._get_session_file_path(session_log.name)
|
15
|
+
session_dir_path = os.path.dirname(session_file_path)
|
16
|
+
if not os.path.isdir(session_dir_path):
|
17
|
+
os.makedirs(session_dir_path, exist_ok=True)
|
16
18
|
with open(session_file_path, "w") as f:
|
17
|
-
f.write(
|
18
|
-
start_time =
|
19
|
-
if start_time
|
19
|
+
f.write(session_log.model_dump_json())
|
20
|
+
start_time = session_log.start_time
|
21
|
+
if start_time == "":
|
20
22
|
return
|
21
|
-
timeline_dir_path = self._get_timeline_dir_path(session_log
|
23
|
+
timeline_dir_path = self._get_timeline_dir_path(session_log)
|
22
24
|
os.makedirs(timeline_dir_path, exist_ok=True)
|
23
|
-
with open(os.path.join(timeline_dir_path, session_log
|
25
|
+
with open(os.path.join(timeline_dir_path, session_log.name), "w"):
|
24
26
|
pass
|
25
27
|
|
26
28
|
def read(self, session_name: str) -> SessionStateLog:
|
27
29
|
session_file_path = self._get_session_file_path(session_name)
|
28
30
|
with open(session_file_path, "r") as f:
|
29
|
-
return
|
31
|
+
return SessionStateLog.model_validate_json(f.read())
|
30
32
|
|
31
33
|
def list(
|
32
34
|
self,
|
@@ -59,21 +61,20 @@ class FileSessionStateLogger(AnySessionStateLogger):
|
|
59
61
|
paginated_sessions = matching_sessions[start_index:end_index]
|
60
62
|
# Extract session logs from the sorted list of tuples
|
61
63
|
data = [session_log for _, session_log in paginated_sessions]
|
62
|
-
return
|
64
|
+
return SessionStateLogList(total=total, data=data)
|
63
65
|
|
64
66
|
def _get_session_file_path(self, session_name: str) -> str:
|
65
67
|
return os.path.join(self._session_log_dir, f"{session_name}.json")
|
66
68
|
|
67
|
-
def _get_timeline_dir_path(
|
68
|
-
|
69
|
-
) -> str:
|
69
|
+
def _get_timeline_dir_path(self, session_log: SessionStateLog) -> str:
|
70
|
+
start_time = self._get_start_time(session_log)
|
70
71
|
year = start_time.year
|
71
72
|
month = start_time.month
|
72
73
|
day = start_time.day
|
73
74
|
hour = start_time.hour
|
74
75
|
minute = start_time.minute
|
75
76
|
second = start_time.second
|
76
|
-
paths = session_log
|
77
|
+
paths = session_log.path + [
|
77
78
|
f"{year}",
|
78
79
|
f"{month}",
|
79
80
|
f"{day}",
|
@@ -84,15 +85,6 @@ class FileSessionStateLogger(AnySessionStateLogger):
|
|
84
85
|
return os.path.join(self._session_log_dir, "_timeline", *paths)
|
85
86
|
|
86
87
|
def _get_start_time(self, session_log: SessionStateLog) -> datetime.datetime:
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
if len(histories) == 0:
|
91
|
-
continue
|
92
|
-
first_history = histories[0]
|
93
|
-
first_time = datetime.datetime.strptime(
|
94
|
-
first_history["time"], "%Y-%m-%d %H:%M:%S.%f"
|
95
|
-
)
|
96
|
-
if result is None or first_time < result:
|
97
|
-
result = first_time
|
98
|
-
return result
|
88
|
+
return datetime.datetime.strptime(
|
89
|
+
session_log.start_time, "%Y-%m-%d %H:%M:%S.%f"
|
90
|
+
)
|
zrb/task/any_task.py
CHANGED
@@ -3,12 +3,12 @@ from __future__ import annotations # Enables forward references
|
|
3
3
|
from abc import ABC, abstractmethod
|
4
4
|
from typing import TYPE_CHECKING, Any
|
5
5
|
|
6
|
-
from
|
7
|
-
from
|
6
|
+
from zrb.env.any_env import AnyEnv
|
7
|
+
from zrb.input.any_input import AnyInput
|
8
8
|
|
9
9
|
if TYPE_CHECKING:
|
10
|
-
from
|
11
|
-
from
|
10
|
+
from zrb.context import any_context
|
11
|
+
from zrb.session import session
|
12
12
|
|
13
13
|
|
14
14
|
class AnyTask(ABC):
|
zrb/task/base_task.py
CHANGED
@@ -3,17 +3,17 @@ import os
|
|
3
3
|
from collections.abc import Callable
|
4
4
|
from typing import Any
|
5
5
|
|
6
|
-
from
|
7
|
-
from
|
8
|
-
from
|
9
|
-
from
|
10
|
-
from
|
11
|
-
from
|
12
|
-
from
|
13
|
-
from
|
14
|
-
from
|
15
|
-
from
|
16
|
-
from .
|
6
|
+
from zrb.attr.type import BoolAttr, fstring
|
7
|
+
from zrb.context.any_context import AnyContext
|
8
|
+
from zrb.context.shared_context import AnySharedContext, SharedContext
|
9
|
+
from zrb.env.any_env import AnyEnv
|
10
|
+
from zrb.input.any_input import AnyInput
|
11
|
+
from zrb.session.any_session import AnySession
|
12
|
+
from zrb.session.session import Session
|
13
|
+
from zrb.task.any_task import AnyTask
|
14
|
+
from zrb.util.attr import get_bool_attr
|
15
|
+
from zrb.util.run import run_async
|
16
|
+
from zrb.xcom.xcom import Xcom
|
17
17
|
|
18
18
|
|
19
19
|
class BaseTask(AnyTask):
|
@@ -24,8 +24,8 @@ class BaseTask(AnyTask):
|
|
24
24
|
icon: str | None = None,
|
25
25
|
description: str | None = None,
|
26
26
|
cli_only: bool = False,
|
27
|
-
input: list[AnyInput] | AnyInput | None = None,
|
28
|
-
env: list[AnyEnv] | AnyEnv | None = None,
|
27
|
+
input: list[AnyInput | None] | AnyInput | None = None,
|
28
|
+
env: list[AnyEnv | None] | AnyEnv | None = None,
|
29
29
|
action: fstring | Callable[[AnyContext], Any] | None = None,
|
30
30
|
execute_condition: BoolAttr = True,
|
31
31
|
retries: int = 2,
|
@@ -63,16 +63,22 @@ class BaseTask(AnyTask):
|
|
63
63
|
return f"<{self.__class__.__name__} name={self._name}>"
|
64
64
|
|
65
65
|
def __rshift__(self, other: AnyTask | list[AnyTask]) -> AnyTask:
|
66
|
-
|
67
|
-
other
|
68
|
-
|
69
|
-
|
70
|
-
task
|
71
|
-
|
66
|
+
try:
|
67
|
+
if isinstance(other, AnyTask):
|
68
|
+
other.append_upstreams(self)
|
69
|
+
elif isinstance(other, list):
|
70
|
+
for task in other:
|
71
|
+
task.append_upstreams(self)
|
72
|
+
return other
|
73
|
+
except Exception as e:
|
74
|
+
raise ValueError(f"Invalid operation {self} >> {other}: {e}")
|
72
75
|
|
73
76
|
def __lshift__(self, other: AnyTask | list[AnyTask]) -> AnyTask:
|
74
|
-
|
75
|
-
|
77
|
+
try:
|
78
|
+
self.append_upstreams(other)
|
79
|
+
return self
|
80
|
+
except Exception as e:
|
81
|
+
raise ValueError(f"Invalid operation {self} << {other}: {e}")
|
76
82
|
|
77
83
|
@property
|
78
84
|
def name(self) -> str:
|
@@ -103,7 +109,7 @@ class BaseTask(AnyTask):
|
|
103
109
|
envs.append(self._envs)
|
104
110
|
elif self._envs is not None:
|
105
111
|
envs += self._envs
|
106
|
-
return envs
|
112
|
+
return [env for env in envs if env is not None]
|
107
113
|
|
108
114
|
@property
|
109
115
|
def inputs(self) -> list[AnyInput]:
|
@@ -112,7 +118,7 @@ class BaseTask(AnyTask):
|
|
112
118
|
self.__combine_inputs(inputs, upstream.inputs)
|
113
119
|
if self._inputs is not None:
|
114
120
|
self.__combine_inputs(inputs, self._inputs)
|
115
|
-
return inputs
|
121
|
+
return [task_input for task_input in inputs if task_input is not None]
|
116
122
|
|
117
123
|
def __combine_inputs(
|
118
124
|
self, inputs: list[AnyInput], other_inputs: list[AnyInput] | AnyInput
|
@@ -120,7 +126,11 @@ class BaseTask(AnyTask):
|
|
120
126
|
input_names = [task_input.name for task_input in inputs]
|
121
127
|
if isinstance(other_inputs, AnyInput):
|
122
128
|
other_inputs = [other_inputs]
|
129
|
+
elif other_inputs is None:
|
130
|
+
other_inputs = []
|
123
131
|
for task_input in other_inputs:
|
132
|
+
if task_input is None:
|
133
|
+
continue
|
124
134
|
if task_input.name not in input_names:
|
125
135
|
inputs.append(task_input)
|
126
136
|
|
zrb/task/base_trigger.py
CHANGED
@@ -2,21 +2,20 @@ import asyncio
|
|
2
2
|
from collections.abc import Callable
|
3
3
|
from typing import Any
|
4
4
|
|
5
|
+
from zrb.attr.type import fstring
|
6
|
+
from zrb.callback.any_callback import AnyCallback
|
5
7
|
from zrb.context.any_context import AnyContext
|
6
8
|
from zrb.context.any_shared_context import AnySharedContext
|
9
|
+
from zrb.context.shared_context import SharedContext
|
10
|
+
from zrb.dot_dict.dot_dict import DotDict
|
7
11
|
from zrb.env.any_env import AnyEnv
|
8
12
|
from zrb.input.any_input import AnyInput
|
13
|
+
from zrb.session.any_session import AnySession
|
14
|
+
from zrb.session.session import Session
|
9
15
|
from zrb.task.any_task import AnyTask
|
10
|
-
|
11
|
-
from
|
12
|
-
from
|
13
|
-
from ..context.shared_context import SharedContext
|
14
|
-
from ..dot_dict.dot_dict import DotDict
|
15
|
-
from ..session.any_session import AnySession
|
16
|
-
from ..session.session import Session
|
17
|
-
from ..util.cli.style import CYAN
|
18
|
-
from ..xcom.xcom import Xcom
|
19
|
-
from .base_task import BaseTask
|
16
|
+
from zrb.task.base_task import BaseTask
|
17
|
+
from zrb.util.cli.style import CYAN
|
18
|
+
from zrb.xcom.xcom import Xcom
|
20
19
|
|
21
20
|
|
22
21
|
class BaseTrigger(BaseTask):
|
@@ -28,8 +27,8 @@ class BaseTrigger(BaseTask):
|
|
28
27
|
icon: str | None = None,
|
29
28
|
description: str | None = None,
|
30
29
|
cli_only: bool = False,
|
31
|
-
input: list[AnyInput] | AnyInput | None = None,
|
32
|
-
env: list[AnyEnv] | AnyEnv | None = None,
|
30
|
+
input: list[AnyInput | None] | AnyInput | None = None,
|
31
|
+
env: list[AnyEnv | None] | AnyEnv | None = None,
|
33
32
|
action: fstring | Callable[[AnyContext], Any] | None = None,
|
34
33
|
execute_condition: bool | str | Callable[[AnySharedContext], bool] = True,
|
35
34
|
queue_name: fstring | None = None,
|