zrb 1.0.0a17__py3-none-any.whl → 1.0.0a19__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 (144) hide show
  1. zrb/__init__.py +2 -0
  2. zrb/builtin/project/add/fastapp/fastapp_task.py +25 -39
  3. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/.flake8 +3 -0
  4. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/create_column_task.py +14 -0
  5. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py +128 -0
  6. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_util.py +213 -0
  7. zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/entity/any_client_method.template.py → my_app_name/_zrb/entity/template/any_client_method.py} +1 -1
  8. zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/entity/module_template → my_app_name/_zrb/entity/template/app_template/module/my_module}/service/my_entity/my_entity_usecase.py +4 -5
  9. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/factory.py +13 -0
  10. zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/entity/module_template → my_app_name/_zrb/entity/template/app_template/module/my_module}/service/my_entity/repository/my_entity_db_repository.py +4 -4
  11. zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/entity/module_template → my_app_name/_zrb/entity/template/app_template/module/my_module}/service/my_entity/repository/my_entity_repository.py +1 -2
  12. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/format_task.py +17 -0
  13. zrb/builtin/project/add/fastapp/fastapp_template/{_zrb → my_app_name/_zrb}/input.py +1 -4
  14. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py +85 -0
  15. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_util.py +154 -0
  16. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/api_client.py +6 -0
  17. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/direct_client.py +6 -0
  18. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/factory.py +9 -0
  19. zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/module/template/module_template → my_app_name/_zrb/module/template/app_template/module/my_module}/migration/env.py +2 -4
  20. zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/module/template/module_template → my_app_name/_zrb/module/template/app_template/module/my_module}/migration/script.py.mako +1 -0
  21. zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/module/template/module_template → my_app_name/_zrb/module/template/app_template/module/my_module}/route.py +3 -3
  22. zrb/builtin/project/add/fastapp/fastapp_template/{_zrb → my_app_name/_zrb}/task.py +12 -14
  23. zrb/builtin/project/add/fastapp/fastapp_template/{_zrb → my_app_name/_zrb}/util.py +1 -1
  24. zrb/builtin/project/add/fastapp/fastapp_template/{_zrb → my_app_name/_zrb}/venv_task.py +1 -1
  25. zrb/builtin/project/add/fastapp/fastapp_template/{common → my_app_name/common}/app.py +2 -2
  26. zrb/builtin/project/add/fastapp/fastapp_template/{common → my_app_name/common}/base_db_repository.py +1 -1
  27. zrb/builtin/project/add/fastapp/fastapp_template/{common → my_app_name/common}/db_engine.py +1 -1
  28. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/main.py +7 -0
  29. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/migrate.py +3 -0
  30. zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/client/any_client.py +1 -1
  31. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py +7 -0
  32. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py +6 -0
  33. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/factory.py +9 -0
  34. zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/migration/env.py +2 -4
  35. zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/migration/script.py.mako +1 -0
  36. zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/migration_metadata.py +1 -1
  37. zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/route.py +4 -4
  38. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/factory.py +13 -0
  39. zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/service/user/repository/user_db_repository.py +4 -4
  40. zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/service/user/repository/user_repository.py +1 -2
  41. zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/service/user/user_usecase.py +4 -5
  42. zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/gateway/migration/env.py +2 -4
  43. zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/gateway/migration/script.py.mako +1 -0
  44. zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/gateway/route.py +5 -5
  45. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +0 -0
  46. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/__init__.py +0 -0
  47. zrb/builtin/project/add/fastapp/fastapp_util.py +29 -5
  48. zrb/builtin/python.py +4 -1
  49. zrb/builtin/todo.py +35 -14
  50. zrb/callback/callback.py +0 -1
  51. zrb/config.py +1 -0
  52. zrb/content_transformer/content_transformer.py +5 -3
  53. zrb/context/any_context.py +6 -6
  54. zrb/group/group.py +0 -1
  55. zrb/input/any_input.py +4 -0
  56. zrb/input/base_input.py +4 -4
  57. zrb/input/bool_input.py +1 -1
  58. zrb/input/float_input.py +2 -2
  59. zrb/input/int_input.py +1 -1
  60. zrb/input/option_input.py +2 -2
  61. zrb/input/password_input.py +2 -2
  62. zrb/input/text_input.py +2 -2
  63. zrb/runner/cli.py +2 -31
  64. zrb/runner/common_util.py +31 -0
  65. zrb/runner/web_app.py +25 -6
  66. zrb/runner/web_controller/static/pico.min.css +1 -1
  67. zrb/runner/web_controller/static/task-ui/common-util.js +63 -0
  68. zrb/runner/web_controller/static/task-ui/current-session.js +164 -0
  69. zrb/runner/web_controller/static/task-ui/event.js +120 -0
  70. zrb/runner/web_controller/static/task-ui/past-session.js +138 -0
  71. zrb/runner/web_controller/task_ui/controller.py +20 -19
  72. zrb/runner/web_controller/task_ui/view.html +12 -15
  73. zrb/session_state_logger/any_session_state_logger.py +0 -1
  74. zrb/session_state_logger/file_session_state_logger.py +0 -1
  75. zrb/task/base_trigger.py +0 -1
  76. zrb/task/llm_task.py +0 -1
  77. zrb/task/make_task.py +0 -1
  78. zrb/task/scaffolder.py +6 -4
  79. zrb/task/scheduler.py +0 -1
  80. zrb/util/cmd/command.py +0 -1
  81. zrb/util/codemod/append_code_to_class.py +4 -4
  82. zrb/util/codemod/append_code_to_function.py +2 -2
  83. zrb/util/codemod/append_code_to_method.py +2 -2
  84. zrb/util/codemod/prepend_code_to_module.py +2 -2
  85. zrb/util/file.py +1 -1
  86. zrb/util/todo.py +100 -17
  87. zrb/xcom/xcom.py +0 -1
  88. {zrb-1.0.0a17.dist-info → zrb-1.0.0a19.dist-info}/METADATA +1 -1
  89. zrb-1.0.0a19.dist-info/RECORD +241 -0
  90. zrb/builtin/project/add/fastapp/fastapp_template/_zrb/column/create_column_task.py +0 -11
  91. zrb/builtin/project/add/fastapp/fastapp_template/_zrb/entity/module_template/service/my_entity/repository/factory.py +0 -13
  92. zrb/builtin/project/add/fastapp/fastapp_template/_zrb/entity/task.py +0 -260
  93. zrb/builtin/project/add/fastapp/fastapp_template/_zrb/module/task.py +0 -143
  94. zrb/builtin/project/add/fastapp/fastapp_template/_zrb/module/template/module_template/client/api_client.py +0 -6
  95. zrb/builtin/project/add/fastapp/fastapp_template/_zrb/module/template/module_template/client/direct_client.py +0 -6
  96. zrb/builtin/project/add/fastapp/fastapp_template/_zrb/module/template/module_template/client/factory.py +0 -9
  97. zrb/builtin/project/add/fastapp/fastapp_template/main.py +0 -7
  98. zrb/builtin/project/add/fastapp/fastapp_template/migrate.py +0 -3
  99. zrb/builtin/project/add/fastapp/fastapp_template/module/auth/client/api_client.py +0 -7
  100. zrb/builtin/project/add/fastapp/fastapp_template/module/auth/client/direct_client.py +0 -6
  101. zrb/builtin/project/add/fastapp/fastapp_template/module/auth/client/factory.py +0 -9
  102. zrb/builtin/project/add/fastapp/fastapp_template/module/auth/service/user/repository/factory.py +0 -13
  103. zrb/runner/web_controller/task_ui/partial/common-util.js +0 -37
  104. zrb/runner/web_controller/task_ui/partial/main.js +0 -195
  105. zrb/runner/web_controller/task_ui/partial/show-existing-session.js +0 -97
  106. zrb/runner/web_controller/task_ui/partial/visualize-history.js +0 -104
  107. zrb-1.0.0a17.dist-info/RECORD +0 -234
  108. /zrb/builtin/project/add/fastapp/fastapp_template/{.gitignore → my_app_name/.gitignore} +0 -0
  109. /zrb/builtin/project/add/fastapp/fastapp_template/{README.md → my_app_name/README.md} +0 -0
  110. /zrb/builtin/project/add/fastapp/fastapp_template/{__init__.py → my_app_name/__init__.py} +0 -0
  111. /zrb/builtin/project/add/fastapp/fastapp_template/{_zrb → my_app_name/_zrb}/config.py +0 -0
  112. /zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/entity/schema.template.py → my_app_name/_zrb/entity/template/app_template/schema/my_entity.py} +0 -0
  113. /zrb/builtin/project/add/fastapp/fastapp_template/{_zrb → my_app_name/_zrb}/group.py +0 -0
  114. /zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/module/template/module_template/migration/versions/.gitkeep → my_app_name/_zrb/module/template/app_template/module/gateway/subroute/my_module.py} +0 -0
  115. /zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/module/template/module_template → my_app_name/_zrb/module/template/app_template/module/my_module}/alembic.ini +0 -0
  116. /zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/module/template/module_template → my_app_name/_zrb/module/template/app_template/module/my_module}/client/any_client.py +0 -0
  117. /zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/module/template/module_template → my_app_name/_zrb/module/template/app_template/module/my_module}/migration/README +0 -0
  118. /zrb/builtin/project/add/fastapp/fastapp_template/{module/gateway → my_app_name/_zrb/module/template/app_template/module/my_module}/migration/versions/.gitkeep +0 -0
  119. /zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/module/template/module_template → my_app_name/_zrb/module/template/app_template/module/my_module}/migration_metadata.py +0 -0
  120. /zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/module/template/module_template → my_app_name/_zrb/module/template/app_template/module/my_module}/service/__init__.py +0 -0
  121. /zrb/builtin/project/add/fastapp/fastapp_template/{_zrb/module/template/task_definition.py → my_app_name/_zrb/module/template/module_task_definition.py} +0 -0
  122. /zrb/builtin/project/add/fastapp/fastapp_template/{common → my_app_name/common}/__init__.py +0 -0
  123. /zrb/builtin/project/add/fastapp/fastapp_template/{common → my_app_name/common}/base_usecase.py +0 -0
  124. /zrb/builtin/project/add/fastapp/fastapp_template/{common → my_app_name/common}/error.py +0 -0
  125. /zrb/builtin/project/add/fastapp/fastapp_template/{common → my_app_name/common}/schema.py +0 -0
  126. /zrb/builtin/project/add/fastapp/fastapp_template/{config.py → my_app_name/config.py} +0 -0
  127. /zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/__init__.py +0 -0
  128. /zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/alembic.ini +0 -0
  129. /zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/migration/README +0 -0
  130. /zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/migration/versions/3093c7336477_add_user_table.py +0 -0
  131. /zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/service/__init__.py +0 -0
  132. /zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/service/user/__init__.py +0 -0
  133. /zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/auth/service/user/repository/__init__.py +0 -0
  134. /zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/gateway/alembic.ini +0 -0
  135. /zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/gateway/migration/README +0 -0
  136. /zrb/builtin/project/add/fastapp/fastapp_template/{schema/__init__.py → my_app_name/module/gateway/migration/versions/.gitkeep} +0 -0
  137. /zrb/builtin/project/add/fastapp/fastapp_template/{module → my_app_name/module}/gateway/migration_metadata.py +0 -0
  138. /zrb/builtin/project/add/fastapp/fastapp_template/{requirements.txt → my_app_name/requirements.txt} +0 -0
  139. /zrb/builtin/project/add/fastapp/fastapp_template/{schema → my_app_name/schema}/permission.py +0 -0
  140. /zrb/builtin/project/add/fastapp/fastapp_template/{schema → my_app_name/schema}/role.py +0 -0
  141. /zrb/builtin/project/add/fastapp/fastapp_template/{schema → my_app_name/schema}/user.py +0 -0
  142. /zrb/builtin/project/add/fastapp/fastapp_template/{template.env → my_app_name/template.env} +0 -0
  143. {zrb-1.0.0a17.dist-info → zrb-1.0.0a19.dist-info}/WHEEL +0 -0
  144. {zrb-1.0.0a17.dist-info → zrb-1.0.0a19.dist-info}/entry_points.txt +0 -0
