zrb 0.17.2__py3-none-any.whl → 0.17.5__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.
@@ -15,7 +15,7 @@ class MessagebusCaller(Caller):
15
15
  publisher: Publisher,
16
16
  consumer_factory: Callable[[], Consumer],
17
17
  timeout: float = 30,
18
- check_reply_interval: float = 0.1,
18
+ check_reply_interval: float = 0.05,
19
19
  ):
20
20
  self.logger = logger
21
21
  self.admin = admin
zrb/task/any_task.py CHANGED
@@ -25,11 +25,11 @@ TAnyTask = TypeVar("TAnyTask", bound="AnyTask")
25
25
 
26
26
  class AnyTask(ABC):
27
27
  """
28
- Contract/interface for all Zrb Task.
28
+ Abstraction for Zrb Task.
29
29
 
30
- This class acts as a template for creating new Zrb Task types.
30
+ This class acts as a template for creating new Task type.
31
31
 
32
- To define a new Zrb Task, you should extend this class and implement all its methods.
32
+ To define a new Task type, you should extend this class and implement all its methods.
33
33
  The easiest way to do so is by extending `Task`
34
34
  """
35
35
 
@@ -91,7 +91,7 @@ class SingleBaseRemoteCmdTask(CmdTask):
91
91
  on_retry: Optional[OnRetry] = None,
92
92
  on_failed: Optional[OnFailed] = None,
93
93
  checkers: Iterable[AnyTask] = [],
94
- checking_interval: Union[float, int] = 0,
94
+ checking_interval: Union[float, int] = 0.05,
95
95
  retry: int = 2,
96
96
  retry_interval: Union[float, int] = 1,
97
97
  max_output_line: int = 1000,
@@ -146,7 +146,7 @@ class SingleBaseRemoteCmdTask(CmdTask):
146
146
  self._remote_config = remote_config
147
147
 
148
148
  def copy(self) -> TSingleBaseRemoteCmdTask:
149
- return copy.deepcopy(self)
149
+ return super().copy()
150
150
 
151
151
  def inject_envs(self):
152
152
  super().inject_envs()
@@ -235,7 +235,7 @@ class BaseRemoteCmdTask(BaseTask):
235
235
  on_retry: Optional[OnRetry] = None,
236
236
  on_failed: Optional[OnFailed] = None,
237
237
  checkers: Iterable[AnyTask] = [],
238
- checking_interval: Union[float, int] = 0,
238
+ checking_interval: Union[float, int] = 0.05,
239
239
  retry: int = 2,
240
240
  retry_interval: Union[float, int] = 1,
241
241
  max_output_line: int = 1000,
@@ -37,8 +37,44 @@ from zrb.task_input.any_input import AnyInput
37
37
  @typechecked
38
38
  class BaseTask(FinishTracker, AttemptTracker, Renderer, BaseTaskModel, AnyTask):
39
39
  """
40
- Base class for all tasks.
41
- Every task definition should be extended from this class.
40
+ Base class for all Tasks.
41
+ Every Task definition should be extended from this class.
42
+
43
+ Task is the smallest Zrb automation unit.
44
+
45
+ You can configure a Task by using several interfaces:
46
+ - `inputs`: interfaces to read user input at the beginning of the execution.
47
+ - `envs`: interfaces to read and use OS Environment Variables.
48
+ - `env_files`: interfaces to read and use Environment Files.
49
+
50
+ Moreover, you can define Task dependencies by specifying it's `upstreams` or by using shift-right operator.
51
+
52
+ Every Task has its own life-cycle state:
53
+ - `Triggered`: The Task is triggered.
54
+ - `Waiting`: The Task is waiting for all it's upstreams to be ready.
55
+ - `Skipped`: The Task is not executed and will immediately enter the `Ready` state.
56
+ - `Started`: The Task execution is started.
57
+ - `Failed`: The Task execution is failed. It will enter the `Retry` state if the current attempt is less than the maximum attempt.
58
+ - `Retry`: The task will be restarted.
59
+ - `Ready`: The task is ready.
60
+
61
+ There are several configurations related to Task's life cycle:
62
+ - `retry`: How many retries should be attempted.
63
+ - `retry_interval`: How long to wait before the next retry attempt.
64
+ - `fallbacks`: What to do if the Task is failed and no retry attempt will be performed.
65
+ - `checkers`: How to determine if a Task is `Ready`.
66
+ - `checking_interval`: How long to wait before checking for Task's readiness.
67
+ - `run`: What a Task should do.
68
+ - `on_triggered`: What to do when a Task is `Triggered`.
69
+ - `on_waiting`: What to do when a Task is `Waiting`.
70
+ - `on_skipped`: What to do when a Task is `Skipped`.
71
+ - `on_started`: What to do when a Task is `Started`.
72
+ - `on_ready`: What to do when a Task is `Ready`.
73
+ - `on_retry`: What to do when a Task is `Retry`.
74
+ - `on_failed`: What to do when a Task is `Failed`.
75
+ - `should_execute`: Whether a Task should be `Started` or not (`Skipped`).
76
+
77
+ Finally, you can put related Tasks under the same `group`.
42
78
  """
43
79
 
44
80
  __running_tasks: List[AnyTask] = []
@@ -58,7 +94,7 @@ class BaseTask(FinishTracker, AttemptTracker, Renderer, BaseTaskModel, AnyTask):
58
94
  upstreams: Iterable[AnyTask] = [],
59
95
  fallbacks: Iterable[AnyTask] = [],
60
96
  checkers: Iterable[AnyTask] = [],
61
- checking_interval: Union[float, int] = 0,
97
+ checking_interval: Union[float, int] = 0.05,
62
98
  run: Optional[Callable[..., Any]] = None,
63
99
  on_triggered: Optional[OnTriggered] = None,
64
100
  on_waiting: Optional[OnWaiting] = None,
@@ -72,7 +108,7 @@ class BaseTask(FinishTracker, AttemptTracker, Renderer, BaseTaskModel, AnyTask):
72
108
  ):
73
109
  # init properties
74
110
  retry_interval = retry_interval if retry_interval >= 0 else 0
75
- checking_interval = checking_interval if checking_interval > 0 else 0.05
111
+ checking_interval = checking_interval if checking_interval > 0 else 0
76
112
  retry = retry if retry >= 0 else 0
77
113
  # init parent classes
78
114
  FinishTracker.__init__(self, checking_interval=checking_interval)
@@ -270,18 +306,17 @@ class BaseTask(FinishTracker, AttemptTracker, Renderer, BaseTaskModel, AnyTask):
270
306
  new_kwargs = self.get_input_map()
271
307
  # make sure args and kwargs['_args'] are the same
272
308
  self.log_info("Set run args")
273
- new_args = copy.deepcopy(args)
309
+ new_args = list(args)
274
310
  if len(args) == 0 and "_args" in kwargs:
275
311
  new_args = kwargs["_args"]
276
- new_kwargs["_args"] = new_args
277
- # inject self as input_map['_task']
278
- new_kwargs["_task"] = self
279
312
  self._set_args(new_args)
280
313
  self._set_kwargs(new_kwargs)
281
314
  # run the task
