etlplus 0.16.0__py3-none-any.whl → 0.16.6__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.
- etlplus/README.md +22 -0
- etlplus/__init__.py +2 -0
- etlplus/api/__init__.py +14 -14
- etlplus/api/auth.py +9 -6
- etlplus/api/config.py +6 -6
- etlplus/api/endpoint_client.py +16 -16
- etlplus/api/errors.py +4 -4
- etlplus/api/pagination/__init__.py +6 -6
- etlplus/api/pagination/config.py +11 -9
- etlplus/api/rate_limiting/__init__.py +2 -2
- etlplus/api/rate_limiting/config.py +10 -10
- etlplus/api/rate_limiting/rate_limiter.py +2 -2
- etlplus/api/request_manager.py +4 -4
- etlplus/api/retry_manager.py +6 -6
- etlplus/api/transport.py +10 -10
- etlplus/api/types.py +47 -26
- etlplus/api/utils.py +49 -49
- etlplus/cli/commands.py +22 -22
- etlplus/cli/handlers.py +12 -13
- etlplus/{workflow/pipeline.py → config.py} +54 -91
- etlplus/connector/__init__.py +6 -6
- etlplus/connector/api.py +7 -7
- etlplus/connector/database.py +3 -3
- etlplus/connector/file.py +3 -3
- etlplus/connector/types.py +2 -2
- etlplus/enums.py +35 -167
- etlplus/ops/__init__.py +1 -0
- etlplus/ops/enums.py +173 -0
- etlplus/ops/extract.py +209 -22
- etlplus/ops/load.py +140 -34
- etlplus/ops/run.py +88 -103
- etlplus/ops/transform.py +46 -27
- etlplus/ops/types.py +147 -0
- etlplus/ops/utils.py +5 -5
- etlplus/ops/validate.py +13 -13
- etlplus/types.py +5 -102
- etlplus/workflow/README.md +0 -24
- etlplus/workflow/__init__.py +2 -4
- etlplus/workflow/dag.py +23 -1
- etlplus/workflow/jobs.py +15 -28
- etlplus/workflow/profile.py +4 -2
- {etlplus-0.16.0.dist-info → etlplus-0.16.6.dist-info}/METADATA +1 -1
- {etlplus-0.16.0.dist-info → etlplus-0.16.6.dist-info}/RECORD +47 -45
- {etlplus-0.16.0.dist-info → etlplus-0.16.6.dist-info}/WHEEL +0 -0
- {etlplus-0.16.0.dist-info → etlplus-0.16.6.dist-info}/entry_points.txt +0 -0
- {etlplus-0.16.0.dist-info → etlplus-0.16.6.dist-info}/licenses/LICENSE +0 -0
- {etlplus-0.16.0.dist-info → etlplus-0.16.6.dist-info}/top_level.txt +0 -0
etlplus/types.py
CHANGED
|
@@ -12,12 +12,12 @@ Notes
|
|
|
12
12
|
See Also
|
|
13
13
|
--------
|
|
14
14
|
- :mod:`etlplus.api.types` for HTTP-specific aliases and data classes
|
|
15
|
-
- :mod:`etlplus.connector.types` for connector-specific aliases
|
|
16
|
-
surfaces
|
|
15
|
+
- :mod:`etlplus.connector.types` for connector-specific aliases
|
|
17
16
|
|
|
18
17
|
Examples
|
|
19
18
|
--------
|
|
20
|
-
>>> from etlplus.types import JSONDict
|
|
19
|
+
>>> from etlplus.types import JSONDict
|
|
20
|
+
>>> from etlplus.ops.types import PipelineConfig
|
|
21
21
|
>>> payload: JSONDict = {'id': 1, 'name': 'Ada'}
|
|
22
22
|
>>> isinstance(payload, dict)
|
|
23
23
|
True
|
|
@@ -54,33 +54,15 @@ __all__ = [
|
|
|
54
54
|
'JSONRecords',
|
|
55
55
|
# Type Aliases (File System)
|
|
56
56
|
'StrPath',
|
|
57
|
-
# Type Aliases (Functions)
|
|
58
|
-
'AggregateFunc',
|
|
59
|
-
'OperatorFunc',
|
|
60
|
-
# Type Aliases (Records & Fields)
|
|
61
|
-
'FieldName',
|
|
62
|
-
'Fields',
|
|
63
57
|
# Type Aliases (Transform Specs)
|
|
64
58
|
'StrAnyMap',
|
|
65
59
|
'StrSeqMap',
|
|
66
60
|
'StrStrMap',
|
|
67
|
-
'AggregateSpec',
|
|
68
|
-
'FilterSpec',
|
|
69
|
-
'MapSpec',
|
|
70
|
-
'SelectSpec',
|
|
71
|
-
'SortSpec',
|
|
72
|
-
# Type Aliases (Pipelines)
|
|
73
|
-
'StepOrSteps',
|
|
74
|
-
'StepSeq',
|
|
75
|
-
'StepSpec',
|
|
76
|
-
'PipelineStepName',
|
|
77
|
-
'PipelineConfig',
|
|
78
|
-
# Type Aliases (Helpers)
|
|
79
|
-
'StepApplier',
|
|
80
|
-
'SortKey',
|
|
81
61
|
# Type Aliases (Networking / Runtime)
|
|
82
62
|
'Sleeper',
|
|
83
63
|
'Timeout',
|
|
64
|
+
# Type Aliases (Templates)
|
|
65
|
+
'TemplateKey',
|
|
84
66
|
]
|
|
85
67
|
|
|
86
68
|
|
|
@@ -125,22 +107,6 @@ type JSONRecords = list[JSONRecord]
|
|
|
125
107
|
# Path-like inputs accepted by file helpers.
|
|
126
108
|
type StrPath = str | Path | PathLike[str]
|
|
127
109
|
|
|
128
|
-
# -- Functions -- #
|
|
129
|
-
|
|
130
|
-
# Callable reducing numeric collections into a summary value.
|
|
131
|
-
type AggregateFunc = Callable[[list[float], int], Any]
|
|
132
|
-
|
|
133
|
-
# Binary predicate consumed by filter operations.
|
|
134
|
-
type OperatorFunc = Callable[[Any, Any], bool]
|
|
135
|
-
|
|
136
|
-
# -- Records & Fields -- #
|
|
137
|
-
|
|
138
|
-
# Individual field identifier referenced inside specs.
|
|
139
|
-
type FieldName = str
|
|
140
|
-
|
|
141
|
-
# Ordered list of :data:`FieldName` entries preserving projection order.
|
|
142
|
-
type Fields = list[FieldName]
|
|
143
|
-
|
|
144
110
|
# -- Transform Specs -- #
|
|
145
111
|
|
|
146
112
|
# Kept intentionally broad for runtime-friendly validation in transform.py.
|
|
@@ -156,69 +122,6 @@ type StrStrMap = Mapping[str, str]
|
|
|
156
122
|
# Mapping whose values are homogeneous sequences.
|
|
157
123
|
type StrSeqMap = Mapping[str, Sequence[Any]]
|
|
158
124
|
|
|
159
|
-
# Transform step specifications
|
|
160
|
-
|
|
161
|
-
# Filtering spec expecting ``field``, ``op``, and ``value`` keys.
|
|
162
|
-
type FilterSpec = StrAnyMap
|
|
163
|
-
|
|
164
|
-
# Field renaming instructions mapping old keys to new ones.
|
|
165
|
-
type MapSpec = StrStrMap
|
|
166
|
-
|
|
167
|
-
# Projection spec as a field list or mapping with metadata.
|
|
168
|
-
#
|
|
169
|
-
# Examples
|
|
170
|
-
# --------
|
|
171
|
-
# >>> from etlplus.types import SelectSpec
|
|
172
|
-
# >>> spec1: SelectSpec = ['a','b']
|
|
173
|
-
# >>> spec2: SelectSpec = {'fields': [...]}
|
|
174
|
-
type SelectSpec = Fields | StrSeqMap
|
|
175
|
-
|
|
176
|
-
# Sort directive expressed as a field string or mapping with flags.
|
|
177
|
-
#
|
|
178
|
-
# Examples
|
|
179
|
-
# --------
|
|
180
|
-
# >>> from etlplus.types import SortSpec
|
|
181
|
-
# >>> spec1: SortSpec = 'field'
|
|
182
|
-
# >>> spec2: SortSpec = {'field': 'x', 'reverse': True}
|
|
183
|
-
type SortSpec = str | StrAnyMap
|
|
184
|
-
|
|
185
|
-
# Aggregate instruction covering ``field``, ``func``, and optional alias.
|
|
186
|
-
#
|
|
187
|
-
# Supported functions: ``avg``, ``count``, ``max``, ``min``, and ``sum``.
|
|
188
|
-
# Examples
|
|
189
|
-
# --------
|
|
190
|
-
# >>> from etlplus.types import AggregateSpec
|
|
191
|
-
# >>> spec: AggregateSpec = \
|
|
192
|
-
# ... {'field': 'x', 'func': 'sum' | 'avg' | ..., 'alias'?: '...'}
|
|
193
|
-
type AggregateSpec = StrAnyMap
|
|
194
|
-
|
|
195
|
-
# -- Pipelines-- #
|
|
196
|
-
|
|
197
|
-
# Unified pipeline step spec consumed by :mod:`etlplus.ops.transform`.
|
|
198
|
-
type StepSpec = AggregateSpec | FilterSpec | MapSpec | SelectSpec | SortSpec
|
|
199
|
-
|
|
200
|
-
# Collections of steps
|
|
201
|
-
|
|
202
|
-
# Ordered collection of :data:`StepSpec` entries.
|
|
203
|
-
type StepSeq = Sequence[StepSpec]
|
|
204
|
-
|
|
205
|
-
# Accepts either a single :data:`StepSpec` or a sequence of them.
|
|
206
|
-
type StepOrSteps = StepSpec | StepSeq
|
|
207
|
-
|
|
208
|
-
# Canonical literal names for supported transform stages.
|
|
209
|
-
type PipelineStepName = Literal['filter', 'map', 'select', 'sort', 'aggregate']
|
|
210
|
-
|
|
211
|
-
# Mapping from step name to its associated specification payload.
|
|
212
|
-
type PipelineConfig = Mapping[PipelineStepName, StepOrSteps]
|
|
213
|
-
|
|
214
|
-
# -- Helpers -- #
|
|
215
|
-
|
|
216
|
-
# Callable that applies step configuration to a batch of records.
|
|
217
|
-
type StepApplier = Callable[[JSONList, Any], JSONList]
|
|
218
|
-
|
|
219
|
-
# Tuple combining stable sort index and computed sort value.
|
|
220
|
-
type SortKey = tuple[int, Any]
|
|
221
|
-
|
|
222
125
|
# -- Networking / Runtime -- #
|
|
223
126
|
|
|
224
127
|
# Sleep function used by retry helpers.
|
etlplus/workflow/README.md
CHANGED
|
@@ -12,8 +12,6 @@ Back to project overview: see the top-level [README](../../README.md).
|
|
|
12
12
|
|
|
13
13
|
- [`etlplus.workflow` Subpackage](#etlplusworkflow-subpackage)
|
|
14
14
|
- [Supported Configuration Types](#supported-configuration-types)
|
|
15
|
-
- [Loading and Validating Configs](#loading-and-validating-configs)
|
|
16
|
-
- [Example: Loading a Pipeline Config](#example-loading-a-pipeline-config)
|
|
17
15
|
- [See Also](#see-also)
|
|
18
16
|
|
|
19
17
|
## Supported Configuration Types
|
|
@@ -23,28 +21,6 @@ Back to project overview: see the top-level [README](../../README.md).
|
|
|
23
21
|
- **Pipeline**: End-to-end pipeline configuration
|
|
24
22
|
- **Profile**: User or environment-specific settings
|
|
25
23
|
|
|
26
|
-
## Loading and Validating Configs
|
|
27
|
-
|
|
28
|
-
Use the provided classes to load and validate configuration files:
|
|
29
|
-
|
|
30
|
-
```python
|
|
31
|
-
from etlplus.workflow import PipelineConfig
|
|
32
|
-
|
|
33
|
-
cfg = PipelineConfig.from_yaml("pipeline.yml")
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
- Supports YAML and JSON formats
|
|
37
|
-
- Validates against expected schema
|
|
38
|
-
|
|
39
|
-
## Example: Loading a Pipeline Config
|
|
40
|
-
|
|
41
|
-
```python
|
|
42
|
-
from etlplus.workflow import PipelineConfig
|
|
43
|
-
|
|
44
|
-
pipeline = PipelineConfig.from_yaml("configs/pipeline.yml")
|
|
45
|
-
print(pipeline)
|
|
46
|
-
```
|
|
47
|
-
|
|
48
24
|
## See Also
|
|
49
25
|
|
|
50
26
|
- Top-level CLI and library usage in the main [README](../../README.md)
|
etlplus/workflow/__init__.py
CHANGED
|
@@ -12,8 +12,7 @@ from .jobs import JobConfig
|
|
|
12
12
|
from .jobs import LoadRef
|
|
13
13
|
from .jobs import TransformRef
|
|
14
14
|
from .jobs import ValidationRef
|
|
15
|
-
from .
|
|
16
|
-
from .pipeline import load_pipeline_config
|
|
15
|
+
from .profile import ProfileConfig
|
|
17
16
|
|
|
18
17
|
# SECTION: EXPORTS ========================================================== #
|
|
19
18
|
|
|
@@ -23,10 +22,9 @@ __all__ = [
|
|
|
23
22
|
'ExtractRef',
|
|
24
23
|
'JobConfig',
|
|
25
24
|
'LoadRef',
|
|
26
|
-
'
|
|
25
|
+
'ProfileConfig',
|
|
27
26
|
'TransformRef',
|
|
28
27
|
'ValidationRef',
|
|
29
28
|
# Functions
|
|
30
|
-
'load_pipeline_config',
|
|
31
29
|
'topological_sort_jobs',
|
|
32
30
|
]
|
etlplus/workflow/dag.py
CHANGED
|
@@ -47,6 +47,28 @@ class DagError(ValueError):
|
|
|
47
47
|
return self.message
|
|
48
48
|
|
|
49
49
|
|
|
50
|
+
# SECTION: INTERNAL FUNCTIONS =============================================== #
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _ready(
|
|
54
|
+
indegree: dict[str, int],
|
|
55
|
+
) -> list[str]:
|
|
56
|
+
"""
|
|
57
|
+
Return a sorted list of nodes with zero indegree.
|
|
58
|
+
|
|
59
|
+
Parameters
|
|
60
|
+
----------
|
|
61
|
+
indegree : dict[str, int]
|
|
62
|
+
Mapping of node name to indegree.
|
|
63
|
+
|
|
64
|
+
Returns
|
|
65
|
+
-------
|
|
66
|
+
list[str]
|
|
67
|
+
Sorted list of node names ready to process.
|
|
68
|
+
"""
|
|
69
|
+
return sorted(name for name, deg in indegree.items() if deg == 0)
|
|
70
|
+
|
|
71
|
+
|
|
50
72
|
# SECTION: FUNCTIONS ======================================================== #
|
|
51
73
|
|
|
52
74
|
|
|
@@ -88,7 +110,7 @@ def topological_sort_jobs(
|
|
|
88
110
|
edges[dep].add(job.name)
|
|
89
111
|
indegree[job.name] += 1
|
|
90
112
|
|
|
91
|
-
queue = deque(
|
|
113
|
+
queue = deque(_ready(indegree))
|
|
92
114
|
ordered: list[str] = []
|
|
93
115
|
|
|
94
116
|
while queue:
|
etlplus/workflow/jobs.py
CHANGED
|
@@ -6,14 +6,13 @@ transform, load).
|
|
|
6
6
|
|
|
7
7
|
Notes
|
|
8
8
|
-----
|
|
9
|
-
- Lightweight references used inside :class:`PipelineConfig` to avoid storing
|
|
10
|
-
large nested structures.
|
|
11
9
|
- All attributes are simple and optional where appropriate, keeping parsing
|
|
12
10
|
tolerant.
|
|
13
11
|
"""
|
|
14
12
|
|
|
15
13
|
from __future__ import annotations
|
|
16
14
|
|
|
15
|
+
from collections.abc import Sequence
|
|
17
16
|
from dataclasses import dataclass
|
|
18
17
|
from dataclasses import field
|
|
19
18
|
from typing import Any
|
|
@@ -76,13 +75,15 @@ def _parse_depends_on(
|
|
|
76
75
|
"""
|
|
77
76
|
if isinstance(value, str):
|
|
78
77
|
return [value]
|
|
79
|
-
if isinstance(value,
|
|
78
|
+
if isinstance(value, Sequence) and not isinstance(
|
|
79
|
+
value,
|
|
80
|
+
(str, bytes, bytearray),
|
|
81
|
+
):
|
|
80
82
|
return [entry for entry in value if isinstance(entry, str)]
|
|
81
83
|
return []
|
|
82
84
|
|
|
83
85
|
|
|
84
86
|
def _require_str(
|
|
85
|
-
# data: dict[str, Any],
|
|
86
87
|
data: StrAnyMap,
|
|
87
88
|
key: str,
|
|
88
89
|
) -> str | None:
|
|
@@ -149,13 +150,9 @@ class ExtractRef:
|
|
|
149
150
|
data = maybe_mapping(obj)
|
|
150
151
|
if not data:
|
|
151
152
|
return None
|
|
152
|
-
source
|
|
153
|
-
if source is None:
|
|
153
|
+
if (source := _require_str(data, 'source')) is None:
|
|
154
154
|
return None
|
|
155
|
-
return cls(
|
|
156
|
-
source=source,
|
|
157
|
-
options=coerce_dict(data.get('options')),
|
|
158
|
-
)
|
|
155
|
+
return cls(source=source, options=coerce_dict(data.get('options')))
|
|
159
156
|
|
|
160
157
|
|
|
161
158
|
@dataclass(kw_only=True, slots=True)
|
|
@@ -214,18 +211,13 @@ class JobConfig:
|
|
|
214
211
|
data = maybe_mapping(obj)
|
|
215
212
|
if not data:
|
|
216
213
|
return None
|
|
217
|
-
name
|
|
218
|
-
if name is None:
|
|
214
|
+
if (name := _require_str(data, 'name')) is None:
|
|
219
215
|
return None
|
|
220
216
|
|
|
221
|
-
description = _coerce_optional_str(data.get('description'))
|
|
222
|
-
|
|
223
|
-
depends_on = _parse_depends_on(data.get('depends_on'))
|
|
224
|
-
|
|
225
217
|
return cls(
|
|
226
218
|
name=name,
|
|
227
|
-
description=description,
|
|
228
|
-
depends_on=depends_on,
|
|
219
|
+
description=_coerce_optional_str(data.get('description')),
|
|
220
|
+
depends_on=_parse_depends_on(data.get('depends_on')),
|
|
229
221
|
extract=ExtractRef.from_obj(data.get('extract')),
|
|
230
222
|
validate=ValidationRef.from_obj(data.get('validate')),
|
|
231
223
|
transform=TransformRef.from_obj(data.get('transform')),
|
|
@@ -274,8 +266,7 @@ class LoadRef:
|
|
|
274
266
|
data = maybe_mapping(obj)
|
|
275
267
|
if not data:
|
|
276
268
|
return None
|
|
277
|
-
target
|
|
278
|
-
if target is None:
|
|
269
|
+
if (target := _require_str(data, 'target')) is None:
|
|
279
270
|
return None
|
|
280
271
|
return cls(
|
|
281
272
|
target=target,
|
|
@@ -321,8 +312,7 @@ class TransformRef:
|
|
|
321
312
|
data = maybe_mapping(obj)
|
|
322
313
|
if not data:
|
|
323
314
|
return None
|
|
324
|
-
pipeline
|
|
325
|
-
if pipeline is None:
|
|
315
|
+
if (pipeline := _require_str(data, 'pipeline')) is None:
|
|
326
316
|
return None
|
|
327
317
|
return cls(pipeline=pipeline)
|
|
328
318
|
|
|
@@ -372,13 +362,10 @@ class ValidationRef:
|
|
|
372
362
|
data = maybe_mapping(obj)
|
|
373
363
|
if not data:
|
|
374
364
|
return None
|
|
375
|
-
ruleset
|
|
376
|
-
if ruleset is None:
|
|
365
|
+
if (ruleset := _require_str(data, 'ruleset')) is None:
|
|
377
366
|
return None
|
|
378
|
-
severity = _coerce_optional_str(data.get('severity'))
|
|
379
|
-
phase = _coerce_optional_str(data.get('phase'))
|
|
380
367
|
return cls(
|
|
381
368
|
ruleset=ruleset,
|
|
382
|
-
severity=severity,
|
|
383
|
-
phase=phase,
|
|
369
|
+
severity=_coerce_optional_str(data.get('severity')),
|
|
370
|
+
phase=_coerce_optional_str(data.get('phase')),
|
|
384
371
|
)
|
etlplus/workflow/profile.py
CHANGED
|
@@ -18,6 +18,7 @@ from typing import Self
|
|
|
18
18
|
|
|
19
19
|
from ..types import StrAnyMap
|
|
20
20
|
from ..utils import cast_str_dict
|
|
21
|
+
from ..utils import maybe_mapping
|
|
21
22
|
|
|
22
23
|
# SECTION: EXPORTS ========================================================== #
|
|
23
24
|
|
|
@@ -56,7 +57,8 @@ class ProfileConfig:
|
|
|
56
57
|
cls,
|
|
57
58
|
obj: StrAnyMap | None,
|
|
58
59
|
) -> Self:
|
|
59
|
-
"""
|
|
60
|
+
"""
|
|
61
|
+
Parse a mapping into a :class:`ProfileConfig` instance.
|
|
60
62
|
|
|
61
63
|
Parameters
|
|
62
64
|
----------
|
|
@@ -73,7 +75,7 @@ class ProfileConfig:
|
|
|
73
75
|
return cls()
|
|
74
76
|
|
|
75
77
|
# Coerce all env values to strings using shared helper.
|
|
76
|
-
env = cast_str_dict(obj.get('env'))
|
|
78
|
+
env = cast_str_dict(maybe_mapping(obj.get('env')))
|
|
77
79
|
|
|
78
80
|
return cls(
|
|
79
81
|
default_target=obj.get('default_target'),
|
|
@@ -1,49 +1,50 @@
|
|
|
1
|
-
etlplus/README.md,sha256=
|
|
2
|
-
etlplus/__init__.py,sha256=
|
|
1
|
+
etlplus/README.md,sha256=L3un9q7Q7Mstfh0dmSjpsZMZzsOz2tvlWw4_-Y_LZEs,1887
|
|
2
|
+
etlplus/__init__.py,sha256=yHZt-sjjfPjB_CrNhcT9bcMlZCfwiul39ZhQ2VfxpRs,318
|
|
3
3
|
etlplus/__main__.py,sha256=btoROneNiigyfBU7BSzPKZ1R9gzBMpxcpsbPwmuHwTM,479
|
|
4
4
|
etlplus/__version__.py,sha256=1E0GMK_yUWCMQFKxXjTvyMwofi0qT2k4CDNiHWiymWE,327
|
|
5
|
-
etlplus/
|
|
5
|
+
etlplus/config.py,sha256=6BCI9hC1yWYAy5WclIHJlg90FYeWn5vAVrT1NWUTwpE,8817
|
|
6
|
+
etlplus/enums.py,sha256=MfQhy3XDpN7oqLrF7_WwZojl7n8cW3RAzsZGRnAbWgc,4073
|
|
6
7
|
etlplus/mixins.py,sha256=ifGpHwWv7U00yqGf-kN93vJax2IiK4jaGtTsPsO3Oak,1350
|
|
7
8
|
etlplus/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
etlplus/types.py,sha256=
|
|
9
|
+
etlplus/types.py,sha256=Op2H1dcmv0Srm9prFnBZjt7f1S4Mqrus7XrdsjoZkIM,3461
|
|
9
10
|
etlplus/utils.py,sha256=X-k_Y8i6oDjlE5aQu9sw3gPw7O2ikiSn4uoheVv_ERc,17091
|
|
10
11
|
etlplus/api/README.md,sha256=amxS_eIcsnNuVvD0x_w8nkyfedOTYbhlY0gGhaFg0DE,8705
|
|
11
|
-
etlplus/api/__init__.py,sha256=
|
|
12
|
-
etlplus/api/auth.py,sha256=
|
|
13
|
-
etlplus/api/config.py,sha256=
|
|
14
|
-
etlplus/api/endpoint_client.py,sha256=
|
|
12
|
+
etlplus/api/__init__.py,sha256=eIHkdNBZv6ViB_5MhW3f3vWMYJLFoF4Tr3Wnb3O7B4E,4647
|
|
13
|
+
etlplus/api/auth.py,sha256=PZEJIBwLwnUGfF76s32a5GnLcpDvu4ghEd-wEAHx4rU,12260
|
|
14
|
+
etlplus/api/config.py,sha256=WmH1GOQxoBAr3vUsmYIyMbXSt7kiyNbtKjyMS1dqt-A,17653
|
|
15
|
+
etlplus/api/endpoint_client.py,sha256=UtvK4h_-fxINM-5QcumkcLJsL0Uw4L0L_4RMxC024Yk,30737
|
|
15
16
|
etlplus/api/enums.py,sha256=Tvkru6V8fzQh2JM2FDLcA_yaPENOKz5JgzxLhieqEvc,1141
|
|
16
|
-
etlplus/api/errors.py,sha256=
|
|
17
|
-
etlplus/api/request_manager.py,sha256=
|
|
18
|
-
etlplus/api/retry_manager.py,sha256=
|
|
19
|
-
etlplus/api/transport.py,sha256=
|
|
20
|
-
etlplus/api/types.py,sha256=
|
|
21
|
-
etlplus/api/utils.py,sha256=
|
|
22
|
-
etlplus/api/pagination/__init__.py,sha256=
|
|
17
|
+
etlplus/api/errors.py,sha256=8LuZfExUpZ67PPqPr6SdAmFA-wc0ocw4JHoBYyEcg0s,4664
|
|
18
|
+
etlplus/api/request_manager.py,sha256=K3tlRFflUM-_S-optnHzJx_AWcbd0ZQGVX_NytkN4zg,18690
|
|
19
|
+
etlplus/api/retry_manager.py,sha256=RV5xkmbExNHF_b-IN5RWx2wawiJzeklc9miGXPQb7U4,11326
|
|
20
|
+
etlplus/api/transport.py,sha256=f9hgtlnz5fFUsMYWdwAkSsdULJSv-276ekP8u_k3e4Y,9448
|
|
21
|
+
etlplus/api/types.py,sha256=gxwmgPDra7OfAPjJv2Mq45axd_s4TiGAqYtMCx167UM,8008
|
|
22
|
+
etlplus/api/utils.py,sha256=cxQYV0iAbhr65_yvhSii5jhfNcVQGgdwuwO86PJVD-s,26415
|
|
23
|
+
etlplus/api/pagination/__init__.py,sha256=K76nkMnMyM81wzbKTQynq1rRv81ndEUVEuF6cmPzvKQ,1401
|
|
23
24
|
etlplus/api/pagination/client.py,sha256=yMEpWqRxTCD4zRc9OYtEyUtShpGH5atiHFEAt95v2FE,5394
|
|
24
|
-
etlplus/api/pagination/config.py,sha256=
|
|
25
|
+
etlplus/api/pagination/config.py,sha256=pt4yAGr03Esr1gEZg3Nm6kfBOM1FpWwf_t6XTpvBd4s,13596
|
|
25
26
|
etlplus/api/pagination/paginator.py,sha256=B0OK_0FVmUz3-lCDeKgDOqYJOoEQtjO6I5eSmK58tbY,24433
|
|
26
|
-
etlplus/api/rate_limiting/__init__.py,sha256=
|
|
27
|
-
etlplus/api/rate_limiting/config.py,sha256=
|
|
28
|
-
etlplus/api/rate_limiting/rate_limiter.py,sha256=
|
|
27
|
+
etlplus/api/rate_limiting/__init__.py,sha256=8VIjkW2wGjTFJjjAqOBSFKcKsBFuYndS4o33PLSo_q8,1072
|
|
28
|
+
etlplus/api/rate_limiting/config.py,sha256=U8T8BxrX87uFR-ksTG1FkmxoVr-FTaLIa0wWeXIcZss,9775
|
|
29
|
+
etlplus/api/rate_limiting/rate_limiter.py,sha256=qmOf15qvhFk2htMsGcHfgzATqOBd2BdrG8ShadfOIgY,7035
|
|
29
30
|
etlplus/cli/README.md,sha256=8H_G2d3HteYIU6ReX9K9DM485QjWDT5vHMQbGD_vv20,1237
|
|
30
31
|
etlplus/cli/__init__.py,sha256=J97-Rv931IL1_b4AXnB7Fbbd7HKnHBpx18NQfC_kE6c,299
|
|
31
|
-
etlplus/cli/commands.py,sha256=
|
|
32
|
+
etlplus/cli/commands.py,sha256=Mbnu_YYUrOumbDjkul9x5VjP8VXW5u08xNi4nLF9Yyo,25048
|
|
32
33
|
etlplus/cli/constants.py,sha256=0F7dXIQKWUhhVu2Us527GJeknJIWpBqz7CK2e5OQgcE,1947
|
|
33
|
-
etlplus/cli/handlers.py,sha256=
|
|
34
|
+
etlplus/cli/handlers.py,sha256=JdN7W7mqmQL9xyU7PkBtsQf7eu3j5-E2AhAQvbfy-4g,18470
|
|
34
35
|
etlplus/cli/io.py,sha256=tGGNQ4ecezqj-mD285fgBVrYdphdeqApsyV9VojOj1I,7836
|
|
35
36
|
etlplus/cli/main.py,sha256=68_uJwmWajhOC9o4R_ns8IQloC9BFmAKC_9GlQOxKWg,5239
|
|
36
37
|
etlplus/cli/options.py,sha256=vfXT3YLh7wG1iC-aTdSg6ItMC8l6n0Lozmy53XjqLbA,1199
|
|
37
38
|
etlplus/cli/state.py,sha256=3Dq5BKct0uAvRajtc2yHbsX7wqepZOwlAMKsyvQcnqk,7918
|
|
38
39
|
etlplus/cli/types.py,sha256=tclhKVJXDqHzlTQBYKARfqMgDOcuBJ-Zej2pvFy96WM,652
|
|
39
|
-
etlplus/connector/__init__.py,sha256=
|
|
40
|
-
etlplus/connector/api.py,sha256=
|
|
40
|
+
etlplus/connector/__init__.py,sha256=C1nMuEvCnYS07kpoP91aWEg1utV1D4bO603OzveF7s0,1012
|
|
41
|
+
etlplus/connector/api.py,sha256=uXoQvOGGnZEP96H0O19nMgu7uiBfTqEFNuFl0r9oBbQ,4531
|
|
41
42
|
etlplus/connector/connector.py,sha256=OQP4kK_1O6g9FnDBrE3L58LOSfImsK5EBHtKI4N71u8,574
|
|
42
43
|
etlplus/connector/core.py,sha256=0GeXjlZFnyS-4j7jR_AtclQtELE6x-vodHJ4rfjFLL8,2795
|
|
43
|
-
etlplus/connector/database.py,sha256=
|
|
44
|
+
etlplus/connector/database.py,sha256=Y8fzcbzucIZW64g9zkqO-M_H02CiW5lB0IDk0RynWJo,3014
|
|
44
45
|
etlplus/connector/enums.py,sha256=43NziUOpol4YvBtM13WJJzY1EAQOjaWESxLl7J2ZT8U,1069
|
|
45
|
-
etlplus/connector/file.py,sha256=
|
|
46
|
-
etlplus/connector/types.py,sha256=
|
|
46
|
+
etlplus/connector/file.py,sha256=AsEXUHOokP2s5NQoTazF3Skz7qMj-1FNdvRZj9LfdbM,2858
|
|
47
|
+
etlplus/connector/types.py,sha256=51UPD4edtMRiRL35ZVfbmKTodhrLUiRP5P067SZGzms,953
|
|
47
48
|
etlplus/connector/utils.py,sha256=fS2hPAfuhKTg_L2xDxF5fJnsO1SuuDIiEWU7GuaJKUM,2933
|
|
48
49
|
etlplus/database/README.md,sha256=3Af5BEGLkBmMoGOLtS1GQuj4wKPh_CwSp5NEPMf2uaY,1435
|
|
49
50
|
etlplus/database/__init__.py,sha256=AKJsDl2RHuRGPS-eXgNJeh4aSncJP5Y0yLApBF6i7i8,1052
|
|
@@ -116,26 +117,27 @@ etlplus/file/yaml.py,sha256=b_SxDSEQPVXQv9a9Ih4wAcI940pE5Ksy5pQE6K6ckhw,2062
|
|
|
116
117
|
etlplus/file/zip.py,sha256=8wnmnGW_pGTx65736CzAG67XIi5y98KxucRT8sNDeuQ,4195
|
|
117
118
|
etlplus/file/zsav.py,sha256=5hMuBjYeHw--UL2ZCCDn6TzJkr_YNhdQhvKI6nr3WW0,1674
|
|
118
119
|
etlplus/ops/README.md,sha256=8omi7DYZhelc26JKk8Cm8QR8I3OGwziysPj1ivx41iQ,1380
|
|
119
|
-
etlplus/ops/__init__.py,sha256=
|
|
120
|
-
etlplus/ops/
|
|
121
|
-
etlplus/ops/
|
|
122
|
-
etlplus/ops/
|
|
123
|
-
etlplus/ops/
|
|
124
|
-
etlplus/ops/
|
|
125
|
-
etlplus/ops/
|
|
120
|
+
etlplus/ops/__init__.py,sha256=r5_-pPhSLCD1nq1EbN0rQrLOGpudueeIxCH_JvT2bt0,1718
|
|
121
|
+
etlplus/ops/enums.py,sha256=dC_8CfaTiB2i83Az-oG-2hkjMuAfDADNbcMF2f94UeU,4014
|
|
122
|
+
etlplus/ops/extract.py,sha256=fPk8LLjEmCZ5U59IUm15vG5aXTmduteCqtsVIlxvvxI,11022
|
|
123
|
+
etlplus/ops/load.py,sha256=yicciVwomUKkdbhuRqbavKBNpT2Hg813BnQzG6IgF4o,10811
|
|
124
|
+
etlplus/ops/run.py,sha256=4HWelMevW0pW_76lJkoMcbzeQMiThMbxzO09wx6yoHg,11278
|
|
125
|
+
etlplus/ops/transform.py,sha256=-41uw_pwOGsMTUYxtXaeYOmTF_fTkN-L4Q9KT1OFe78,25671
|
|
126
|
+
etlplus/ops/types.py,sha256=Cvp8AJzJhJ1iYjyHd7j9ZLioxE2NdK__3g6fOI0qq6Q,4198
|
|
127
|
+
etlplus/ops/utils.py,sha256=9UXym1W4qCMxBkcqCPUmI1QJ27yh1kOAbVnI1KsAGwE,10855
|
|
128
|
+
etlplus/ops/validate.py,sha256=VtMhrH6itd_PFH4IhBOndvJpxxOPI56OAJhnrSyT_6U,13323
|
|
126
129
|
etlplus/templates/README.md,sha256=IfPXlj1TGVA-uFWosHJhE2rabFW-znxOlOMazO9Z5cE,1361
|
|
127
130
|
etlplus/templates/__init__.py,sha256=tsniN7XJYs3NwYxJ6c2HD5upHP3CDkLx-bQCMt97UOM,106
|
|
128
131
|
etlplus/templates/ddl.sql.j2,sha256=s8fMWvcb4eaJVXkifuib1aQPljtZ8buuyB_uA-ZdU3Q,4734
|
|
129
132
|
etlplus/templates/view.sql.j2,sha256=Iy8DHfhq5yyvrUKDxqp_aHIEXY4Tm6j4wT7YDEFWAhk,2180
|
|
130
|
-
etlplus/workflow/README.md,sha256=
|
|
131
|
-
etlplus/workflow/__init__.py,sha256=
|
|
132
|
-
etlplus/workflow/dag.py,sha256
|
|
133
|
-
etlplus/workflow/jobs.py,sha256=
|
|
134
|
-
etlplus/workflow/
|
|
135
|
-
etlplus/
|
|
136
|
-
etlplus-0.16.
|
|
137
|
-
etlplus-0.16.
|
|
138
|
-
etlplus-0.16.
|
|
139
|
-
etlplus-0.16.
|
|
140
|
-
etlplus-0.16.
|
|
141
|
-
etlplus-0.16.0.dist-info/RECORD,,
|
|
133
|
+
etlplus/workflow/README.md,sha256=QelyVFGX-sZM9mx3v6BXkzX36hv6MI1yK4eCPSOKNwI,1050
|
|
134
|
+
etlplus/workflow/__init__.py,sha256=XgCQr684om0rONrQZ61yQ0r4qqFQL0iLAAB2Mn2BRSE,594
|
|
135
|
+
etlplus/workflow/dag.py,sha256=-f1x8N1eb-PUuiOwEvFLmJwfR7JaMDJihlCHlhrFhgE,2937
|
|
136
|
+
etlplus/workflow/jobs.py,sha256=hLE9QJUzQaI0aOEon0P-xxxa6xHp997ANei4F310WRY,8711
|
|
137
|
+
etlplus/workflow/profile.py,sha256=FQU3bzBZ9_yjKC9kCXKN1FQDS9zjNUjtWB1r3UL95_Q,1993
|
|
138
|
+
etlplus-0.16.6.dist-info/licenses/LICENSE,sha256=MuNO63i6kWmgnV2pbP2SLqP54mk1BGmu7CmbtxMmT-U,1069
|
|
139
|
+
etlplus-0.16.6.dist-info/METADATA,sha256=_6gQGwfRwLCcr9OF_s313Nuka2e4TvxOsyHtu4M-JSE,28114
|
|
140
|
+
etlplus-0.16.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
141
|
+
etlplus-0.16.6.dist-info/entry_points.txt,sha256=6w-2-jzuPa55spzK34h-UKh2JTEShh38adFRONNP9QE,45
|
|
142
|
+
etlplus-0.16.6.dist-info/top_level.txt,sha256=aWWF-udn_sLGuHTM6W6MLh99ArS9ROkUWO8Mi8y1_2U,8
|
|
143
|
+
etlplus-0.16.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|