zrb/builtin/todo.py CHANGED
@@ -4,7 +4,7 @@ import os
4
4
  from typing import Any
5
5
 
6
6
  from zrb.builtin.group import todo_group
7
- from zrb.config import TODO_DIR, TODO_VISUAL_FILTER
7
+ from zrb.config import TODO_DIR, TODO_RETENTION, TODO_VISUAL_FILTER
8
8
  from zrb.context.any_context import AnyContext
9
9
  from zrb.input.str_input import StrInput
10
10
  from zrb.input.text_input import TextInput
@@ -12,12 +12,13 @@ from zrb.task.make_task import make_task
12
12
  from zrb.util.file import read_file, write_file
13
13
  from zrb.util.todo import (
14
14
  TodoTaskModel,
15
- add_durations,
15
+ add_duration,
16
16
  cascade_todo_task,
17
17
  get_visual_todo_card,
18
18
  get_visual_todo_list,
19
19
  line_to_todo_task,
20
20
  load_todo_list,
21
+ parse_duration,
21
22
  save_todo_list,
22
23
  select_todo_task,
23
24
  todo_task_to_line,
@@ -165,11 +166,17 @@ def archive_todo(ctx: AnyContext):
165
166
  todo_list: list[TodoTaskModel] = []
166
167
  if os.path.isfile(todo_file_path):
167
168
  todo_list = load_todo_list(todo_file_path)
168
- working_todo_list = [
169
- todo_task for todo_task in todo_list if not todo_task.completed
170
- ]
169
+ retention_duration = datetime.timedelta(seconds=parse_duration(TODO_RETENTION))
170
+ threshold_date = datetime.date.today() - retention_duration
171
171
  new_archived_todo_list = [
172
- todo_task for todo_task in todo_list if todo_task.completed
172
+ todo_task
173
+ for todo_task in todo_list
174
+ if todo_task.completed
175
+ and todo_task.completion_date is not None
176
+ and todo_task.completion_date < threshold_date
177
+ ]
178
+ working_todo_list = [
179
+ todo_task for todo_task in todo_list if todo_task not in new_archived_todo_list
173
180
  ]
174
181
  if len(new_archived_todo_list) == 0:
175
182
  ctx.print("No completed task to archive")
@@ -204,10 +211,10 @@ def archive_todo(ctx: AnyContext):
204
211
  default_str="30m",
205
212
  ),
