zrb 1.0.0a18__py3-none-any.whl → 1.0.0a20__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.
Files changed (66) hide show
  1. zrb/__init__.py +5 -0
  2. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py +1 -1
  3. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py +1 -1
  4. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py +1 -1
  5. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase.py +1 -5
  6. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase_factory.py +6 -0
  7. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py +3 -9
  8. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +44 -0
  9. zrb/config.py +17 -0
  10. zrb/input/any_input.py +4 -0
  11. zrb/input/base_input.py +4 -4
  12. zrb/input/bool_input.py +1 -1
  13. zrb/input/float_input.py +2 -2
  14. zrb/input/int_input.py +1 -1
  15. zrb/input/option_input.py +2 -2
  16. zrb/input/password_input.py +2 -2
  17. zrb/input/text_input.py +2 -2
  18. zrb/runner/cli.py +9 -34
  19. zrb/runner/common_util.py +31 -0
  20. zrb/runner/web_app.py +164 -44
  21. zrb/runner/web_config.py +288 -0
  22. zrb/runner/web_controller/error_page/controller.py +27 -0
  23. zrb/runner/web_controller/error_page/view.html +33 -0
  24. zrb/runner/web_controller/group_info_page/controller.py +40 -0
  25. zrb/runner/web_controller/group_info_page/view.html +36 -0
  26. zrb/runner/web_controller/home_page/controller.py +13 -48
  27. zrb/runner/web_controller/home_page/view.html +29 -20
  28. zrb/runner/web_controller/login_page/controller.py +25 -0
  29. zrb/runner/web_controller/login_page/view.html +50 -0
  30. zrb/runner/web_controller/logout_page/controller.py +26 -0
  31. zrb/runner/web_controller/logout_page/view.html +40 -0
  32. zrb/runner/web_controller/{task_ui → session_page}/controller.py +35 -26
  33. zrb/runner/web_controller/{task_ui → session_page}/partial/input.html +1 -1
  34. zrb/runner/web_controller/session_page/view.html +91 -0
  35. zrb/runner/web_controller/static/common.css +11 -0
  36. zrb/runner/web_controller/static/login/event.js +33 -0
  37. zrb/runner/web_controller/static/logout/event.js +20 -0
  38. zrb/runner/web_controller/static/pico.min.css +1 -1
  39. zrb/runner/web_controller/static/session/common-util.js +63 -0
  40. zrb/runner/web_controller/static/session/current-session.js +164 -0
  41. zrb/runner/web_controller/static/session/event.js +120 -0
  42. zrb/runner/web_controller/static/session/past-session.js +138 -0
  43. zrb/runner/web_util.py +53 -0
  44. {zrb-1.0.0a18.dist-info → zrb-1.0.0a20.dist-info}/METADATA +2 -1
  45. {zrb-1.0.0a18.dist-info → zrb-1.0.0a20.dist-info}/RECORD +50 -47
  46. zrb/runner/web_controller/group_info_ui/controller.py +0 -83
  47. zrb/runner/web_controller/group_info_ui/partial/group_info.html +0 -2
  48. zrb/runner/web_controller/group_info_ui/partial/group_li.html +0 -1
  49. zrb/runner/web_controller/group_info_ui/partial/task_info.html +0 -2
  50. zrb/runner/web_controller/group_info_ui/partial/task_li.html +0 -1
  51. zrb/runner/web_controller/group_info_ui/view.html +0 -31
  52. zrb/runner/web_controller/home_page/partial/group_info.html +0 -2
  53. zrb/runner/web_controller/home_page/partial/group_li.html +0 -1
  54. zrb/runner/web_controller/home_page/partial/task_info.html +0 -2
  55. zrb/runner/web_controller/home_page/partial/task_li.html +0 -1
  56. zrb/runner/web_controller/task_ui/__init__.py +0 -0
  57. zrb/runner/web_controller/task_ui/partial/common-util.js +0 -37
  58. zrb/runner/web_controller/task_ui/partial/main.js +0 -195
  59. zrb/runner/web_controller/task_ui/partial/show-existing-session.js +0 -97
  60. zrb/runner/web_controller/task_ui/partial/visualize-history.js +0 -104
  61. zrb/runner/web_controller/task_ui/view.html +0 -87
  62. /zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/{factory.py → user_repository_factory.py} +0 -0
  63. /zrb/{builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository → runner/web_controller/group_info_page}/__init__.py +0 -0
  64. /zrb/runner/web_controller/{group_info_ui → session_page}/__init__.py +0 -0
  65. {zrb-1.0.0a18.dist-info → zrb-1.0.0a20.dist-info}/WHEEL +0 -0
  66. {zrb-1.0.0a18.dist-info → zrb-1.0.0a20.dist-info}/entry_points.txt +0 -0
