ddeutil-workflow 0.0.3__py3-none-any.whl → 0.0.4__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.
@@ -1 +1 @@
1
- __version__: str = "0.0.3"
1
+ __version__: str = "0.0.4"
@@ -5,13 +5,17 @@
5
5
  # ------------------------------------------------------------------------------
6
6
  from __future__ import annotations
7
7
 
8
+ import contextlib
8
9
  import inspect
9
10
  import itertools
10
11
  import logging
11
12
  import subprocess
13
+ import sys
12
14
  import time
15
+ import uuid
13
16
  from abc import ABC, abstractmethod
14
17
  from inspect import Parameter
18
+ from pathlib import Path
15
19
  from queue import Queue
16
20
  from subprocess import CompletedProcess
17
21
  from typing import Any, Callable, Optional, Union
@@ -25,7 +29,7 @@ from .__regex import RegexConf
25
29
  from .__types import DictData, DictStr
26
30
  from .exceptions import TaskException
27
31
  from .loader import Loader, map_params
28
- from .utils import Params, make_registry
32
+ from .utils import Params, make_exec, make_registry
29
33
 
30
34
 
31
35
  class BaseStage(BaseModel, ABC):
@@ -78,9 +82,27 @@ class ShellStage(BaseStage):
78
82
  env: DictStr = Field(default_factory=dict)
79
83
 
80
84
  @staticmethod
85
+ @contextlib.contextmanager
81
86
  def __prepare_shell(shell: str):
82
- """Prepare shell statement string that include newline"""
83
- return shell.replace("\n", ";")
87
+ """Return context of prepared shell statement that want to execute. This
88
+ step will write the `.sh` file before giving this file name to context.
89
+ After that, it will auto delete this file automatic.
90
+
91
+ :param shell: A shell statement that want to prepare.
92
+ """
93
+ f_name: str = f"{uuid.uuid4()}.sh"
94
+ f_shebang: str = "bash" if sys.platform.startswith("win") else "sh"
95
+ with open(f"./{f_name}", mode="w", newline="\n") as f:
96
+ f.write(f"#!/bin/{f_shebang}\n")
97
+
98
+ # NOTE: make sure that shell script file does not have `\r` char.
99
+ f.write(shell.replace("\r\n", "\n"))
100
+
101
+ make_exec(f"./{f_name}")
102
+
103
+ yield [f_shebang, f_name]
104
+
105
+ Path(f_name).unlink()
84
106
 
85
107
  def set_outputs(self, rs: CompletedProcess, params: DictData) -> DictData:
86
108
  """Set outputs to params"""
@@ -95,8 +117,7 @@ class ShellStage(BaseStage):
95
117
  # NOTE: The output will fileter unnecessary keys from ``_locals``.
96
118
  "outputs": {
97
119
  "return_code": rs.returncode,
98
- "stdout": rs.stdout,
99
- "stderr": rs.stderr,
120
+ "stdout": rs.stdout.rstrip("\n"),
100
121
  },
101
122
  }
102
123
  return params
@@ -105,19 +126,21 @@ class ShellStage(BaseStage):
105
126
  """Execute the Shell & Powershell statement with the Python build-in
106
127
  ``subprocess`` package.
107
128
  """
108
- rs: CompletedProcess = subprocess.run(
109
- self.__prepare_shell(self.shell),
110
- capture_output=True,
111
- text=True,
112
- shell=True,
113
- )
129
+ with self.__prepare_shell(self.shell) as sh:
130
+ with open(sh[-1]) as f:
131
+ logging.debug(f.read())
132
+ logging.info(f"Shell-Execute: {sh}")
133
+ rs: CompletedProcess = subprocess.run(
134
+ sh,
135
+ shell=False,
136
+ capture_output=True,
137
+ text=True,
138
+ )
114
139
  if rs.returncode > 0:
115
- print(f"{rs.stderr}\nRunning Statement:\n---\n{self.shell}")
116
- # FIXME: raise err for this execution.
117
- # raise TaskException(
118
- # f"{rs.stderr}\nRunning Statement:\n---\n"
119
- # f"{self.shell}"
120
- # )
140
+ logging.error(f"{rs.stderr}\nRunning Statement:\n---\n{self.shell}")
141
+ raise TaskException(
142
+ f"{rs.stderr}\nRunning Statement:\n---\n{self.shell}"
143
+ )
121
144
  self.set_outputs(rs, params)
122
145
  return params
123
146
 
@@ -472,6 +495,7 @@ class Pipeline(BaseModel):
472
495
  job_id: str = jq.get()
473
496
  logging.info(f"[PIPELINE]: Start execute the job: {job_id!r}")
474
497
  job: Job = self.jobs[job_id]
498
+
475
499
  # TODO: Condition on ``needs`` of this job was set. It should create
476
500
  # multithreading process on this step.
477
501
  # But, I don't know how to handle changes params between each job
@@ -480,6 +504,7 @@ class Pipeline(BaseModel):
480
504
  # >>> import multiprocessing
481
505
  # >>> with multiprocessing.Pool(processes=3) as pool:
482
506
  # ... results = pool.starmap(merge_names, ('', '', ...))
507
+ #
483
508
  if any(params["jobs"].get(need) for need in job.needs):
484
509
  jq.put(job_id)
485
510
  job.execute(params=params)
ddeutil/workflow/utils.py CHANGED
@@ -6,10 +6,12 @@
6
6
  from __future__ import annotations
7
7
 
8
8
  import inspect
9
+ import stat
9
10
  from abc import ABC, abstractmethod
10
11
  from datetime import date, datetime
11
12
  from functools import wraps
12
13
  from importlib import import_module