206
213
  StrInput(
207
- name="start",
208
- prompt="Working start time (%Y-%m-%d %H:%M:%S)",
209
- description="Working start time",
210
- default_str=lambda _: _get_default_start(),
214
+ name="stop",
215
+ prompt="Working stop time (%Y-%m-%d %H:%M:%S)",
216
+ description="Working stop time",
217
+ default_str=lambda _: _get_default_stop_work_time_str(),
211
218
  ),
212
219
  ],
213
220
  description="🕒 Log work todo",
@@ -226,8 +233,10 @@ def log_todo(ctx: AnyContext):
226
233
  return get_visual_todo_list(todo_list, TODO_VISUAL_FILTER)
227
234
  # Update todo task
228
235
  todo_task = cascade_todo_task(todo_task)
229
- current_duration = todo_task.keyval.get("duration", "0")
230
- todo_task.keyval["duration"] = add_durations(current_duration, ctx.input.duration)
236
+ current_duration_str = todo_task.keyval.get("duration", "0")
237
+ todo_task.keyval["duration"] = add_duration(
238
+ current_duration_str, ctx.input.duration
239
+ )
231
240
  # Save todo list
232
241
  save_todo_list(todo_file_path, todo_list)
233
242
  # Add log work
@@ -241,8 +250,13 @@ def log_todo(ctx: AnyContext):
241
250
  else:
242
251
  log_work_json = "[]"
243
252
  log_work: list[dict[str, Any]] = json.loads(log_work_json)
253
+ start_work_time_str = _get_start_work_time_str(ctx.input.stop, ctx.input.duration)
244
254
  log_work.append(
245
- {"log": ctx.input.log, "duration": ctx.input.duration, "start": ctx.input.start}
255
+ {
256
+ "log": ctx.input.log,
257
+ "duration": ctx.input.duration,
258
+ "start": start_work_time_str,
259
+ }
246
260
  )
247
261
  # save todo with log work
248
262
  write_file(log_work_file_path, json.dumps(log_work, indent=2))
@@ -261,7 +275,14 @@ def log_todo(ctx: AnyContext):
261
275
  )
262
276
 
263
277
 
264
- def _get_default_start() -> str:
278
+ def _get_start_work_time_str(stop_work_time_str: str, work_duration_str: str) -> str:
279
+ work_duration = parse_duration(work_duration_str)
280
+ stop_work_time = datetime.datetime.strptime(stop_work_time_str, "%Y-%m-%d %H:%M:%S")
281
+ start_work_time = stop_work_time - datetime.timedelta(seconds=work_duration)
282
+ return start_work_time.strftime("%Y-%m-%d %H:%M:%S")
283
+
284
+
285
+ def _get_default_stop_work_time_str() -> str:
265
286
  return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
