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.
@@ -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.1
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.109 ; extra == 'test'
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.26 ; extra == 'test'
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: utils.receive.string
159
- run-date: utils.receive.datetime
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: utils.receive.datetime
207
- author-email: utils.receive.string
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
- ### Hooks (Transform)
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: utils.receive.datetime
232
- sp_name: utils.receive.string
233
- source_name: utils.receive.string
234
- target_name: utils.receive.string
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
- hook: hooks/mssql-proc@odbc
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,,
@@ -1,9 +0,0 @@
1
- from typing import Any
2
-
3
- from ddeutil.core import lazy
4
-
5
- registries: dict[str, Any] = {
6
- "postgres-proc": {
7
- "pysycopg": lazy("ddeutil.workflow.tasks._postgres.postgres_procedure"),
8
- },
9
- }
@@ -1,2 +0,0 @@
1
- def postgres_procedure():
2
- return
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,2 +0,0 @@
1
- def conn(value):
2
- 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,,