zrb/__init__.py CHANGED
@@ -27,12 +27,14 @@ from zrb.group.group import Group
27
27
  from zrb.input.any_input import AnyInput
28
28
  from zrb.input.base_input import BaseInput
29
29
  from zrb.input.bool_input import BoolInput
30
+ from zrb.input.float_input import FloatInput
30
31
  from zrb.input.int_input import IntInput
31
32
  from zrb.input.option_input import OptionInput
32
33
  from zrb.input.password_input import PasswordInput
33
34
  from zrb.input.str_input import StrInput
34
35
  from zrb.input.text_input import TextInput
35
36
  from zrb.runner.cli import cli
37
+ from zrb.runner.web_config import User, web_config
36
38
  from zrb.session.session import Session
37
39
  from zrb.task.any_task import AnyTask
38
40
  from zrb.task.base_task import BaseTask
@@ -73,6 +75,7 @@ assert CmdResult
73
75
  assert CmdTask
74
76
  assert HttpCheck
75
77
  assert TcpCheck
78
+ assert FloatInput
76
79
  assert IntInput
77
80
  assert OptionInput
78
81
  assert PasswordInput
@@ -98,6 +101,8 @@ assert Scaffolder
98
101
  assert Scheduler
99
102
  assert cli
100
103
  assert Xcom
104
+ assert web_config
105
+ assert User
101
106
 
102
107
  if LOAD_BUILTIN:
103
108
  from zrb import builtin
@@ -1,6 +1,6 @@
1
1
  from my_app_name.config import APP_AUTH_BASE_URL
2
2
  from my_app_name.module.auth.client.any_client import AnyClient
3
- from my_app_name.module.auth.service.user.user_usecase import user_usecase
3
+ from my_app_name.module.auth.service.user.user_usecase_factory import user_usecase
4
4
 
5
5
 
6
6
  class APIClient(user_usecase.as_api_client(base_url=APP_AUTH_BASE_URL), AnyClient):
@@ -1,5 +1,5 @@
1
1
  from my_app_name.module.auth.client.any_client import AnyClient
2
- from my_app_name.module.auth.service.user.user_usecase import user_usecase
2
+ from my_app_name.module.auth.service.user.user_usecase_factory import user_usecase
3
3
 
4
4
 
5
5
  class DirectClient(user_usecase.as_direct_client(), AnyClient):
@@ -2,7 +2,7 @@ from fastapi import FastAPI
2
2
  from my_app_name.common.app import app
3
3
  from my_app_name.common.schema import BasicResponse
4
4
  from my_app_name.config import APP_MAIN_MODULE, APP_MODE, APP_MODULES
5
- from my_app_name.module.auth.service.user.user_usecase import user_usecase
5
+ from my_app_name.module.auth.service.user.user_usecase_factory import user_usecase
6
6
 
7
7
 
8
8
  def serve_health_check(app: FastAPI):
@@ -1,5 +1,4 @@
1
1
  from my_app_name.common.base_usecase import BaseUsecase
2
- from my_app_name.module.auth.service.user.repository.factory import user_repository
3
2
  from my_app_name.module.auth.service.user.repository.user_repository import (
4
3
  UserRepository,
5
4
  )
@@ -50,8 +49,5 @@ class UserUsecase(BaseUsecase):
50
49
  @BaseUsecase.route(
51
50
  "/api/v1/users/{user_id}", methods=["delete"], response_model=UserResponse
52
51
  )
53
- async def delete_user(self, user_id: str) -> UserResponse:
52
+ async def delete_user(self, user_id: str, deleted_by: str) -> UserResponse:
54
53
  return await self.user_repository.delete(user_id)
55
-
56
-
57
- user_usecase = UserUsecase(user_repository=user_repository)
@@ -0,0 +1,6 @@
1
+ from my_app_name.module.auth.service.user.repository.user_repository_factory import (
2
+ user_repository,
3
+ )
4
+ from my_app_name.module.auth.service.user.user_usecase import UserUsecase
5
+
6
+ user_usecase = UserUsecase(user_repository=user_repository)
@@ -2,8 +2,7 @@ from fastapi import FastAPI
2
2
  from my_app_name.common.app import app