266
287
 
267
288
 
zrb/callback/callback.py CHANGED
@@ -8,7 +8,6 @@ from zrb.util.attr import get_str_dict_attr
8
8
 
9
9
 
10
10
  class Callback(AnyCallback):
11
-
12
11
  def __init__(
13
12
  self,
14
13
  input_mapping: StrDictAttr,
zrb/config.py CHANGED
@@ -56,6 +56,7 @@ SESSION_LOG_DIR = os.getenv(
56
56
  )
57
57
  TODO_DIR = os.getenv("ZRB_TODO_DIR", os.path.expanduser(os.path.join("~", "todo")))
58
58
  TODO_VISUAL_FILTER = os.getenv("ZRB_TODO_FILTER", "")
59
+ TODO_RETENTION = os.getenv("ZRB_TODO_RETENTION", "2w")
59
60
  VERSION = metadata.version("zrb")
60
61
  WEB_HTTP_PORT = int(os.getenv("ZRB_WEB_HTTP_PORT", "21213"))
61
62
  LLM_MODEL = os.getenv("ZRB_LLM_MODEL", "ollama_chat/llama3.1")
@@ -8,13 +8,12 @@ from zrb.util.file import read_file, write_file
8
8
 
9
9
 
10
10
  class ContentTransformer(AnyContentTransformer):
11
-
12
11
  def __init__(
13
12
  self,
14
13
  match: list[str] | str | Callable[[AnyContext, str], bool],
15
14
  transform: (
16
15
  dict[str, str | Callable[[AnyContext], str]]
17
- | Callable[[AnyContext, str], str]
16
+ | Callable[[AnyContext, str], None]
18
17
  ),
19
18
  auto_render: bool = True,
20
19
  ):
@@ -25,7 +24,10 @@ class ContentTransformer(AnyContentTransformer):
25
24
  def match(self, ctx: AnyContext, file_path: str) -> bool:
26
25
  if callable(self._match):
27
26
  return self._match(ctx, file_path)
28
- patterns = [self._match] if isinstance(self._match, str) else self._match
27
+ if isinstance(self._match, str):
28
+ patterns = [self._match]
29
+ else:
30
+ patterns = self._match
29
31
  for pattern in patterns:
30
32
  try:
31
33
  if re.fullmatch(pattern, file_path):
@@ -42,7 +42,7 @@ class AnyContext(AnySharedContext):
42
42
  sep: str | None = " ",
43
43
  end: str | None = "\n",
44
44
  file: TextIO | None = sys.stderr,
45
- flush: bool = True
45
+ flush: bool = True,
46
46
  ):
