ddeutil-workflow 0.0.1__py3-none-any.whl → 0.0.2__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.
- ddeutil/workflow/__about__.py +1 -1
- ddeutil/workflow/conn.py +31 -29
- ddeutil/workflow/dataset.py +1 -5
- ddeutil/workflow/exceptions.py +0 -50
- ddeutil/workflow/loader.py +26 -190
- ddeutil/workflow/pipeline.py +201 -83
- ddeutil/workflow/schedule.py +3 -8
- ddeutil/workflow/tasks/__init__.py +6 -10
- ddeutil/workflow/tasks/_pandas.py +54 -0
- ddeutil/workflow/tasks/_polars.py +45 -2
- ddeutil/workflow/utils.py +65 -0
- {ddeutil_workflow-0.0.1.dist-info → ddeutil_workflow-0.0.2.dist-info}/METADATA +26 -15
- ddeutil_workflow-0.0.2.dist-info/RECORD +25 -0
- ddeutil/workflow/hooks/__init__.py +0 -9
- ddeutil/workflow/hooks/_postgres.py +0 -2
- ddeutil/workflow/utils/__init__.py +0 -0
- ddeutil/workflow/utils/receive.py +0 -33
- ddeutil/workflow/utils/selection.py +0 -2
- ddeutil_workflow-0.0.1.dist-info/RECORD +0 -28
- {ddeutil_workflow-0.0.1.dist-info → ddeutil_workflow-0.0.2.dist-info}/LICENSE +0 -0
- {ddeutil_workflow-0.0.1.dist-info → ddeutil_workflow-0.0.2.dist-info}/WHEEL +0 -0
- {ddeutil_workflow-0.0.1.dist-info → ddeutil_workflow-0.0.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
# ------------------------------------------------------------------------------
|
2
|
+
# Copyright (c) 2022 Korawich Anuttra. All rights reserved.
|
3
|
+
# Licensed under the MIT License. See LICENSE in the project root for
|
4
|
+
# license information.
|
5
|
+
# ------------------------------------------------------------------------------
|
6
|
+
from __future__ import annotations
|
7
|
+
|
8
|
+
import inspect
|
9
|
+
from functools import wraps
|
10
|
+
from importlib import import_module
|
11
|
+
from typing import Callable, Protocol
|
12
|
+
|
13
|
+
from ddeutil.core import lazy
|
14
|
+
|
15
|
+
|
16
|
+
class TagFunc(Protocol):
|
17
|
+
"""Tag Function Protocol"""
|
18
|
+
|
19
|
+
name: str
|
20
|
+
tag: str
|
21
|
+
|
22
|
+
def __call__(self, *args, **kwargs): ...
|
23
|
+
|
24
|
+
|
25
|
+
def tag(tag_value: str, name: str | None = None):
|
26
|
+
"""Tag decorator function that set function attributes, ``tag`` and ``name``
|
27
|
+
for making registries variable.
|
28
|
+
|
29
|
+
:param: tag_value: A tag value for make different use-case of a function.
|
30
|
+
:param: name: A name that keeping in registries.
|
31
|
+
"""
|
32
|
+
|
33
|
+
def func_internal(func: TagFunc):
|
34
|
+
func.tag = tag_value
|
35
|
+
func.name = name or func.__name__.replace("_", "-")
|
36
|
+
|
37
|
+
@wraps(func)
|
38
|
+
def wrapped(*args, **kwargs):
|
39
|
+
return func(*args, **kwargs)
|
40
|
+
|
41
|
+
return wrapped
|
42
|
+
|
43
|
+
return func_internal
|
44
|
+
|
45
|
+
|
46
|
+
def make_registry(module: str) -> dict[str, dict[str, Callable[[], TagFunc]]]:
|
47
|
+
"""Return registries of all functions that able to called with task."""
|
48
|
+
rs: dict[str, dict[str, Callable[[], Callable]]] = {}
|
49
|
+
for fstr, func in inspect.getmembers(
|
50
|
+
import_module(module), inspect.isfunction
|
51
|
+
):
|
52
|
+
if not hasattr(func, "tag"):
|
53
|
+
continue
|
54
|
+
|
55
|
+
if func.name in rs:
|
56
|
+
if func.tag in rs[func.name]:
|
57
|
+
raise ValueError(
|
58
|
+
f"The tag {func.tag!r} already exists on module {module}"
|
59
|
+
)
|
60
|
+
rs[func.name][func.tag] = lazy(f"{module}.{fstr}")
|
61
|
+
continue
|
62
|
+
|
63
|
+
# NOTE: Create new register name if it not exists
|
64
|
+
rs[func.name] = {func.tag: lazy(f"{module}.{fstr}")}
|
65
|
+
return rs
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ddeutil-workflow
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.2
|
4
4
|
Summary: Data Developer & Engineer Workflow Utility Objects
|
5
5
|
Author-email: ddeutils <korawich.anu@gmail.com>
|
6
6
|
License: MIT
|
@@ -23,15 +23,14 @@ Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
24
24
|
Requires-Dist: fmtutil
|
25
25
|
Requires-Dist: ddeutil-io
|
26
|
-
Requires-Dist: ddeutil-model
|
27
26
|
Requires-Dist: python-dotenv
|
28
27
|
Provides-Extra: test
|
29
28
|
Requires-Dist: sqlalchemy ==2.0.30 ; extra == 'test'
|
30
29
|
Requires-Dist: paramiko ==3.4.0 ; extra == 'test'
|
31
30
|
Requires-Dist: sshtunnel ==0.4.0 ; extra == 'test'
|
32
|
-
Requires-Dist: boto3 ==1.34.
|
31
|
+
Requires-Dist: boto3 ==1.34.117 ; extra == 'test'
|
33
32
|
Requires-Dist: fsspec ==2024.5.0 ; extra == 'test'
|
34
|
-
Requires-Dist: polars ==0.20.
|
33
|
+
Requires-Dist: polars ==0.20.31 ; extra == 'test'
|
35
34
|
Requires-Dist: pyarrow ==16.1.0 ; extra == 'test'
|
36
35
|
|
37
36
|
# Data Utility: _Workflow_
|
@@ -83,6 +82,9 @@ The first step, you should start create the connections and datasets for In and
|
|
83
82
|
Out of you data that want to use in pipeline of workflow. Some of this component
|
84
83
|
is similar component of the **Airflow** because I like it concepts.
|
85
84
|
|
85
|
+
The main feature of this project is the `Pipeline` object that can call any
|
86
|
+
registried function.
|
87
|
+
|
86
88
|
### Connection
|
87
89
|
|
88
90
|
The connection for worker able to do any thing.
|
@@ -155,8 +157,10 @@ The state of doing lists that worker should to do. It be collection of the stage
|
|
155
157
|
run_py_local:
|
156
158
|
type: ddeutil.workflow.pipe.Pipeline
|
157
159
|
params:
|
158
|
-
author-run:
|
159
|
-
|
160
|
+
author-run:
|
161
|
+
type: str
|
162
|
+
run-date:
|
163
|
+
type: datetime
|
160
164
|
jobs:
|
161
165
|
first-job:
|
162
166
|
stages:
|
@@ -203,13 +207,15 @@ pipe.execute(params={'author-run': 'Local Workflow', 'run-date': '2024-01-01'})
|
|
203
207
|
pipe_el_pg_to_lake:
|
204
208
|
type: ddeutil.workflow.pipe.Pipeline
|
205
209
|
params:
|
206
|
-
run-date:
|
207
|
-
|
210
|
+
run-date:
|
211
|
+
type: datetime
|
212
|
+
author-email:
|
213
|
+
type: str
|
208
214
|
jobs:
|
209
215
|
extract-load:
|
210
216
|
stages:
|
211
217
|
- name: "Extract Load from Postgres to Lake"
|
212
|
-
id: extract
|
218
|
+
id: extract-load
|
213
219
|
task: tasks/postgres-to-delta@polars
|
214
220
|
with:
|
215
221
|
source:
|
@@ -222,21 +228,26 @@ pipe_el_pg_to_lake:
|
|
222
228
|
endpoint: "/${{ params.name }}"
|
223
229
|
```
|
224
230
|
|
225
|
-
###
|
231
|
+
### Tasks (Transform)
|
226
232
|
|
227
233
|
```yaml
|
228
234
|
pipe_hook_mssql_proc:
|
229
235
|
type: ddeutil.workflow.pipe.Pipeline
|
230
236
|
params:
|
231
|
-
run_date:
|
232
|
-
|
233
|
-
|
234
|
-
|
237
|
+
run_date:
|
238
|
+
type: datetime
|
239
|
+
sp_name:
|
240
|
+
type: str
|
241
|
+
source_name:
|
242
|
+
type: str
|
243
|
+
target_name:
|
244
|
+
type: str
|
235
245
|
jobs:
|
236
246
|
transform:
|
237
247
|
stages:
|
238
248
|
- name: "Transform Data in MS SQL Server"
|
239
|
-
|
249
|
+
id: transform
|
250
|
+
task: tasks/mssql-proc@odbc
|
240
251
|
with:
|
241
252
|
exec: ${{ params.sp_name }}
|
242
253
|
params:
|
@@ -0,0 +1,25 @@
|
|
1
|
+
ddeutil/workflow/__about__.py,sha256=Ow9Rd-50zm5qXBM0iKjjMszFJAKgfR8LsocpgUKYVrI,27
|
2
|
+
ddeutil/workflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
ddeutil/workflow/__regex.py,sha256=bOngaQ0zJgy3vfNwF2MlI8XhLu_Ei1Vz8y50iLj8ao4,1061
|
4
|
+
ddeutil/workflow/__types.py,sha256=7t-i5_-eif9zUBwb7jnv5RbSjzOihyl3yFDqXzaeyxk,428
|
5
|
+
ddeutil/workflow/conn.py,sha256=KpQywXVurVvUjOdDg8zrPp1mKyRwR6qqrEjkPBhi_yc,6838
|
6
|
+
ddeutil/workflow/dataset.py,sha256=Qszg65YyMCy6Bojya_OSbXtUjCqS8sZnDJvJtu706YA,8578
|
7
|
+
ddeutil/workflow/exceptions.py,sha256=LAa3QlnPqECGxq6PpXoXNZVca7v7l4szjTZ3zWXJoWM,824
|
8
|
+
ddeutil/workflow/loader.py,sha256=iTE1Rhjl-bq3YHZCKYWY51iwbQie2N6-MsaduOF1qSg,4463
|
9
|
+
ddeutil/workflow/pipeline.py,sha256=r3FjbiC51eDArkoOQmfoSE--bZgggxUvRUh99bj3A9Y,14529
|
10
|
+
ddeutil/workflow/schedule.py,sha256=f3V6dM66fM2C67vt9ltFSyqmxCMx1yo_gJuUDR_RMIE,2672
|
11
|
+
ddeutil/workflow/utils.py,sha256=j2CmadYq9nXTyGWYGp_L0LS-fOnkTyzTNpf359ne1dA,2011
|
12
|
+
ddeutil/workflow/tasks/__init__.py,sha256=TIcw9JinrdepWgyazSMLk_QflUFms99ILI4GvLHUGD0,338
|
13
|
+
ddeutil/workflow/tasks/_pandas.py,sha256=ob8Ozq9ASiky8SwxWcR8HUr_j-qQoJez6EEckHrfR3s,1693
|
14
|
+
ddeutil/workflow/tasks/_polars.py,sha256=0EbASTqc-aNtNnLN1QIYONqb5gzJvoqqZ-V584UNQtI,2708
|
15
|
+
ddeutil/workflow/vendors/__dict.py,sha256=ETwkeA0qzKNgedfeRgAz1qShNXTIXIS4DXzJB4lM4jo,9962
|
16
|
+
ddeutil/workflow/vendors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
+
ddeutil/workflow/vendors/__schedule.py,sha256=cUIwtTli9G0klrNFxAIbG3VTiv6umRuNAZiKA-kOtpE,20690
|
18
|
+
ddeutil/workflow/vendors/aws_warpped.py,sha256=zjq_LCu3ffVBRrxS2vqss9X24yrtuAEt9ouy2_WvS0o,5980
|
19
|
+
ddeutil/workflow/vendors/minio_warpped.py,sha256=pScLy38Du9moOrGaSBSFsoQRhiQ686FQyloOeLA0OQk,261
|
20
|
+
ddeutil/workflow/vendors/sftp_wrapped.py,sha256=lQn4mnHhgvE9g1pbpoQF7HvZOxab8Z2XaDtSIJvumGM,7090
|
21
|
+
ddeutil_workflow-0.0.2.dist-info/LICENSE,sha256=nGFZ1QEhhhWeMHf9n99_fdt4vQaXS29xWKxt-OcLywk,1085
|
22
|
+
ddeutil_workflow-0.0.2.dist-info/METADATA,sha256=o1ECtqH1WSBpz0UNu9OdzFqmxrmpbZP2H-KqHF4l8i0,7511
|
23
|
+
ddeutil_workflow-0.0.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
24
|
+
ddeutil_workflow-0.0.2.dist-info/top_level.txt,sha256=m9M6XeSWDwt_yMsmH6gcOjHZVK5O0-vgtNBuncHjzW4,8
|
25
|
+
ddeutil_workflow-0.0.2.dist-info/RECORD,,
|
File without changes
|
@@ -1,33 +0,0 @@
|
|
1
|
-
import datetime as dt
|
2
|
-
from typing import Any
|
3
|
-
|
4
|
-
|
5
|
-
def datetime(value: Any) -> dt.datetime:
|
6
|
-
if isinstance(value, dt.datetime):
|
7
|
-
return value
|
8
|
-
elif isinstance(value, dt.date):
|
9
|
-
return dt.datetime(value.year, value.month, value.day)
|
10
|
-
if value is None:
|
11
|
-
return dt.datetime.now(dt.timezone.utc)
|
12
|
-
elif not isinstance(value, str):
|
13
|
-
raise ValueError(
|
14
|
-
f"Value that want to convert to datetime does not support for "
|
15
|
-
f"type: {type(value)}"
|
16
|
-
)
|
17
|
-
return dt.datetime.fromisoformat(value)
|
18
|
-
|
19
|
-
|
20
|
-
def string(value: Any) -> str:
|
21
|
-
return str(value)
|
22
|
-
|
23
|
-
|
24
|
-
def integer(value: Any) -> int:
|
25
|
-
if not isinstance(value, int):
|
26
|
-
try:
|
27
|
-
return int(str(value))
|
28
|
-
except TypeError as err:
|
29
|
-
raise ValueError(
|
30
|
-
f"Value that want to convert to integer does not support for "
|
31
|
-
f"type: {type(value)}"
|
32
|
-
) from err
|
33
|
-
return value
|
@@ -1,28 +0,0 @@
|
|
1
|
-
ddeutil/workflow/__about__.py,sha256=YZoDMFgikTmgL5EqRKa4mX-zXFr2c20J7dSZJ4dqSd0,27
|
2
|
-
ddeutil/workflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
ddeutil/workflow/__regex.py,sha256=bOngaQ0zJgy3vfNwF2MlI8XhLu_Ei1Vz8y50iLj8ao4,1061
|
4
|
-
ddeutil/workflow/__types.py,sha256=7t-i5_-eif9zUBwb7jnv5RbSjzOihyl3yFDqXzaeyxk,428
|
5
|
-
ddeutil/workflow/conn.py,sha256=5Nf6IQf2PXC6eLn469tGNvtnXAx-eOm3jJ_ltj90VbQ,6831
|
6
|
-
ddeutil/workflow/dataset.py,sha256=SNp58WwTvgDSFWll9aizJeiHX_fd68f687cRME7vBo4,8599
|
7
|
-
ddeutil/workflow/exceptions.py,sha256=aV_LN4_zmAk2R2p5ZYJcSMrsdBsRo6cMwm0lwZv_400,2399
|
8
|
-
ddeutil/workflow/loader.py,sha256=nJffdJ8kchhwYsEGnWoG_leR16dzU0evo_p5Wbi4rp4,9710
|
9
|
-
ddeutil/workflow/pipeline.py,sha256=kN6k2ht4C2OPHZYPljpnUQqfY3K54kMSOS1azGt7R68,10755
|
10
|
-
ddeutil/workflow/schedule.py,sha256=RSvT0pi1Gb1un3OseRUW9AngRgVuAlXFT23QrSjtxYk,2828
|
11
|
-
ddeutil/workflow/hooks/__init__.py,sha256=x5pY43037-cE0j3ofU_f7oEylzx-sN7pQwhiZubBtvY,199
|
12
|
-
ddeutil/workflow/hooks/_postgres.py,sha256=8bAAlxHe_K1sAqwE1Pz6y6cKuytimmPnaEeudEPag2A,37
|
13
|
-
ddeutil/workflow/tasks/__init__.py,sha256=NgGzbxWBV6lRgIEvp4VuREbKzo_ncTLgx00W2BAR-uk,276
|
14
|
-
ddeutil/workflow/tasks/_polars.py,sha256=OT6kt7mYHx88DEJsO8sfnIfcjdXZ02XCAAcQBKr6wXM,1429
|
15
|
-
ddeutil/workflow/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
|
-
ddeutil/workflow/utils/receive.py,sha256=lWB8k-_hPmdkq2bjPSL_2IX1X19I8f017u8-7jNRH68,939
|
17
|
-
ddeutil/workflow/utils/selection.py,sha256=0qJu4mgVfNLLlnBbrsQtKK__LmG_DZf2Gs8CBplP4c0,34
|
18
|
-
ddeutil/workflow/vendors/__dict.py,sha256=ETwkeA0qzKNgedfeRgAz1qShNXTIXIS4DXzJB4lM4jo,9962
|
19
|
-
ddeutil/workflow/vendors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
|
-
ddeutil/workflow/vendors/__schedule.py,sha256=cUIwtTli9G0klrNFxAIbG3VTiv6umRuNAZiKA-kOtpE,20690
|
21
|
-
ddeutil/workflow/vendors/aws_warpped.py,sha256=zjq_LCu3ffVBRrxS2vqss9X24yrtuAEt9ouy2_WvS0o,5980
|
22
|
-
ddeutil/workflow/vendors/minio_warpped.py,sha256=pScLy38Du9moOrGaSBSFsoQRhiQ686FQyloOeLA0OQk,261
|
23
|
-
ddeutil/workflow/vendors/sftp_wrapped.py,sha256=lQn4mnHhgvE9g1pbpoQF7HvZOxab8Z2XaDtSIJvumGM,7090
|
24
|
-
ddeutil_workflow-0.0.1.dist-info/LICENSE,sha256=nGFZ1QEhhhWeMHf9n99_fdt4vQaXS29xWKxt-OcLywk,1085
|
25
|
-
ddeutil_workflow-0.0.1.dist-info/METADATA,sha256=uFH3MTuZk6UNPjLIQqaQSebszywROMUMzjLMftY0OM0,7444
|
26
|
-
ddeutil_workflow-0.0.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
27
|
-
ddeutil_workflow-0.0.1.dist-info/top_level.txt,sha256=m9M6XeSWDwt_yMsmH6gcOjHZVK5O0-vgtNBuncHjzW4,8
|
28
|
-
ddeutil_workflow-0.0.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|