282
315
  coroutines = [
283
316
  asyncio.create_task(self._loop_check(show_done_info=show_done_info)),
284
- asyncio.create_task(self._run_all(*new_args, **new_kwargs)),
317
+ asyncio.create_task(
318
+ self._run_all(*new_args, _args=new_args, _task=self, **new_kwargs)
319
+ ),
285
320
  ]
286
321
  results = await asyncio.gather(*coroutines)
287
322
  result = results[-1]
@@ -456,7 +491,7 @@ class BaseTask(FinishTracker, AttemptTracker, Renderer, BaseTaskModel, AnyTask):
456
491
  # set current task local keyval
457
492
  await self._set_local_keyval(kwargs=kwargs, env_prefix=env_prefix)
458
493
  # get new_kwargs for upstream and checkers
459
- new_kwargs = copy.deepcopy(kwargs)
494
+ new_kwargs = {key: kwargs[key] for key in kwargs}
460
495
  new_kwargs.update(self.get_input_map())
461
496
  upstream_coroutines = []
462
497
  # set upstreams keyval
@@ -58,7 +58,7 @@ class BaseTaskModel(CommonTaskModel, PidModel, TimeTracker):
58
58
  upstreams: Iterable[AnyTask] = [],
59
59
  fallbacks: Iterable[AnyTask] = [],
60
60
  checkers: Iterable[AnyTask] = [],
61
- checking_interval: Union[int, float] = 0,
61
+ checking_interval: Union[int, float] = 0.05,
62
62
  run: Optional[Callable[..., Any]] = None,
63
63
  on_triggered: Optional[OnTriggered] = None,
64
64
  on_waiting: Optional[OnWaiting] = None,
@@ -49,7 +49,7 @@ class CommonTaskModel:
49
49
  upstreams: Iterable[AnyTask] = [],
50
50
  fallbacks: Iterable[AnyTask] = [],
51
51
  checkers: Iterable[AnyTask] = [],
52
- checking_interval: Union[float, int] = 0,
52
+ checking_interval: Union[float, int] = 0.05,
53
53
  run: Optional[Callable[..., Any]] = None,
54
54
  on_triggered: Optional[OnTriggered] = None,
55
55
  on_waiting: Optional[OnWaiting] = None,
zrb/task/checker.py CHANGED
@@ -44,7 +44,7 @@ class Checker(BaseTask):
44
44
  on_ready: Optional[OnReady] = None,
45
45
  on_retry: Optional[OnRetry] = None,
46
46
  on_failed: Optional[OnFailed] = None,
47
- checking_interval: Union[int, float] = 0,
47
+ checking_interval: Union[int, float] = 0.05,
48
48
  progress_interval: Union[int, float] = 30,
49
49
  expected_result: bool = True,
50
50
  should_execute: Union[bool, str, Callable[..., bool]] = True,
zrb/task/cmd_task.py CHANGED
@@ -125,7 +125,7 @@ class CmdTask(BaseTask):
125
125
  on_retry: Optional[OnRetry] = None,
126
126
  on_failed: Optional[OnFailed] = None,
127
127
  checkers: Iterable[AnyTask] = [],
128
- checking_interval: Union[float, int] = 0,
128
+ checking_interval: Union[float, int] = 0.05,
129
129
  retry: int = 2,
130
130
  retry_interval: Union[float, int] = 1,
131
131
  max_output_line: int = 1000,
zrb/task/decorator.py CHANGED
@@ -43,7 +43,7 @@ def python_task(
43
43
  on_retry: Optional[OnRetry] = None,
44
44
  on_failed: Optional[OnFailed] = None,
45
45
  checkers: Iterable[AnyTask] = [],
46
- checking_interval: Union[float, int] = 0,
46
+ checking_interval: Union[float, int] = 0.05,
47
47
  retry: int = 2,
48
48
  retry_interval: Union[float, int] = 1,
49
49
  should_execute: Union[bool, str, Callable[..., bool]] = True,
@@ -115,7 +115,7 @@ class DockerComposeTask(CmdTask):
115
115
  on_retry: Optional[OnRetry] = None,
116
116
  on_failed: Optional[OnFailed] = None,
117
117
  checkers: Iterable[AnyTask] = [],
118
- checking_interval: Union[float, int] = 0,
118
+ checking_interval: Union[float, int] = 0.05,
119
119
  retry: int = 2,
120
120
  retry_interval: Union[float, int] = 1,
121
121
  max_output_line: int = 1000,
zrb/task/flow_task.py CHANGED
@@ -45,27 +45,13 @@ class FlowTask(BaseTask):
45
45
  on_retry: Optional[OnRetry] = None,
46
46
  on_failed: Optional[OnFailed] = None,
47
47
  checkers: Iterable[AnyTask] = [],
48
- checking_interval: float = 0,
48
+ checking_interval: Union[float, int] = 0.05,
49
49
  retry: int = 2,
50
- retry_interval: float = 1,
50
+ retry_interval: Union[float, int] = 1,
51
51
  steps: List[Union[AnyTask, List[AnyTask]]] = [],
52
52
  should_execute: Union[bool, str, Callable[..., bool]] = True,
53
53
  return_upstream_result: bool = False,
54
54
  ):