3
3
  from my_app_name.common.schema import BasicResponse
4
4
  from my_app_name.config import APP_MAIN_MODULE, APP_MODE, APP_MODULES
5
- from my_app_name.module.auth.client.factory import client as auth_client
6
- from my_app_name.schema.user import UserCreate, UserResponse
5
+ from my_app_name.module.gateway.subroute.auth import serve_auth_route
7
6
 
8
7
 
9
8
  def serve_health_check(app: FastAPI):
@@ -31,13 +30,8 @@ def serve_route(app: FastAPI):
31
30
  serve_health_check(app)
32
31
  serve_readiness_check(app)
33
32
 
34
- @app.get("/api/v1/users", response_model=list[UserResponse])
35
- async def auth_get_all_users() -> UserResponse:
36
- return await auth_client.get_all_users()
37
-
38
- @app.post("/api/v1/users", response_model=UserResponse | list[UserResponse])
39
- async def auth_create_user(data: UserCreate | list[UserCreate]):
40
- return await auth_client.create_user(data)
33
+ # Serve Auth Route
34
+ serve_auth_route(app)
41
35
 
42
36
 
43
37
  serve_route(app)
@@ -0,0 +1,44 @@
1
+ from fastapi import FastAPI
2
+ from my_app_name.module.auth.client.factory import client as auth_client
3
+ from my_app_name.schema.user import (
4
+ UserCreate,
5
+ UserCreateWithAudit,
6
+ UserResponse,
7
+ UserUpdate,
8
+ UserUpdateWithAudit,
9
+ )
10
+
11
+
12
+ def serve_auth_route(app: FastAPI):
13
+
14
+ @app.get("/api/v1/users", response_model=list[UserResponse])
15
+ async def get_all_users() -> UserResponse:
16
+ return await auth_client.get_all_users()
17
+
18
+ @app.get("/api/v1/users/{user_id}", response_model=UserResponse)
19
+ async def get_user_by_id(user_id: str) -> UserResponse:
20
+ return await auth_client.get_user_by_id(user_id)
21
+
22
+ @app.post("/api/v1/users", response_model=UserResponse | list[UserResponse])
23
+ async def create_user(data: UserCreate | list[UserCreate]):
24
+ if isinstance(data, UserCreate):
25
+ data_dict = data.model_dump(exclude_unset=True)
26
+ audited_data = UserCreateWithAudit(**data_dict, created_by="system")
27
+ return await auth_client.create_user(audited_data)
28
+ audited_data = [
29
+ UserCreateWithAudit(
30
+ **row.model_dump(exclude_unset=True), created_by="system"
31
+ )
32
+ for row in data
33
+ ]
34
+ return await auth_client.create_user(audited_data)
35
+
36
+ @app.put("/api/v1/users/{user_id}", response_model=UserResponse)
37
+ async def update_user(user_id: str, data: UserUpdate) -> UserResponse:
38
+ data_dict = data.model_dump(exclude_unset=True)
39
+ audited_data = UserUpdateWithAudit(**data_dict, updated_by="system")
40
+ return await auth_client.update_user(user_id, audited_data)
41
+
42
+ @app.delete("/api/v1/users/{user_id}", response_model=UserResponse)
43
+ async def delete_user(user_id: str) -> UserResponse:
44
+ return await auth_client.delete_user(user_id, deleted_by="system")
zrb/config.py CHANGED
@@ -59,6 +59,23 @@ TODO_VISUAL_FILTER = os.getenv("ZRB_TODO_FILTER", "")
59
59
  TODO_RETENTION = os.getenv("ZRB_TODO_RETENTION", "2w")
60
60
  VERSION = metadata.version("zrb")
61
61
  WEB_HTTP_PORT = int(os.getenv("ZRB_WEB_HTTP_PORT", "21213"))