47
47
  """Prints values to the specified output stream.
48
48
 
@@ -62,7 +62,7 @@ class AnyContext(AnySharedContext):
62
62
  sep: str | None = " ",
63
63
  end: str | None = "\n",
64
64
  file: TextIO | None = sys.stderr,
65
- flush: bool = True
65
+ flush: bool = True,
66
66
  ):
67
67
  """Logs debug-level messages.
68
68
 
@@ -82,7 +82,7 @@ class AnyContext(AnySharedContext):
82
82
  sep: str | None = " ",
83
83
  end: str | None = "\n",
84
84
  file: TextIO | None = sys.stderr,
85
- flush: bool = True
85
+ flush: bool = True,
86
86
  ):
87
87
  """Logs info-level messages.
88
88
 
@@ -102,7 +102,7 @@ class AnyContext(AnySharedContext):
102
102
  sep: str | None = " ",
103
103
  end: str | None = "\n",
104
104
  file: TextIO | None = sys.stderr,
105
- flush: bool = True
105
+ flush: bool = True,
106
106
  ):
107
107
  """Logs warning-level messages.
108
108
 
@@ -122,7 +122,7 @@ class AnyContext(AnySharedContext):
122
122
  sep: str | None = " ",
123
123
  end: str | None = "\n",
124
124
  file: TextIO | None = sys.stderr,
125
- flush: bool = True
125
+ flush: bool = True,
126
126
  ):
127
127
  """Logs error-level messages.
128
128
 
@@ -142,7 +142,7 @@ class AnyContext(AnySharedContext):
142
142
  sep: str | None = " ",
143
143
  end: str | None = "\n",
144
144
  file: TextIO | None = sys.stderr,
145
- flush: bool = True
145
+ flush: bool = True,
146
146
  ):
147
147
  """Logs critical-level messages.
148
148
 
zrb/group/group.py CHANGED
@@ -3,7 +3,6 @@ from zrb.task.any_task import AnyTask
3
3
 
4
4
 
5
5
  class Group(AnyGroup):
6
-
7
6
  def __init__(
8
7
  self, name: str, description: str | None = None, banner: str | None = None
9
8
  ):
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,6 +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.common_util import get_run_kwargs
8
9
  from zrb.runner.web_app import create_app
9
10
  from zrb.session.session import Session
10
11
  from zrb.task.any_task import AnyTask
@@ -20,7 +21,6 @@ from zrb.util.string.conversion import double_quote
20
21
 
21
22
 
22
23
  class Cli(Group):
23
-
24
24
  def run(self, args: list[str] = []):
25
25
  load_zrb_init()
26
26
  kwargs, args = self._extract_kwargs_from_args(args)
@@ -31,7 +31,7 @@ class Cli(Group):
31
31
  if "h" in kwargs or "help" in kwargs:
32
32
  self._show_task_info(node)
33
33
  return
34
- run_kwargs = self._get_run_kwargs(node, args, kwargs)
34
+ run_kwargs = get_run_kwargs(task=node, args=args, kwargs=kwargs, prompt=True)
35
35
  try:
36
36
  result = self._run_task(node, args, run_kwargs)
37
37
  if result is not None:
@@ -73,35 +73,6 @@ class Cli(Group):
73
73
  continue
74
74
  return task.run(Session(shared_ctx=shared_ctx, root_group=self))
75
75
 