55
- final_upstreams: List[AnyTask] = list(upstreams)
56
- inputs: List[AnyInput] = list(inputs)
57
- envs: List[Env] = list(envs)
58
- env_files: List[EnvFile] = list(env_files)
59
- for step in steps:
60
- tasks = self._step_to_tasks(step)
61
- new_upstreams = self._get_embeded_tasks(
62
- tasks=tasks,
63
- upstreams=final_upstreams,
64
- inputs=inputs,
65
- envs=envs,
66
- env_files=env_files,
67
- )
68
- final_upstreams = new_upstreams
69
55
  BaseTask.__init__(
70
56
  self,
71
57
  name=name,
@@ -76,7 +62,13 @@ class FlowTask(BaseTask):
76
62
  icon=icon,
77
63
  color=color,
78
64
  description=description,
79
- upstreams=final_upstreams,
65
+ upstreams=self._create_flow_upstreams(
66
+ steps=steps,
67
+ upstreams=list(upstreams),
68
+ inputs=list(inputs),
69
+ envs=list(envs),
70
+ env_files=list(env_files),
71
+ ),
80
72
  fallbacks=fallbacks,
81
73
  on_triggered=on_triggered,
82
74
  on_waiting=on_waiting,
@@ -97,12 +89,33 @@ class FlowTask(BaseTask):
97
89
  def copy(self) -> TFlowTask:
98
90
  return super().copy()
99
91
 
100
- def _step_to_tasks(self, node: Union[AnyTask, List[AnyTask]]) -> List[AnyTask]:
101
- if isinstance(node, AnyTask):
102
- return [node]
103
- return node
92
+ def _create_flow_upstreams(
93
+ self,
94
+ steps: List[Union[AnyTask, List[AnyTask]]],
95
+ upstreams: List[AnyTask],
96
+ inputs: List[AnyInput],
97
+ envs: List[Env],
98
+ env_files: List[EnvFile],
99
+ ) -> List[AnyTask]:
100
+ flow_upstreams = upstreams
101
+ for step in steps:
102
+ tasks = [task.copy() for task in self._step_to_tasks(step)]
103
+ new_upstreams = self._create_embeded_tasks(
104
+ tasks=tasks,
105
+ upstreams=flow_upstreams,
106
+ inputs=inputs,
107
+ envs=envs,
108
+ env_files=env_files,
109
+ )
110
+ flow_upstreams = new_upstreams
111
+ return flow_upstreams
112
+
113
+ def _step_to_tasks(self, step: Union[AnyTask, List[AnyTask]]) -> List[AnyTask]:
114
+ if isinstance(step, AnyTask):
115
+ return [step]
116
+ return step
104
117
 
105
- def _get_embeded_tasks(
118
+ def _create_embeded_tasks(
106
119
  self,
107
120
  tasks: List[AnyTask],
108
121
  upstreams: List[AnyTask],
@@ -111,28 +124,26 @@ class FlowTask(BaseTask):
111
124
  env_files: List[EnvFile],
112
125
  ) -> List[AnyTask]:
113
126
  embeded_tasks: List[AnyTask] = []
114
- for task in tasks:
115
- embeded_task = task.copy()
116
- embeded_task_root_upstreams = self._get_root_upstreams(tasks=[embeded_task])
117
- for embeded_task_root_upstream in embeded_task_root_upstreams:
118
- embeded_task_root_upstream.add_upstream(*upstreams)
119
- # embeded_task.add_upstream(*upstreams)
127
+ for embeded_task in tasks:
128
+ embeded_task_upstreams = self._get_all_upstreams(tasks=[embeded_task])
129
+ for embeded_task_upstream in embeded_task_upstreams:
130
+ embeded_task_upstream.add_upstream(*upstreams)
120
131
  embeded_task.add_env(*envs)
121
132
  embeded_task.add_env_file(*env_files)
122
133
  embeded_task.add_input(*inputs)
123
134
  embeded_tasks.append(embeded_task)
124
135
  return embeded_tasks
125
136
 
126
- def _get_root_upstreams(self, tasks: List[AnyTask]):
127
- root_upstreams = []
137
+ def _get_all_upstreams(self, tasks: List[AnyTask]):
138
+ all_upstreams = []
128
139
  for task in tasks:
129
140
  upstreams = task._get_upstreams()
130
141
  if len(upstreams) == 0:
131
- root_upstreams.append(task)
142
+ all_upstreams.append(task)
132
143
  continue
133
144
  for upstream in upstreams:
134
145
  if len(upstream._get_upstreams()) == 0:
135
- root_upstreams.append(upstream)
146
+ all_upstreams.append(upstream)
136
147
  continue
137
- root_upstreams += self._get_root_upstreams([upstream])
138
- return root_upstreams
148
+ all_upstreams += self._get_all_upstreams([upstream])
149
+ return all_upstreams
zrb/task/http_checker.py CHANGED
@@ -87,7 +87,7 @@ class HTTPChecker(Checker):
87
87
  on_ready: Optional[OnReady] = None,
88
88
  on_retry: Optional[OnRetry] = None,
89
89
  on_failed: Optional[OnFailed] = None,
90
- checking_interval: Union[int, float] = 0,
90
+ checking_interval: Union[int, float] = 0.05,
91
91
  progress_interval: Union[int, float] = 5,
92
92
  expected_result: bool = True,
93
93
  should_execute: Union[bool, JinjaTemplate, Callable[..., bool]] = True,
zrb/task/notifier.py CHANGED
@@ -58,7 +58,7 @@ class Notifier(BaseTask):
58
58
  on_ready: Optional[OnReady] = None,
59
59
  on_retry: Optional[OnRetry] = None,
60
60
  on_failed: Optional[OnFailed] = None,
61
- checking_interval: Union[int, float] = 0,
61
+ checking_interval: Union[int, float] = 0.05,
62
62
  retry: int = 2,
63
63
  retry_interval: Union[float, int] = 1,
64
64
  should_execute: Union[bool, str, Callable[..., bool]] = True,
zrb/task/path_checker.py CHANGED
@@ -56,7 +56,7 @@ class PathChecker(Checker):
56
56
  on_failed: Optional[OnFailed] = None,
57
57
  path: JinjaTemplate = "",
58
58
  ignored_path: Union[JinjaTemplate, Iterable[JinjaTemplate]] = [],
59
- checking_interval: Union[int, float] = 0,
59
+ checking_interval: Union[int, float] = 0.05,
60
60
  progress_interval: Union[int, float] = 5,
61
61
  expected_result: bool = True,
62
62
  should_execute: Union[bool, JinjaTemplate, Callable[..., bool]] = True,
zrb/task/path_watcher.py CHANGED
@@ -72,7 +72,7 @@ class PathWatcher(Watcher):
72
72
  on_failed: Optional[OnFailed] = None,
73
73
  path: JinjaTemplate = "",
74
74
  ignored_path: Union[JinjaTemplate, Iterable[JinjaTemplate]] = [],
75
- checking_interval: Union[int, float] = 0,
75
+ checking_interval: Union[int, float] = 0.05,
76
76
  progress_interval: Union[int, float] = 30,
77
77
  watch_new_files: bool = True,
78
78
  watch_modified_files: bool = True,
zrb/task/port_checker.py CHANGED
@@ -66,7 +66,7 @@ class PortChecker(Checker):
66
66
  on_ready: Optional[OnReady] = None,
67
67
  on_retry: Optional[OnRetry] = None,
68
68
  on_failed: Optional[OnFailed] = None,
69
- checking_interval: Union[int, float] = 0,
69
+ checking_interval: Union[int, float] = 0.05,
70
70
  progress_interval: Union[int, float] = 5,
71
71
  expected_result: bool = True,
72
72
  should_execute: Union[bool, str, Callable[..., bool]] = True,
@@ -76,7 +76,7 @@ class RecurringTask(BaseTask):
76
76
  on_retry: Optional[OnRetry] = None,
77
77
  on_failed: Optional[OnFailed] = None,
78
78
  checkers: Iterable[AnyTask] = [],
79
- checking_interval: float = 0,
79
+ checking_interval: float = 0.05,
80
80
  retry: int = 0,
81
81
  retry_interval: float = 1,
82
82
  should_execute: Union[bool, str, Callable[..., bool]] = True,
@@ -185,7 +185,7 @@ class RecurringTask(BaseTask):
185
185
  async def __run_from_queue(self):
186
186
  while True:
187
187
  if len(self._run_configs) == 0:
188
- await asyncio.sleep(0.1)
188
+ await asyncio.sleep(0.05)
189
189
  continue
190
190
  if self._single_execution:
191
191
  # Drain the queue, leave only the latest task
@@ -66,7 +66,7 @@ class RemoteCmdTask(BaseRemoteCmdTask):
66
66
  on_retry: Optional[OnRetry] = None,
67
67
  on_failed: Optional[OnFailed] = None,
68
68
  checkers: Iterable[AnyTask] = [],
69
- checking_interval: Union[float, int] = 0,
69
+ checking_interval: Union[float, int] = 0.05,
70
70
  retry: int = 2,
71
71
  retry_interval: Union[float, int] = 1,
72
72
  max_output_line: int = 1000,
@@ -123,7 +123,7 @@ class ResourceMaker(BaseTask):
123
123
  on_retry=on_retry,
124
124
  on_failed=on_failed,
125
125
  checkers=[],
126
- checking_interval=0.1,
126
+ checking_interval=0.05,
127
127
  retry=0,
128
128
  retry_interval=0,
129
129
  should_execute=should_execute,
zrb/task/rsync_task.py CHANGED
@@ -69,7 +69,7 @@ class RsyncTask(BaseRemoteCmdTask):
69
69
  on_retry: Optional[OnRetry] = None,
70
70
  on_failed: Optional[OnFailed] = None,
71
71
  checkers: Iterable[AnyTask] = [],
72
- checking_interval: Union[float, int] = 0,
72
+ checking_interval: Union[float, int] = 0.05,
73
73
  retry: int = 2,
74
74
  retry_interval: Union[float, int] = 1,
75
75
  max_output_line: int = 1000,
zrb/task/server.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import asyncio
2
+ import copy
2
3
 
3
4
  from zrb.helper.accessories.color import colored
4
5
  from zrb.helper.accessories.name import get_random_name
@@ -35,8 +36,8 @@ class Controller:
35
36
  name: Optional[str] = None,
36
37
  ):
37
38
  self._name = get_random_name() if name is None else name
38
- self._triggers = [trigger] if isinstance(trigger, AnyTask) else trigger
39
- self._actions = [action] if isinstance(action, AnyTask) else action
39
+ self._triggers = self._to_task_list(trigger)
40
+ self._actions = self._to_task_list(action)
40
41
  self._args: List[Any] = []
41
42
  self._kwargs: Mapping[str, Any] = {}
42
43
  self._inputs: List[AnyInput] = []
@@ -58,28 +59,28 @@ class Controller:
58
59
  def set_env_files(self, env_files: List[EnvFile]):
59
60
  self._env_files = env_files
60
61
 
61
- def get_sub_env_files(self) -> Iterable[EnvFile]:
62
+ def get_original_env_files(self) -> Iterable[EnvFile]:
62
63
  env_files = []
63
64
  for trigger in self._triggers:
64
- env_files += trigger.copy()._get_env_files()
65
+ env_files += trigger._get_env_files()
65
66
  for action in self._actions:
66
- env_files += action.copy()._get_env_files()
67
+ env_files += action._get_env_files()
67
68
  return env_files
68
69
 
69
- def get_sub_envs(self) -> Iterable[Env]:
70
+ def get_original_envs(self) -> Iterable[Env]:
70
71
  envs = []
71
72
  for trigger in self._triggers:
72
- envs += trigger.copy()._get_envs()
73
+ envs += trigger._get_envs()
73
74
  for action in self._actions:
74
- envs += action.copy()._get_envs()
75
+ envs += action._get_envs()
75
76
  return envs
76
77
 
77
- def get_sub_inputs(self) -> Iterable[AnyInput]:
78
+ def get_original_inputs(self) -> Iterable[AnyInput]:
78
79
  inputs = []
79
80
  for trigger in self._triggers:
80
- inputs += trigger.copy()._get_combined_inputs()
81
+ inputs += trigger._get_combined_inputs()
81
82
  for action in self._actions:
82
- inputs += action.copy()._get_combined_inputs()
83
+ inputs += action._get_combined_inputs()
83
84
  return inputs
84
85
 
85
86
  def to_function(self) -> Callable[..., Any]:
@@ -92,6 +93,11 @@ class Controller:
92
93
 
93
94
  return fn
94
95
 
96
+ def _to_task_list(self, tasks: Union[AnyTask, List[AnyTask]]) -> List[AnyTask]:
97
+ if isinstance(tasks, AnyTask):
98
+ return [tasks.copy()]
99
+ return [task.copy() for task in tasks]
100
+
95
101
  def _get_task(self) -> AnyTask:
96
102
  actions = [action.copy() for action in self._actions]
97
103
  actions.insert(0, self._get_remonitor_task())
@@ -141,17 +147,18 @@ class Server(BaseTask):
141
147
  on_retry: Optional[OnRetry] = None,
142
148
  on_failed: Optional[OnFailed] = None,
143
149
  checkers: Iterable[AnyTask] = [],
144
- checking_interval: float = 0,
150
+ checking_interval: Union[int, float] = 0.05,
145
151
  retry: int = 0,
146
- retry_interval: float = 1,
152
+ retry_interval: Union[int, float] = 1,
147
153
  should_execute: Union[bool, str, Callable[..., bool]] = True,
148
154
  return_upstream_result: bool = False,
149
155
  ):