62
+ WEB_GUEST_USERNAME = os.getenv("ZRB_WEB_GUEST_USERNAME", "user")
63
+ WEB_SUPER_ADMIN_USERNAME = os.getenv("ZRB_WEB_SUPERADMIN_USERNAME", "admin")
64
+ WEB_SUPER_ADMIN_PASSWORD = os.getenv("ZRB_WEB_SUPERADMIN_PASSWORD", "admin")
65
+ WEB_ACCESS_TOKEN_COOKIE_NAME = os.getenv(
66
+ "ZRB_WEB_ACCESS_TOKEN_COOKIE_NAME", "access_token"
67
+ )
68
+ WEB_REFRESH_TOKEN_COOKIE_NAME = os.getenv(
69
+ "ZRB_WEB_REFRESH_TOKEN_COOKIE_NAME", "refresh_token"
70
+ )
71
+ WEB_SECRET_KEY = os.getenv("ZRB_WEB_SECRET", "zrb")
72
+ WEB_ENABLE_AUTH = to_boolean(os.getenv("ZRB_WEB_ENABLE_AUTH", "0"))
73
+ WEB_AUTH_ACCESS_TOKEN_EXPIRE_MINUTES = int(
74
+ os.getenv("ZRB_WEB_ACCESS_TOKEN_EXPIRE", "30")
75
+ )
76
+ WEB_AUTH_REFRESH_TOKEN_EXPIRE_MINUTES = int(
77
+ os.getenv("ZRB_WEB_ACCESS_TOKEN_EXPIRE", f"{60*24*7}")
78
+ )
62
79
  LLM_MODEL = os.getenv("ZRB_LLM_MODEL", "ollama_chat/llama3.1")
63
80
  LLM_SYSTEM_PROMPT = os.getenv("ZRB_LLM_SYSTEM_PROMPT", "You are a helpful assistant")