76
- def _get_run_kwargs(
77
- self, task: AnyTask, args: list[str], kwargs: dict[str, str]
78
- ) -> tuple[Any]:
79
- arg_index = 0
80
- str_kwargs = {key: val for key, val in kwargs.items()}
81
- run_kwargs = {**str_kwargs}
82
- shared_ctx = SharedContext(args=args)
83
- for task_input in task.inputs:
84
- if task_input.name in str_kwargs:
85
- # Update shared context for next input default value
86
- task_input.update_shared_context(
87
- shared_ctx, str_kwargs[task_input.name]
88
- )
89
- elif arg_index < len(args):
90
- run_kwargs[task_input.name] = args[arg_index]
91
- # Update shared context for next input default value
92
- task_input.update_shared_context(
93
- shared_ctx, run_kwargs[task_input.name]
94
- )
95
- arg_index += 1
96
- else:
97
- str_value = task_input.prompt_cli_str(shared_ctx)
98
- run_kwargs[task_input.name] = str_value
99
- # Update shared context for next input default value
100
- task_input.update_shared_context(
101
- shared_ctx, run_kwargs[task_input.name]
102
- )
103
- return run_kwargs
104
-
105
76
  def _show_task_info(self, task: AnyTask):
106
77
  description = task.description
107
78
  inputs = task.inputs
@@ -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
zrb/runner/web_app.py CHANGED
@@ -1,12 +1,13 @@
1
1
  import asyncio
2
+ import json
2
3
  import os
3
4
  import sys
4
5
  from datetime import datetime, timedelta
5
- from typing import Any
6
6
 
7
7
  from zrb.config import BANNER, WEB_HTTP_PORT
8
8
  from zrb.context.shared_context import SharedContext
9
9
  from zrb.group.any_group import AnyGroup
10
+ from zrb.runner.common_util import get_run_kwargs
10
11
  from zrb.runner.web_controller.group_info_ui.controller import handle_group_info_ui
11
12
  from zrb.runner.web_controller.home_page.controller import handle_home_page
12
13
  from zrb.runner.web_controller.task_ui.controller import handle_task_ui
@@ -75,10 +76,8 @@ def create_app(root_group: AnyGroup, port: int = WEB_HTTP_PORT):
75
76
  return handle_group_info_ui(root_group, node, url)
76
77
  raise HTTPException(status_code=404, detail="Not Found")
77
78
 
78
- @app.post("/api/{path:path}")
79
- async def create_new_session(
80
- path: str, request: Request = None
81
- ) -> NewSessionResponse:
79
+ @app.post("/api/sessions/{path:path}")
80
+ async def create_new_session(path: str, request: Request) -> NewSessionResponse:
82
81
  """
83
82
  Creating new session
84
83
  """
@@ -96,7 +95,27 @@ def create_app(root_group: AnyGroup, port: int = WEB_HTTP_PORT):
96
95
  return NewSessionResponse(session_name=session.name)
97
96
  raise HTTPException(status_code=404, detail="Not Found")
98
97
 
99
- @app.get("/api/{path:path}", response_model=SessionStateLog | SessionStateLogList)
98
+ @app.get("/api/inputs/{path:path}", response_model=dict[str, str])
99
+ async def get_default_inputs(
100
+ path: str, query: str = Query("{}", description="JSON encoded inputs")
101
+ ):
102
+ """
103
+ Getting input completion for path
104
+ """
105
+ args = path.strip("/").split("/")
106
+ task, _, _ = extract_node_from_args(root_group, args)
107
+ if isinstance(task, AnyTask):
108
+ query_dict = json.loads(query)
109
+ run_kwargs = get_run_kwargs(
110
+ task=task, args=[], kwargs=query_dict, prompt=False
111
+ )
112
+ return run_kwargs
113
+ raise HTTPException(status_code=404, detail="Not Found")
114
+
115
+ @app.get(
116
+ "/api/sessions/{path:path}",
117
+ response_model=SessionStateLog | SessionStateLogList,
118
+ )
100
119
  async def get_session(
101
120
  path: str,
102
121
  min_start_query: str = Query(default=None, alias="from"),