150
156
  inputs, envs, env_files = list(inputs), list(envs), list(env_files)
151
157
  for controller in controllers:
152
- inputs += controller.get_sub_inputs()
153
- envs += controller.get_sub_envs()
154
- env_files += controller.get_sub_env_files()
158
+ controller_cp = copy.deepcopy(controller)
159
+ inputs += controller_cp.get_original_inputs()
160
+ envs += controller_cp.get_original_envs()
161
+ env_files += controller_cp.get_original_env_files()
155
162
  BaseTask.__init__(
156
163
  self,
157
164
  name=name,
zrb/task/task.py CHANGED
@@ -9,7 +9,41 @@ logger.debug(colored("Loading zrb.task.task", attrs=["dark"]))
9
9
  @typechecked
10
10
  class Task(BaseTask):
11
11
  """
12
- Alias for BaseTask.
12
+ Task is the smallest Zrb automation unit.
13
+
14
+ You can configure a Task by using several interfaces:
15
+ - `inputs`: interfaces to read user input at the beginning of the execution.
16
+ - `envs`: interfaces to read and use OS Environment Variables.
17
+ - `env_files`: interfaces to read and use Environment Files.
18
+
19
+ Moreover, you can define Task dependencies by specifying its `upstreams` or by using shift-right operator.
20
+
21
+ Every Task has its own life-cycle state:
22
+ - `Triggered`: The Task is triggered.
23
+ - `Waiting`: The Task is waiting for all it's upstreams to be ready.
24
+ - `Skipped`: The Task is not executed and will immediately enter the `Ready` state.
25
+ - `Started`: The Task execution is started.
26
+ - `Failed`: The Task execution is failed. It will enter the `Retry` state if the current attempt is less than the maximum attempt.
27
+ - `Retry`: The task will be restarted.
28
+ - `Ready`: The task is ready.
29
+
30
+ There are several configurations related to Task's life cycle:
31
+ - `retry`: How many retries should be attempted.
32
+ - `retry_interval`: How long to wait before the next retry attempt.
33
+ - `fallbacks`: What to do if the Task is failed and no retry attempt will be performed.
34
+ - `checkers`: How to determine if a Task is `Ready`.
35
+ - `checking_interval`: How long to wait before checking for Task's readiness.
36
+ - `run`: What a Task should do.
37
+ - `on_triggered`: What to do when a Task is `Triggered`.
38
+ - `on_waiting`: What to do when a Task is `Waiting`.
39
+ - `on_skipped`: What to do when a Task is `Skipped`.
40
+ - `on_started`: What to do when a Task is `Started`.
41
+ - `on_ready`: What to do when a Task is `Ready`.
42
+ - `on_retry`: What to do when a Task is `Retry`.
43
+ - `on_failed`: What to do when a Task is `Failed`.
44
+ - `should_execute`: Whether a Task should be `Started` or not (`Skipped`).
45
+
46
+ Finally, you can put related Tasks under the same `group`.
13
47
  """
14
48
 
15
49
  pass
zrb/task/time_watcher.py CHANGED
@@ -68,7 +68,7 @@ class TimeWatcher(Watcher):
68
68
  on_retry: Optional[OnRetry] = None,
69
69
  on_failed: Optional[OnFailed] = None,
70
70
  schedule: JinjaTemplate = "",
71
- checking_interval: Union[int, float] = 0,
71
+ checking_interval: Union[int, float] = 0.05,
72
72
  progress_interval: Union[int, float] = 30,
73
73
  should_execute: Union[bool, JinjaTemplate, Callable[..., bool]] = True,
74
74
  ):