64
81
  LLM_HISTORY_FILE = os.getenv(
zrb/input/any_input.py CHANGED
@@ -32,3 +32,7 @@ class AnyInput(ABC):
32
32
  @abstractmethod
33
33
  def prompt_cli_str(self, shared_ctx: AnySharedContext) -> str:
34
34
  pass
35
+
36
+ @abstractmethod
37
+ def get_default_str(self, shared_ctx: AnySharedContext) -> str:
38
+ pass
zrb/input/base_input.py CHANGED
@@ -42,14 +42,14 @@ class BaseInput(AnyInput):
42
42
  def to_html(self, ctx: AnySharedContext) -> str:
43
43
  name = self.name
44
44
  description = self.description
45
- default = self._get_default_str(ctx)
45
+ default = self.get_default_str(ctx)
46
46
  return f'<input name="{name}" placeholder="{description}" value="{default}" />'
47
47
 
48
48
  def update_shared_context(
49
49
  self, shared_ctx: AnySharedContext, str_value: str | None = None
50
50
  ):
51
51
  if str_value is None:
52
- str_value = self._get_default_str(shared_ctx)
52
+ str_value = self.get_default_str(shared_ctx)
53
53
  value = self._parse_str_value(str_value)
54
54
  if self.name in shared_ctx.input:
55
55
  raise ValueError(f"Input already defined in the context: {self.name}")
@@ -75,7 +75,7 @@ class BaseInput(AnyInput):
75
75
 
76
76
  def _prompt_cli_str(self, shared_ctx: AnySharedContext) -> str:
77
77
  prompt_message = self.prompt_message
78
- default_value = self._get_default_str(shared_ctx)
78
+ default_value = self.get_default_str(shared_ctx)
79
79
  if default_value != "":
80
80
  prompt_message = f"{prompt_message} [{default_value}]"
81
81
  print(f"{prompt_message}: ", end="")
@@ -84,7 +84,7 @@ class BaseInput(AnyInput):
84
84
  value = default_value
85
85
  return value
86
86
 
87
- def _get_default_str(self, shared_ctx: AnySharedContext) -> str:
87
+ def get_default_str(self, shared_ctx: AnySharedContext) -> str:
88
88
  return get_str_attr(
89
89
  shared_ctx, self._default_str, auto_render=self._auto_render
90
90
  )
zrb/input/bool_input.py CHANGED
@@ -26,7 +26,7 @@ class BoolInput(BaseInput):
26
26
  def to_html(self, ctx: AnySharedContext) -> str:
27
27
  name = self.name
28
28
  description = self.description
29
- default = to_boolean(self._get_default_str(ctx))
29
+ default = to_boolean(self.get_default_str(ctx))
30
30
  selected_true = "selected" if default else ""
31
31
  selected_false = "selected" if not default else ""
32
32
  return "\n".join(
zrb/input/float_input.py CHANGED
@@ -25,8 +25,8 @@ class FloatInput(BaseInput):
25
25
  def to_html(self, ctx: AnySharedContext) -> str:
26
26
  name = self.name
27
27
  description = self.description
28
- default = self._get_default_str(ctx)
29
- return f'<input type="number" name="{name}" placeholder="{description}" value="{default}" />' # noqa
28
+ default = self.get_default_str(ctx)
29
+ return f'<input type="number" name="{name}" placeholder="{description}" value="{default}" step="any" />' # noqa
30
30
 
31
31
  def _parse_str_value(self, str_value: str) -> float:
32
32
  return float(str_value)
zrb/input/int_input.py CHANGED
@@ -25,7 +25,7 @@ class IntInput(BaseInput):
25
25
  def to_html(self, ctx: AnySharedContext) -> str:
26
26
  name = self.name
27
27
  description = self.description
28
- default = self._get_default_str(ctx)
28
+ default = self.get_default_str(ctx)
29
29
  return f'<input type="number" step="1" name="{name}" placeholder="{description}" value="{default}" />' # noqa
30
30
 
31
31
  def _parse_str_value(self, str_value: str) -> int:
zrb/input/option_input.py CHANGED
@@ -28,7 +28,7 @@ class OptionInput(BaseInput):
28
28
  def to_html(self, ctx: AnySharedContext) -> str:
29
29
  name = self.name
30
30
  description = self.description
31
- default = self._get_default_str(ctx)
31
+ default = self.get_default_str(ctx)
32
32
  html = [f'<select name="{name}" placeholder="{description}">']
33
33
  for value in get_str_list_attr(ctx, self._options, self._auto_render):
34
34
  selected = "selected" if value == default else ""
@@ -38,7 +38,7 @@ class OptionInput(BaseInput):
38
38
 
39
39
  def _prompt_cli_str(self, shared_ctx: AnySharedContext) -> str:
40
40
  prompt_message = self.prompt_message
41
- default_value = self._get_default_str(shared_ctx)
41
+ default_value = self.get_default_str(shared_ctx)
42
42
  options = get_str_list_attr(shared_ctx, self._options, self._auto_render)
43
43
  option_str = ", ".join(options)
44
44
  if default_value != "":
@@ -28,12 +28,12 @@ class PasswordInput(BaseInput):
28
28
  def to_html(self, ctx: AnySharedContext) -> str:
29
29
  name = self.name
30
30
  description = self.description
31
- default = self._get_default_str(ctx)
31
+ default = self.get_default_str(ctx)
32
32
  return f'<input type="password" name="{name}" placeholder="{description}" value="{default}" />' # noqa
33
33
 
34
34
  def _prompt_cli_str(self, shared_ctx: AnySharedContext) -> str:
35
35
  prompt_message = self.prompt_message
36
- default_value = self._get_default_str(shared_ctx)
36
+ default_value = self.get_default_str(shared_ctx)
37
37
  value = getpass.getpass(f"{prompt_message}: ")
38
38
  if value.strip() == "":
39
39
  value = default_value
zrb/input/text_input.py CHANGED
@@ -57,7 +57,7 @@ class TextInput(BaseInput):
57
57
  def to_html(self, ctx: AnySharedContext) -> str:
58
58
  name = self.name
59
59
  description = self.description
60
- default = self._get_default_str(ctx)
60
+ default = self.get_default_str(ctx)
61
61
  return "\n".join(
62
62
  [
63
63
  f'<textarea name="{name}" placeholder="{description}">',
@@ -71,7 +71,7 @@ class TextInput(BaseInput):
71
71
  f"{self.comment_start}{super().prompt_message}{self.comment_end}"
72
72
  )
73
73
  prompt_message_eol = f"{prompt_message}\n"
74
- default_value = self._get_default_str(shared_ctx)
74
+ default_value = self.get_default_str(shared_ctx)
75
75
  with tempfile.NamedTemporaryFile(
76
76
  delete=False, suffix=self._extension
77
77
  ) as temp_file:
zrb/runner/cli.py CHANGED
@@ -5,8 +5,13 @@ 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.common_util import get_run_kwargs
8
9
  from zrb.runner.web_app import create_app
10
+ from zrb.runner.web_config import web_config
9
11
  from zrb.session.session import Session
12
+ from zrb.session_state_logger.default_session_state_logger import (
13
+ default_session_state_logger,
14
+ )
10
15
  from zrb.task.any_task import AnyTask
11
16
  from zrb.task.make_task import make_task
12
17
  from zrb.util.cli.style import (
@@ -30,7 +35,7 @@ class Cli(Group):
30
35
  if "h" in kwargs or "help" in kwargs:
31
36
  self._show_task_info(node)
32
37
  return
33
- run_kwargs = self._get_run_kwargs(node, args, kwargs)
38
+ run_kwargs = get_run_kwargs(task=node, args=args, kwargs=kwargs, prompt=True)
34
39
  try:
35
40
  result = self._run_task(node, args, run_kwargs)
36
41
  if result is not None:
@@ -72,35 +77,6 @@ class Cli(Group):
72
77
  continue
73
78
  return task.run(Session(shared_ctx=shared_ctx, root_group=self))
74
79
 
75
- def _get_run_kwargs(
76
- self, task: AnyTask, args: list[str], kwargs: dict[str, str]
77
- ) -> tuple[Any]:
78
- arg_index = 0
79
- str_kwargs = {key: val for key, val in kwargs.items()}
80
- run_kwargs = {**str_kwargs}
81
- shared_ctx = SharedContext(args=args)
82
- for task_input in task.inputs:
83
- if task_input.name in str_kwargs:
84
- # Update shared context for next input default value
85
- task_input.update_shared_context(
86
- shared_ctx, str_kwargs[task_input.name]
87
- )
88
- elif arg_index < len(args):
89
- run_kwargs[task_input.name] = args[arg_index]
90
- # Update shared context for next input default value
91
- task_input.update_shared_context(
92
- shared_ctx, run_kwargs[task_input.name]
93
- )
94
- arg_index += 1
95
- else:
96
- str_value = task_input.prompt_cli_str(shared_ctx)
97
- run_kwargs[task_input.name] = str_value
98
- # Update shared context for next input default value
99
- task_input.update_shared_context(
100
- shared_ctx, run_kwargs[task_input.name]
101
- )
102
- return run_kwargs
103
-
104
80
  def _show_task_info(self, task: AnyTask):
105
81
  description = task.description
106
82
  inputs = task.inputs
@@ -188,10 +164,9 @@ server_group = cli.add_group(
188
164
  group=server_group,
189
165
  alias="start",
190
166
  )
191
- async def run(_: AnyContext):
167
+ async def start_server(_: AnyContext):
192
168
  from uvicorn import Config, Server
193
169
 
194
- app = create_app(cli, WEB_HTTP_PORT)
195
- config = Config(app=app, host="0.0.0.0", port=WEB_HTTP_PORT, loop="asyncio")
196
- server = Server(config)
170
+ app = create_app(cli, web_config, default_session_state_logger)
171
+ server = Server(Config(app=app, host="0.0.0.0", port=WEB_HTTP_PORT, loop="asyncio"))
197
172
  await server.serve()
@@ -0,0 +1,31 @@
1
+ from typing import Any
2
+
3
+ from zrb.context.shared_context import SharedContext
4
+ from zrb.task.any_task import AnyTask
5
+
6
+
7
+ def get_run_kwargs(
8
+ task: AnyTask, args: list[str], kwargs: dict[str, str], prompt: bool = True
9
+ ) -> tuple[Any]:
10
+ arg_index = 0
11
+ str_kwargs = {key: val for key, val in kwargs.items()}
12
+ run_kwargs = {**str_kwargs}
13
+ shared_ctx = SharedContext(args=args)
14
+ for task_input in task.inputs:
15
+ if task_input.name in str_kwargs:
16
+ # Update shared context for next input default value
17
+ task_input.update_shared_context(shared_ctx, str_kwargs[task_input.name])
18
+ elif arg_index < len(args):
19
+ run_kwargs[task_input.name] = args[arg_index]
20
+ # Update shared context for next input default value
21
+ task_input.update_shared_context(shared_ctx, run_kwargs[task_input.name])
22
+ arg_index += 1
23
+ else:
24
+ if prompt:
25
+ str_value = task_input.prompt_cli_str(shared_ctx)
26
+ else:
27
+ str_value = task_input.get_default_str(shared_ctx)
28
+ run_kwargs[task_input.name] = str_value
29
+ # Update shared context for next input default value
30
+ task_input.update_shared_context(shared_ctx, run_kwargs[task_input.name])
31
+ return run_kwargs