14
+ from pathlib import Path
13
15
  from typing import Any, Callable, Literal, Optional, Protocol, Union
14
16
 
15
17
  from ddeutil.core import lazy
@@ -178,3 +180,8 @@ Params = Union[
178
180
  DatetimeParams,
179
181
  StrParams,
180
182
  ]
183
+
184
+
185
+ def make_exec(path: str | Path):
186
+ f: Path = Path(path) if isinstance(path, str) else path
187
+ f.chmod(f.stat().st_mode | stat.S_IEXEC)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ddeutil-workflow
3
- Version: 0.0.3
3
+ Version: 0.0.4
4
4
  Summary: Data Developer & Engineer Workflow Utility Objects
5
5
  Author-email: ddeutils <korawich.anu@gmail.com>
6
6
  License: MIT
@@ -1,13 +1,13 @@
1
- ddeutil/workflow/__about__.py,sha256=smA9c0CTLewINRoxj2VBHoiYDESoFGtXYFDvRT31dgs,27
1
+ ddeutil/workflow/__about__.py,sha256=mI2ex1MyAxyhuxFGZTcowuzhaiztnKZbPh3obkmKpsY,27
2
2
  ddeutil/workflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  ddeutil/workflow/__regex.py,sha256=bOngaQ0zJgy3vfNwF2MlI8XhLu_Ei1Vz8y50iLj8ao4,1061
4
4
  ddeutil/workflow/__types.py,sha256=AkpQq6QlrclpurCZZVY9RMxoyS9z2WGzhaz_ikeTaCU,453
5
5
  ddeutil/workflow/conn.py,sha256=POtNcyqFNGxZnkg5J_H1OIvQVnnqG-ajmBBzjoHl9sg,7238
6
6
  ddeutil/workflow/exceptions.py,sha256=XAq82VHSMLNb4UjGatp7hYfjxFtMiKFtBqJyAhwTl-s,434
7
7
  ddeutil/workflow/loader.py,sha256=TXS4k2dqNycBYSTYcJ80WIsPMKNZbHNeBbcufX6lrJc,5483
8
- ddeutil/workflow/pipeline.py,sha256=fG6ta-SNx4OWS6n8w7YpYDadfnbqayj8A1uY03TvLUA,16942
8
+ ddeutil/workflow/pipeline.py,sha256=Uo26aC-IEdhSao0bxV_dy03fmv72rX9xENxiyzIEfC0,17789
9
9
  ddeutil/workflow/schedule.py,sha256=RMbTC7L32D3fJ5gYxJDCn-vPr2RYEBMSD0G2kj1Qows,2712
10
- ddeutil/workflow/utils.py,sha256=z7evB9kOsgTr30uVuL994bmOMDNZB5xDY2KjO7gL1dc,5379
10
+ ddeutil/workflow/utils.py,sha256=YWZA5npxzsx89O6bQ1-nxq3k_lbx4SDJURXkXwkmsmc,5556
11
11
  ddeutil/workflow/tasks/__init__.py,sha256=TIcw9JinrdepWgyazSMLk_QflUFms99ILI4GvLHUGD0,338
12
12
  ddeutil/workflow/tasks/_pandas.py,sha256=rqz5_VMSqkEdirk7i3EElZoqnRYFyyK_Z8_Zt8FyeTg,1693
13
13
  ddeutil/workflow/tasks/_polars.py,sha256=SYEBx-0I9tbY046QGSMokVugK8Fqjhiw4dzpL6y6Hww,2917
@@ -22,8 +22,8 @@ ddeutil/workflow/vendors/pd.py,sha256=J6Nkb4RqUnz3NMfo3cHX-Udw3HPjqjUimojS86rR4o
22
22
  ddeutil/workflow/vendors/pg.py,sha256=TGwkV6nsarGLbiRTT_wB4uAy3xCR89EPPCMWqlWhFe8,422
23
23
  ddeutil/workflow/vendors/pl.py,sha256=B-l9zcZ9vATAKVMLv5tjKiWo5Qt8ZIv_aQzuVFinKbY,5087
24
24
  ddeutil/workflow/vendors/sftp.py,sha256=lQn4mnHhgvE9g1pbpoQF7HvZOxab8Z2XaDtSIJvumGM,7090
25
- ddeutil_workflow-0.0.3.dist-info/LICENSE,sha256=nGFZ1QEhhhWeMHf9n99_fdt4vQaXS29xWKxt-OcLywk,1085
26
- ddeutil_workflow-0.0.3.dist-info/METADATA,sha256=KcsTd-FjufMK-4fhiIq27yeQUuA7NeB8TCkbXADQ1Dc,7992
27
- ddeutil_workflow-0.0.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
28
- ddeutil_workflow-0.0.3.dist-info/top_level.txt,sha256=m9M6XeSWDwt_yMsmH6gcOjHZVK5O0-vgtNBuncHjzW4,8
29
- ddeutil_workflow-0.0.3.dist-info/RECORD,,
25
+ ddeutil_workflow-0.0.4.dist-info/LICENSE,sha256=nGFZ1QEhhhWeMHf9n99_fdt4vQaXS29xWKxt-OcLywk,1085
26
+ ddeutil_workflow-0.0.4.dist-info/METADATA,sha256=-Sx33xY1RAQQ5OOSiOIIK6Qw8fcrAq-jiINbaXRFvjo,7992
27
+ ddeutil_workflow-0.0.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
28
+ ddeutil_workflow-0.0.4.dist-info/top_level.txt,sha256=m9M6XeSWDwt_yMsmH6gcOjHZVK5O0-vgtNBuncHjzW4,8
29
+ ddeutil_workflow-0.0.4.dist-info/RECORD,,