zrb/task/watcher.py CHANGED
@@ -2,6 +2,7 @@ import asyncio
2
2
 
3
3
  from zrb.helper.accessories.color import colored
4
4
  from zrb.helper.accessories.name import get_random_name
5
+ from zrb.helper.callable import run_async
5
6
  from zrb.helper.log import logger
6
7
  from zrb.helper.typecheck import typechecked
7
8
  from zrb.helper.typing import Any, Callable, Iterable, Optional, Union
@@ -48,7 +49,7 @@ class Watcher(Checker):
48
49
  on_ready: Optional[OnReady] = None,
49
50
  on_retry: Optional[OnRetry] = None,
50
51
  on_failed: Optional[OnFailed] = None,
51
- checking_interval: Union[int, float] = 0,
52
+ checking_interval: Union[int, float] = 0.05,
52
53
  progress_interval: Union[int, float] = 30,
53
54
  expected_result: bool = True,
54
55
  should_execute: Union[bool, str, Callable[..., bool]] = True,
@@ -85,7 +86,9 @@ class Watcher(Checker):
85
86
  async def run(self, *args: Any, **kwargs: Any) -> bool:
86
87
  if not looper.is_registered(self._identifier):
87
88
  asyncio.create_task(
88
- looper.register(self._identifier, self.create_loop_inspector())
89
+ run_async(
90
+ looper.register, self._identifier, self.create_loop_inspector()
91
+ )
89
92
  )
90
93
  return await super().run(*args, **kwargs)
91
94
 
zrb/task_env/env.py CHANGED
@@ -15,8 +15,9 @@ logger.debug(colored("Loading zrb.task_env.env", attrs=["dark"]))
15
15
  @typechecked
16
16
  class Env:
17
17
  """
18
- Env Represents an environment configuration for a task, encapsulating details such as environment name, OS-specific
19
- environment name, default values, and rendering behavior.
18
+ Env is an interface for a Task to read and use OS Environment Variable.
19
+
20
+ Env encapsulating details such as environment name, OS environment name, default values, and rendering behavior.
20
21
 
21
22
  Attributes:
22
23
  name (str): Environment name as recognized by the task.
@@ -77,7 +78,7 @@ class Env:
77
78
 
78
79
  def should_render(self) -> bool:
79
80
  """
80
- Determines whether the environment value should be rendered.
81
+ Retrieves whether the environment value should be rendered.
81
82
 
82
83
  Returns:
83
84
  bool: True if the environment value should be rendered, False otherwise.
zrb/task_env/env_file.py CHANGED
@@ -16,8 +16,9 @@ logger.debug(colored("Loading zrb.task_env.env_file", attrs=["dark"]))
16
16
  @typechecked
17
17
  class EnvFile:
18
18
  """
19
- Represents a handler for an environment file, facilitating the creation and management of environment variables
20
- (Env objects) based on the contents of the specified environment file.
19
+ Env is an interface for a Task to read and use OS Environment File.
20
+
21
+ Under the hood, EnvFile creates list of Env based on its `path` property.
21
22
 
22
23
  Attributes:
23
24
  path (str): The path to the environment file.
zrb/task_group/group.py CHANGED
@@ -15,7 +15,7 @@ TGroup = TypeVar("TGroup", bound="Group")
15
15
  @typechecked
16
16
  class Group:
17
17
  """
18
- Represents a group of tasks and subgroups, facilitating organization and hierarchy.
18
+ Group is an umbrella of several related Tasks or sub-groups, facilitating organization and hierarchy.
19
19
 
20
20
  This class allows the creation of a hierarchical structure by grouping tasks and
21
21
  other task groups together. It provides methods to add tasks, retrieve tasks,
@@ -11,10 +11,12 @@ logger.debug(colored("Loading zrb.task_input.any_input", attrs=["dark"]))
11
11
 
12
12
  class AnyInput(ABC):
13
13
  """
14
- Abstract base class representing a generalized input specification.
15
- This class serves as a template for creating various input types,
16
- providing a standardized interface for input handling and processing.
14
+ Abstraction for Zrb Input.
17
15
 
16
+ This class acts as a template for creating new Inputs.
17
+
18
+ To define a new Input type, you should extend this class and implement all its methods.
19
+ The easiest way to do so is by extending `Input`
18
20
  """
19
21
 
20
22
  @abstractmethod
@@ -14,9 +14,9 @@ logger.debug(colored("Loading zrb.task_input.base_input", attrs=["dark"]))
14
14
  @typechecked
15
15
  class BaseInput(AnyInput):
16
16
  """
17
- A concrete implementation of the AnyInput abstract base class, representing a specific type of task input.
18
- This class allows for the creation of interactive and configurable inputs for tasks, with various attributes
19
- to customize its behavior and appearance.
17
+ Base class for all Input.
18
+
19
+ Input is an interface for a Task to read user input at the beginning of the execution.
20
20
 
21
21
  Attributes:
22
22
  name (str): The name of the input, used as a unique identifier.
@@ -9,7 +9,7 @@ logger.debug(colored("Loading zrb.task_input.task_input", attrs=["dark"]))
9
9
 
10
10
  class Input(BaseInput):
11
11
  """
12
- Alias for BaseInput
12
+ Input is an interface for a Task to read user input at the beginning of the execution.
13
13
 
14
14
  Attributes:
15
15
  name (str): The name of the input, used as a unique identifier.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zrb
3
- Version: 0.17.2
3
+ Version: 0.17.5
4
4
  Summary: A Framework to Enhance Your Workflow
5
5
  Home-page: https://github.com/state-alchemists/zrb
6
6
  License: AGPL-3.0-or-later
@@ -33,7 +33,7 @@ Description-Content-Type: text/markdown
33
33
  ![](https://raw.githubusercontent.com/state-alchemists/zrb/main/_images/zrb/android-chrome-192x192.png)
34
34
 
35
35
 
36
- [🫰 Installation](https://github.com/state-alchemists/zrb/blob/main/docs/installation.md) | [📖 Documentation](https://github.com/state-alchemists/zrb/blob/main/docs/README.md) | [🏁 Getting Started](https://github.com/state-alchemists/zrb/blob/main/docs/getting-started.md) | [💃 Common Mistakes](https://github.com/state-alchemists/zrb/blob/main/docs/oops-i-did-it-again/README.md) | [❓ FAQ](https://github.com/state-alchemists/zrb/blob/main/docs/faq/README.md)
36
+ [🫰 Installation](https://github.com/state-alchemists/zrb/blob/main/docs/installation.md) | [📖 Documentation](https://github.com/state-alchemists/zrb/blob/main/docs/README.md) | [🏁 Getting Started](https://github.com/state-alchemists/zrb/blob/main/docs/getting-started.md) | [💃 Common Mistakes](https://github.com/state-alchemists/zrb/blob/main/docs/common-mistakes/README.md) | [❓ FAQ](https://github.com/state-alchemists/zrb/blob/main/docs/faq/README.md)
37
37
 
38
38
 
39
39
  # 🤖 Zrb: A Framework to Enhance Your Workflow
@@ -43,11 +43,12 @@ Zrb is a [CLI-based](https://en.wikipedia.org/wiki/Command-line_interface) autom
43
43
  - __Automate__ day-to-day tasks.
44
44
  - __Generate__ projects or applications.
45
45
  - __Prepare__, __run__, and __deploy__ your applications with a single command.
46
- - Etc.
46
+ - Deliver __faster__ with __fewer human errors__.
47
47
 
48
- You can also write custom task definitions in [Python](https://www.python.org/), enhancing Zrb's base capabilities. Defining your tasks in Zrb gives you several advantages because:
48
+ Zrb allows you to write custom task definitions in [Python](https://www.python.org/), further enhancing Zrb's capabilities. Defining your tasks in Zrb gives you several advantages because:
49
49
 
50
- - Every task has a __retry mechanism__.
50
+ - Every Zrb Task has a __retry mechanism__.
51
+ - Every Zrb Task is __configurable__ via __environment variables__ or __user inputs__.
51
52
  - Zrb handles your __task dependencies__ automatically.
52
53
  - Zrb runs your task dependencies __concurrently__.
53
54
 
@@ -85,7 +86,9 @@ Download Datasets ──┘
85
86
  ⬇️
86
87
  ```
87
88
 
88
- You can create a file named `zrb_init.py` and define the tasks as follows:
89
+ Zrb Task is the smallest automation unit. You can configure a Zrb Task using user input (`inputs`) or environment variables (`envs` or `env_files`). Every Zrb Task has a configurable `retry` mechanism. Moreover, you can also define Zrb Task dependencies using the shift right operator `>>` or `upstreams` parameter.
90
+
91
+ You can create a file named `zrb_init.py` and define your Zrb Tasks as follows:
89
92
 
90
93
  ```python
91
94
  # File name: zrb_init.py
@@ -129,7 +132,7 @@ def show_stats(*args, **kwargs):
129
132
  # Define dependencies: `show_stat` depends on both, `download_dataset` and `install_pandas`
130
133
  Parallel(download_dataset, install_pandas) >> show_stats
131
134
 
132
- # Register the tasks so that they are accessbie from the CLI
135
+ # Register the tasks so that they are accessble from the CLI
133
136
  runner.register(install_pandas, download_dataset, show_stats)
134
137
  ```
135
138
 
@@ -286,15 +289,15 @@ Visit [our tutorials](https://github.com/state-alchemists/zrb/blob/main/docs/tut
286
289
  - [🫰 Installation](https://github.com/state-alchemists/zrb/blob/main/docs/installation.md)
287
290
  - [🏁 Getting Started](https://github.com/state-alchemists/zrb/blob/main/docs/getting-started.md)
288
291
  - [📖 Documentation](https://github.com/state-alchemists/zrb/blob/main/docs/README.md)
289
- - [💃 Common Mistakes](https://github.com/state-alchemists/zrb/blob/main/docs/oops-i-did-it-again/README.md)
292
+ - [💃 Common Mistakes](https://github.com/state-alchemists/zrb/blob/main/docs/common-mistakes/README.md)
290
293
  - [❓ FAQ](https://github.com/state-alchemists/zrb/blob/main/docs/faq/README.md)
291
294
 
292
295
  # 🐞 Bug Report + Feature Request
293
296
 
294
- You can submit bug report and feature request by creating a new [issue](https://github.com/state-alchemists/zrb/issues) on Zrb Github Repositories. When reporting a bug or requesting a feature, please be sure to:
297
+ You can submit bug reports and feature requests by creating a new [issue](https://github.com/state-alchemists/zrb/issues) on Zrb's GitHub Repositories. When reporting a bug or requesting a feature, please be sure to:
295
298
 
296
299
  - Include the version of Zrb you are using (i.e., `zrb version`)
297
- - Tell us what you have try
300
+ - Tell us what you have tried
298
301
  - Tell us what you expect
299
302
  - Tell us what you get
300
303
 
@@ -326,7 +329,7 @@ We are thankful for the following libraries and services. They accelerate Zrb de
326
329
  - [Jsons](https://pypi.org.project/jsons/): Parse JSON. This package should be part of the standard library.
327
330
  - [Libcst](https://pypi.org/project/libcst/): Turn Python code into a Concrete Syntax Tree.
328
331
  - [Croniter](https://pypi.org/project/croniter/): Parse cron pattern.
329
- - [Flit](https://pypi.org/project/flit), [Twine](https://pypi.org/project/twine/), and many more. See the complete list of Zrb's requirements.txt
332
+ - [Poetry](https://pypi.org/project/poetry), [flake8](https://pypi.org/project/flake8/), [black](https://pypi.org/project/black), [isort](https://pypi.org/project/isort), and many more. See the complete list of Zrb's [pyproject.toml](https://github.com/state-alchemists/zrb/blob/main/pyproject.toml)
330
333
  - Services
331
334
  - [asciiflow.com](https://asciiflow.com/): Creates beautiful ASCII-based diagrams.
332
335
  - [emojipedia.org](https://emojipedia.org/): Find emoji.
@@ -965,7 +965,7 @@ zrb/builtin/project/add/fastapp/app/template/src/kebab-zrb-app-name/src/componen
965
965
  zrb/builtin/project/add/fastapp/app/template/src/kebab-zrb-app-name/src/component/repo/search_filter.py,sha256=lYquQLR4_qr43AlKGNBBNzcGOEOASQHteuLdiewOBoE,147
966
966
  zrb/builtin/project/add/fastapp/app/template/src/kebab-zrb-app-name/src/component/rpc/__init__.py,sha256=i5QOPDiwAwp0EskPSVwJDuVH6pq_DWRi3XN1hMFFw4A,244
967
967
  zrb/builtin/project/add/fastapp/app/template/src/kebab-zrb-app-name/src/component/rpc/messagebus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
968
- zrb/builtin/project/add/fastapp/app/template/src/kebab-zrb-app-name/src/component/rpc/messagebus/caller.py,sha256=4C6bDNUm-cL-G_5R-GdaSCXht_bJM5q8lelnVftCdaQ,3201
968
+ zrb/builtin/project/add/fastapp/app/template/src/kebab-zrb-app-name/src/component/rpc/messagebus/caller.py,sha256=P90X3d6et457EwD4NohOsPNIcz9lFQmzqTbZubmR9aA,3202
969
969
  zrb/builtin/project/add/fastapp/app/template/src/kebab-zrb-app-name/src/component/rpc/messagebus/server.py,sha256=KFVErPpkRDetDokMAR16thaKtOTqk_xRp4lmM1iQNFo,2197
970
970
  zrb/builtin/project/add/fastapp/app/template/src/kebab-zrb-app-name/src/component/rpc/rpc.py,sha256=obJ8ksA9Io5nRpGoTQE506hj82dPwRZIUWTq2JEOLRo,1625
971
971
  zrb/builtin/project/add/fastapp/app/template/src/kebab-zrb-app-name/src/component/schema/__init__.py,sha256=g1CrqtQukcTOnNaKFLj6j-iVaNQ_cvpmdzROtbeteck,127
@@ -1355,46 +1355,46 @@ zrb/shell-scripts/notify.ps1,sha256=6_xPoIwuxARpYljcjVV-iRJS3gJqGfx-B6kj719cJ9o,
1355
1355
  zrb/shell-scripts/rsync-util.sh,sha256=QzdhSBvUNMxB4U2B4m0Dxg9czGckRjB7Vk4A1ObG0-k,353
1356
1356
  zrb/shell-scripts/ssh-util.sh,sha256=9lXDzw6oO8HuA4vdbfps_uQMMwKyNYX9fZkZgpK52g8,401
1357
1357
  zrb/task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1358
- zrb/task/any_task.py,sha256=lzCbrpm6Mo_isNW7KuHK7Rq0t59_9z0oOLAtaJYCEdg,39214
1358
+ zrb/task/any_task.py,sha256=hrgsYikSe_C6JDSWeHNGCCvefNrkVioJWUunrqSFGLE,39199
1359
1359
  zrb/task/any_task_event_handler.py,sha256=AjTC6lIcprutRusNBGl83EifQe4TbZzxdlVIR4ndWN4,524
1360
- zrb/task/base_remote_cmd_task.py,sha256=tZi3jODMXfTkDAmWiFR2YdA-b4-TDTP1uLtO0ulmM34,10101
1360
+ zrb/task/base_remote_cmd_task.py,sha256=P-F4y8_tq4d6UFPy8lXoRq8DPFjRr4FQQcTaImaqa3I,10102
1361
1361
  zrb/task/base_task/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1362
- zrb/task/base_task/base_task.py,sha256=3kwrxjz5EPRpBp2HAhdRHdgRDgyDTak01C6fQMjU1Pw,20446
1362
+ zrb/task/base_task/base_task.py,sha256=BsJ6iqi05Y-3YPuGdpGcogPN9wqScSxiWrCGB_LtWGM,22325
1363
1363
  zrb/task/base_task/component/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1364
- zrb/task/base_task/component/base_task_model.py,sha256=YlEuvYSzlrK83Kds07bu2drKSw3rKyl7qIR1qwIPNZk,10376
1365
- zrb/task/base_task/component/common_task_model.py,sha256=JoAAf8EvuPx31fCK_TBxX_TBeHZrZyFDjLeK8ts0w3A,12285
1364
+ zrb/task/base_task/component/base_task_model.py,sha256=i6TrtTusZ71ZnOnx8yM0aJl8uF6R1hKdAf62bEdpdCs,10379
1365
+ zrb/task/base_task/component/common_task_model.py,sha256=h81BGqplsaWJCQl0Zigl24LLkCUKPEfJikSbITREQnM,12288
1366
1366
  zrb/task/base_task/component/pid_model.py,sha256=RjJIqOpavucDssnd3q3gT4q8QnP8I9SUdlv1b9pR7kU,292
1367
1367
  zrb/task/base_task/component/renderer.py,sha256=9wP2IW811Ta81IoPWmeQ7yVc7eG-uaSnOVbEyeaOIuk,4439
1368
1368
  zrb/task/base_task/component/trackers.py,sha256=c5xhZ6agICxKPI5Va1sn66_9OqC92ebF5CNhcwVUNUE,2074
1369
- zrb/task/checker.py,sha256=Y8WnIZM23fGqZpxHw2Bnk5jb0MmEMS598WZiEB8OUFU,3381
1370
- zrb/task/cmd_task.py,sha256=_wjF9MbKGA0EAr_df47AMC0lROCiaJTUyxT-AFQKKJo,14181
1371
- zrb/task/decorator.py,sha256=WInQrxuVlejvZEGIiBMfkiMa0I5rT9lWRGjyyLu_hzw,3061
1372
- zrb/task/docker_compose_task.py,sha256=Cgk9ROW_xSnSYV0x1E2Xo1AphFoota-omrtLPocDaOU,14908
1373
- zrb/task/flow_task.py,sha256=QIIZgq9C7e-kvTRJ0Y1Slb5AQyy15N9H4NZxdFR3FI8,4867
1374
- zrb/task/http_checker.py,sha256=mStzoRlcDWCyeIP4sRAQSns_U_nEp19qYYE-DONZaA8,5690
1369
+ zrb/task/checker.py,sha256=raYNBHgeyEqkyfBRsPPgSV7ukEfMlJOCUn97WQNl6mU,3384
1370
+ zrb/task/cmd_task.py,sha256=Bfu29x5Cy10gCazIItCEOzrafU7r7z5WlWS4_wD7Znk,14184
1371
+ zrb/task/decorator.py,sha256=stxrl6aXbuUDK83lVf8m8uni3Ii6egLl0TCR0vxslUQ,3064
1372
+ zrb/task/docker_compose_task.py,sha256=hUKF7W3GwxFuEWmlPPFxa7h8npEnig2sm7KjlidHFBI,14911
1373
+ zrb/task/flow_task.py,sha256=QBOoyIrqc6ToSf3RF8xu8h4yxCWCerUAu2Ba0GxAqgg,5147
1374
+ zrb/task/http_checker.py,sha256=y0cWa2t4YtGQr6FWno5sZ6Ej9gQiLDF-Z1kLU1rijRw,5693
1375
1375
  zrb/task/looper.py,sha256=0eM3wEIC_RbThg60MRbK4Az16vt81O5p12cORAYTfnI,1430
1376
- zrb/task/notifier.py,sha256=19E4EcFgFZ0thU9p2P1dGUYR04721pa0K3lqsj6a4Xc,6217
1376
+ zrb/task/notifier.py,sha256=GbvnndQ-3-1vfGpOIIQ0IMS1ddqDxzgTSYThs_zg1xU,6220
1377
1377
  zrb/task/parallel.py,sha256=-coMuiFlS29GpBgW6plPVaCLesgzzD0bYib29OvhXFg,1193
1378
- zrb/task/path_checker.py,sha256=Jn7tnaUiPUbWOPAH3TUgzaa9_uiU0dPkpKCkr2Tlruc,4671
1379
- zrb/task/path_watcher.py,sha256=xoQxfgsGDxzywPPFS2RirtwrK9-cnm_TCTabZRhZr84,7418
1380
- zrb/task/port_checker.py,sha256=KE1fr0NBiUCLplDOHot8RzPBP1h_BvxFzHIZiEOuGaM,4590
1381
- zrb/task/recurring_task.py,sha256=FNxV7n4h9AzUCU8oKXwAS_A9j1newS-esWjmMsC33vE,7430
1382
- zrb/task/remote_cmd_task.py,sha256=rmLB5uCcbbfZBy8-nAZI8mgnNd-J2d4SBemLEDwSlV4,3951
1383
- zrb/task/resource_maker.py,sha256=jQSO7PVIuTZi__JcrpRC4Ni_xmuJszJiMAxH_qfJPhs,7644
1384
- zrb/task/rsync_task.py,sha256=bgCeZQTG-4isvjZGGs_05oOEkkwGc930NTyuUYUm_cg,4187
1385
- zrb/task/server.py,sha256=w0gO73tt9PLWXVtgY-oe6qzvODtxVcizBGCUjRrhp5w,6478
1386
- zrb/task/task.py,sha256=dHv4cmnd0QFPT9PwrfmHpxTaXj86mm8xf7_jAj_engI,329
1387
- zrb/task/time_watcher.py,sha256=m0OKCtYHzO8nz-bmp-PuaHpmGwhPzy2riikjol-_7ZA,5119
1388
- zrb/task/watcher.py,sha256=2dxWgwSK8CrhiNF2JF1S9Pe_BXZPlfxU88n495vlIuY,3250
1378
+ zrb/task/path_checker.py,sha256=SHpwtlS5YbO1jFGNnP7SuswkuDNHMOy52Fr4IzdIG98,4674
1379
+ zrb/task/path_watcher.py,sha256=x2SdgdgaZm2wiAyfBJoMVa625ufHtf8oHKmKhhEqAQk,7421
1380
+ zrb/task/port_checker.py,sha256=Za02E0xzR7xvHEujxuPszaydJCpwl_hJa1S9U4j25XQ,4593
1381
+ zrb/task/recurring_task.py,sha256=6JN7YkAY-NQ_zU2EAzqaQAxvfkGssbxvzNtL_foNA3Q,7434
1382
+ zrb/task/remote_cmd_task.py,sha256=DzAt5Vq8YekqAfu9PflGP0XcdLWX_gLKI64dGVgtL6s,3954
1383
+ zrb/task/resource_maker.py,sha256=wvq8Gv11epA_OYeLY071hIfFYkJ0rMcmcnXUAbd3TRg,7645
1384
+ zrb/task/rsync_task.py,sha256=kusVfttM1H0OEpNpLuU1I25MqChYaJeZDNZiXWtuVbA,4190
1385
+ zrb/task/server.py,sha256=q0RS-H1FWZaeT-mHLsbRx_D2bU-CZP0W3VVIx2KkaL8,6721
1386
+ zrb/task/task.py,sha256=DOomim37qnVVE4neWCJhHvAIkAN_h3QGFzvH-BrGTEI,2240
1387
+ zrb/task/time_watcher.py,sha256=D3_rr5Dlaw8xOg9iZMAGzPiEC2VDvIIvNTluQsZeBHo,5122
1388
+ zrb/task/watcher.py,sha256=7yDAS7kxST4Gd_PLyg_7XU6uXed5qbojE-B5X5z9EY4,3344
1389
1389
  zrb/task/wiki_task.py,sha256=Mcugk_6Pd7pzubi2ZP4eegJs8e9niYKh-9mCrNHXE_g,4330
1390
1390
  zrb/task_env/constant.py,sha256=ySdHv2dawWE-UoeBHl8FEOmrBl4vfkRI67TIBdkK6l8,220
1391
- zrb/task_env/env.py,sha256=C9IzavEtWlpap4C92XONi1ID-RK9gDDLQKl5rYGBsyc,5195
1392
- zrb/task_env/env_file.py,sha256=NkPOjxi8lrvBjB13kc9LU3ODvjGsdw3sSGOyC9-GnzE,3087
1391
+ zrb/task_env/env.py,sha256=WoxPlUgD33p6-y2EJU0oXAXBAnPL65k55hAbv6kO-Zs,5206
1392
+ zrb/task_env/env_file.py,sha256=D5cHJBY1DFcBa3KI3ujTe7Gxk7y_WB1zXCzkZNlDexE,3047
1393
1393
  zrb/task_group/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1394
- zrb/task_group/group.py,sha256=RmYpnh1UGiCi0vKYoqLwlCmJzC5-VKkMgDrVR2y3wsk,6091
1394
+ zrb/task_group/group.py,sha256=uF3tyLABTyyBNyE9FUCfJeYSDnaLFQCis3tuEn5FYho,6109
1395
1395
  zrb/task_input/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1396
- zrb/task_input/any_input.py,sha256=cZ2v8qjJ3B-L-jZgAz5EhpZii5sMoepwan5jAbJE0cM,2067
1397
- zrb/task_input/base_input.py,sha256=qNifwst3ArwAbQ9XBDoyo6whMeS2IP-VZ3Pw0vf8efE,5643
1396
+ zrb/task_input/any_input.py,sha256=-uOq1ONXdhW20FRkC3pzqX081tbfmWjvCc_-d-gCNGY,2087
1397
+ zrb/task_input/base_input.py,sha256=kxt2184s8ppC2dsa69J2uLUOUqsdCmXEJiNUIJxKcuQ,5495
1398
1398
  zrb/task_input/bool_input.py,sha256=xlWjqPvHi52TLiFP13wB1SayJlbzmxv31AS-sZJ0jw4,4040
1399
1399
  zrb/task_input/choice_input.py,sha256=GU28ATSayZsmqCW-euAPoWyA-Kh6d5Wf6FwWLXffk5w,4290
1400
1400
  zrb/task_input/constant.py,sha256=VEsnrI0BDdCJ1Z58EJgxXUhZBe5CA8TfURo0cNu5CaQ,200
@@ -1402,9 +1402,9 @@ zrb/task_input/float_input.py,sha256=rtaowHp8RpiQS8a24ULgtydRu6wkYT1Q7Q_IRcCPD7s
1402
1402
  zrb/task_input/int_input.py,sha256=d2fXcm5fCo09472eMAm6PdzLQD82ZBV9ARq5CjKepAo,4198
1403
1403
  zrb/task_input/password_input.py,sha256=g_g8ZWAzDaHx4h2EHY3UCGvTigC6esAUBzXU0T9nDUk,4192
1404
1404
  zrb/task_input/str_input.py,sha256=BNflOhrJvST9bWK0rGdCi7C7y-QDvHj9ISQMRmujIWU,4200
1405
- zrb/task_input/task_input.py,sha256=x1sGHsoSYAYMdQBrCLmcvZa_ZmGggMPj3goAQzewUKI,2181
1406
- zrb-0.17.2.dist-info/LICENSE,sha256=WfnGCl8G60EYOPAEkuc8C9m9pdXWDe08NsKj3TBbxsM,728
1407
- zrb-0.17.2.dist-info/METADATA,sha256=NNFpLM-mizatYOhAfnsi30eujgnhCA-KPs0KeCP4cRw,16460
1408
- zrb-0.17.2.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
1409
- zrb-0.17.2.dist-info/entry_points.txt,sha256=xTgXc1kBKYhJHEujdaSPHUcJT3-hbyP1mLgwkv-5sSk,40
1410
- zrb-0.17.2.dist-info/RECORD,,
1405
+ zrb/task_input/task_input.py,sha256=DcHgKie5Oo1sUxj41t1ZQjCIK1aAfTgGzaKr7_ap7ZI,2248
1406
+ zrb-0.17.5.dist-info/LICENSE,sha256=WfnGCl8G60EYOPAEkuc8C9m9pdXWDe08NsKj3TBbxsM,728
1407
+ zrb-0.17.5.dist-info/METADATA,sha256=nYeD36gTHtcdrptMrQY6-nc2E7Nd0IRIe90cNhtNcmg,17076
1408
+ zrb-0.17.5.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
1409
+ zrb-0.17.5.dist-info/entry_points.txt,sha256=xTgXc1kBKYhJHEujdaSPHUcJT3-hbyP1mLgwkv-5sSk,40
1410
+ zrb-0.17.5.dist-info/RECORD,,
File without changes
File without changes