etlplus 0.15.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 +25 -3
- etlplus/__init__.py +2 -0
- etlplus/api/README.md +31 -0
- etlplus/api/__init__.py +14 -14
- etlplus/api/auth.py +10 -7
- etlplus/api/config.py +8 -13
- etlplus/api/endpoint_client.py +20 -20
- etlplus/api/errors.py +4 -4
- etlplus/api/pagination/__init__.py +6 -6
- etlplus/api/pagination/config.py +12 -10
- etlplus/api/pagination/paginator.py +6 -7
- etlplus/api/rate_limiting/__init__.py +2 -2
- etlplus/api/rate_limiting/config.py +14 -14
- etlplus/api/rate_limiting/rate_limiter.py +3 -3
- etlplus/api/request_manager.py +4 -4
- etlplus/api/retry_manager.py +8 -8
- etlplus/api/transport.py +11 -11
- etlplus/api/types.py +131 -11
- etlplus/api/utils.py +50 -50
- etlplus/cli/commands.py +93 -60
- etlplus/cli/constants.py +1 -1
- etlplus/cli/handlers.py +43 -26
- etlplus/cli/io.py +2 -2
- etlplus/cli/main.py +2 -2
- etlplus/cli/state.py +4 -7
- etlplus/{workflow/pipeline.py → config.py} +62 -99
- etlplus/connector/__init__.py +43 -0
- etlplus/connector/api.py +161 -0
- etlplus/connector/connector.py +26 -0
- etlplus/connector/core.py +132 -0
- etlplus/connector/database.py +122 -0
- etlplus/connector/enums.py +52 -0
- etlplus/connector/file.py +120 -0
- etlplus/connector/types.py +40 -0
- etlplus/connector/utils.py +122 -0
- etlplus/database/ddl.py +2 -2
- etlplus/database/engine.py +19 -3
- etlplus/database/orm.py +2 -0
- etlplus/enums.py +36 -200
- etlplus/file/_imports.py +1 -0
- etlplus/file/_io.py +52 -4
- etlplus/file/accdb.py +3 -2
- etlplus/file/arrow.py +3 -2
- etlplus/file/avro.py +3 -2
- etlplus/file/bson.py +3 -2
- etlplus/file/cbor.py +3 -2
- etlplus/file/cfg.py +3 -2
- etlplus/file/conf.py +3 -2
- etlplus/file/core.py +11 -8
- etlplus/file/csv.py +3 -2
- etlplus/file/dat.py +3 -2
- etlplus/file/dta.py +3 -2
- etlplus/file/duckdb.py +3 -2
- etlplus/file/enums.py +1 -1
- etlplus/file/feather.py +3 -2
- etlplus/file/fwf.py +3 -2
- etlplus/file/gz.py +3 -2
- etlplus/file/hbs.py +3 -2
- etlplus/file/hdf5.py +3 -2
- etlplus/file/ini.py +3 -2
- etlplus/file/ion.py +3 -2
- etlplus/file/jinja2.py +3 -2
- etlplus/file/json.py +5 -16
- etlplus/file/log.py +3 -2
- etlplus/file/mat.py +3 -2
- etlplus/file/mdb.py +3 -2
- etlplus/file/msgpack.py +3 -2
- etlplus/file/mustache.py +3 -2
- etlplus/file/nc.py +3 -2
- etlplus/file/ndjson.py +3 -2
- etlplus/file/numbers.py +3 -2
- etlplus/file/ods.py +3 -2
- etlplus/file/orc.py +3 -2
- etlplus/file/parquet.py +3 -2
- etlplus/file/pb.py +3 -2
- etlplus/file/pbf.py +3 -2
- etlplus/file/properties.py +3 -2
- etlplus/file/proto.py +3 -2
- etlplus/file/psv.py +3 -2
- etlplus/file/rda.py +3 -2
- etlplus/file/rds.py +3 -2
- etlplus/file/sas7bdat.py +3 -2
- etlplus/file/sav.py +3 -2
- etlplus/file/sqlite.py +3 -2
- etlplus/file/stub.py +1 -0
- etlplus/file/sylk.py +3 -2
- etlplus/file/tab.py +3 -2
- etlplus/file/toml.py +3 -2
- etlplus/file/tsv.py +3 -2
- etlplus/file/txt.py +4 -3
- etlplus/file/vm.py +3 -2
- etlplus/file/wks.py +3 -2
- etlplus/file/xls.py +3 -2
- etlplus/file/xlsm.py +3 -2
- etlplus/file/xlsx.py +3 -2
- etlplus/file/xml.py +9 -3
- etlplus/file/xpt.py +3 -2
- etlplus/file/yaml.py +5 -16
- etlplus/file/zip.py +3 -2
- etlplus/file/zsav.py +3 -2
- etlplus/ops/__init__.py +1 -0
- etlplus/ops/enums.py +173 -0
- etlplus/ops/extract.py +222 -23
- etlplus/ops/load.py +155 -36
- etlplus/ops/run.py +92 -107
- etlplus/ops/transform.py +48 -29
- etlplus/ops/types.py +147 -0
- etlplus/ops/utils.py +11 -40
- etlplus/ops/validate.py +16 -16
- etlplus/types.py +6 -102
- etlplus/utils.py +163 -29
- etlplus/workflow/README.md +0 -24
- etlplus/workflow/__init__.py +2 -15
- etlplus/workflow/dag.py +23 -1
- etlplus/workflow/jobs.py +83 -39
- etlplus/workflow/profile.py +4 -2
- {etlplus-0.15.0.dist-info → etlplus-0.16.6.dist-info}/METADATA +4 -4
- etlplus-0.16.6.dist-info/RECORD +143 -0
- {etlplus-0.15.0.dist-info → etlplus-0.16.6.dist-info}/WHEEL +1 -1
- etlplus/config/README.md +0 -50
- etlplus/config/__init__.py +0 -33
- etlplus/config/types.py +0 -140
- etlplus/dag.py +0 -103
- etlplus/workflow/connector.py +0 -373
- etlplus/workflow/types.py +0 -115
- etlplus/workflow/utils.py +0 -120
- etlplus-0.15.0.dist-info/RECORD +0 -139
- {etlplus-0.15.0.dist-info → etlplus-0.16.6.dist-info}/entry_points.txt +0 -0
- {etlplus-0.15.0.dist-info → etlplus-0.16.6.dist-info}/licenses/LICENSE +0 -0
- {etlplus-0.15.0.dist-info → etlplus-0.16.6.dist-info}/top_level.txt +0 -0
etlplus/workflow/__init__.py
CHANGED
|
@@ -6,38 +6,25 @@ Job workflow helpers.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
from .connector import Connector
|
|
10
|
-
from .connector import ConnectorApi
|
|
11
|
-
from .connector import ConnectorDb
|
|
12
|
-
from .connector import ConnectorFile
|
|
13
|
-
from .connector import parse_connector
|
|
14
9
|
from .dag import topological_sort_jobs
|
|
15
10
|
from .jobs import ExtractRef
|
|
16
11
|
from .jobs import JobConfig
|
|
17
12
|
from .jobs import LoadRef
|
|
18
13
|
from .jobs import TransformRef
|
|
19
14
|
from .jobs import ValidationRef
|
|
20
|
-
from .
|
|
21
|
-
from .pipeline import load_pipeline_config
|
|
15
|
+
from .profile import ProfileConfig
|
|
22
16
|
|
|
23
17
|
# SECTION: EXPORTS ========================================================== #
|
|
24
18
|
|
|
25
19
|
|
|
26
20
|
__all__ = [
|
|
27
21
|
# Data Classes
|
|
28
|
-
'ConnectorApi',
|
|
29
|
-
'ConnectorDb',
|
|
30
|
-
'ConnectorFile',
|
|
31
22
|
'ExtractRef',
|
|
32
23
|
'JobConfig',
|
|
33
24
|
'LoadRef',
|
|
34
|
-
'
|
|
25
|
+
'ProfileConfig',
|
|
35
26
|
'TransformRef',
|
|
36
27
|
'ValidationRef',
|
|
37
28
|
# Functions
|
|
38
|
-
'load_pipeline_config',
|
|
39
|
-
'parse_connector',
|
|
40
29
|
'topological_sort_jobs',
|
|
41
|
-
# Type Aliases
|
|
42
|
-
'Connector',
|
|
43
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,19 +6,19 @@ 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
|
|
20
19
|
from typing import Self
|
|
21
20
|
|
|
21
|
+
from ..types import StrAnyMap
|
|
22
22
|
from ..utils import coerce_dict
|
|
23
23
|
from ..utils import maybe_mapping
|
|
24
24
|
|
|
@@ -35,6 +35,77 @@ __all__ = [
|
|
|
35
35
|
]
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
# SECTION: INTERNAL FUNCTIONS =============================================== #
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _coerce_optional_str(value: Any) -> str | None:
|
|
42
|
+
"""
|
|
43
|
+
Normalize optional string values, coercing non-strings when needed.
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
value : Any
|
|
48
|
+
Optional value to normalize.
|
|
49
|
+
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
str | None
|
|
53
|
+
``None`` when *value* is ``None``; otherwise a string value.
|
|
54
|
+
"""
|
|
55
|
+
if value is None:
|
|
56
|
+
return None
|
|
57
|
+
return value if isinstance(value, str) else str(value)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _parse_depends_on(
|
|
61
|
+
value: Any,
|
|
62
|
+
) -> list[str]:
|
|
63
|
+
"""
|
|
64
|
+
Normalize dependency declarations into a string list.
|
|
65
|
+
|
|
66
|
+
Parameters
|
|
67
|
+
----------
|
|
68
|
+
value : Any
|
|
69
|
+
Input dependency specification (string or list of strings).
|
|
70
|
+
|
|
71
|
+
Returns
|
|
72
|
+
-------
|
|
73
|
+
list[str]
|
|
74
|
+
Normalized dependency list.
|
|
75
|
+
"""
|
|
76
|
+
if isinstance(value, str):
|
|
77
|
+
return [value]
|
|
78
|
+
if isinstance(value, Sequence) and not isinstance(
|
|
79
|
+
value,
|
|
80
|
+
(str, bytes, bytearray),
|
|
81
|
+
):
|
|
82
|
+
return [entry for entry in value if isinstance(entry, str)]
|
|
83
|
+
return []
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _require_str(
|
|
87
|
+
data: StrAnyMap,
|
|
88
|
+
key: str,
|
|
89
|
+
) -> str | None:
|
|
90
|
+
"""
|
|
91
|
+
Extract a required string field from a mapping.
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
data : StrAnyMap
|
|
96
|
+
Mapping containing the target field.
|
|
97
|
+
key : str
|
|
98
|
+
Field name to extract.
|
|
99
|
+
|
|
100
|
+
Returns
|
|
101
|
+
-------
|
|
102
|
+
str | None
|
|
103
|
+
The string value when present and valid; otherwise ``None``.
|
|
104
|
+
"""
|
|
105
|
+
value = data.get(key)
|
|
106
|
+
return value if isinstance(value, str) else None
|
|
107
|
+
|
|
108
|
+
|
|
38
109
|
# SECTION: DATA CLASSES ===================================================== #
|
|
39
110
|
|
|
40
111
|
|
|
@@ -79,13 +150,9 @@ class ExtractRef:
|
|
|
79
150
|
data = maybe_mapping(obj)
|
|
80
151
|
if not data:
|
|
81
152
|
return None
|
|
82
|
-
source
|
|
83
|
-
if not isinstance(source, str):
|
|
153
|
+
if (source := _require_str(data, 'source')) is None:
|
|
84
154
|
return None
|
|
85
|
-
return cls(
|
|
86
|
-
source=source,
|
|
87
|
-
options=coerce_dict(data.get('options')),
|
|
88
|
-
)
|
|
155
|
+
return cls(source=source, options=coerce_dict(data.get('options')))
|
|
89
156
|
|
|
90
157
|
|
|
91
158
|
@dataclass(kw_only=True, slots=True)
|
|
@@ -144,27 +211,13 @@ class JobConfig:
|
|
|
144
211
|
data = maybe_mapping(obj)
|
|
145
212
|
if not data:
|
|
146
213
|
return None
|
|
147
|
-
name
|
|
148
|
-
if not isinstance(name, str):
|
|
214
|
+
if (name := _require_str(data, 'name')) is None:
|
|
149
215
|
return None
|
|
150
216
|
|
|
151
|
-
description = data.get('description')
|
|
152
|
-
if description is not None and not isinstance(description, str):
|
|
153
|
-
description = str(description)
|
|
154
|
-
|
|
155
|
-
depends_raw = data.get('depends_on')
|
|
156
|
-
depends_on: list[str] = []
|
|
157
|
-
if isinstance(depends_raw, str):
|
|
158
|
-
depends_on = [depends_raw]
|
|
159
|
-
elif isinstance(depends_raw, list):
|
|
160
|
-
for entry in depends_raw:
|
|
161
|
-
if isinstance(entry, str):
|
|
162
|
-
depends_on.append(entry)
|
|
163
|
-
|
|
164
217
|
return cls(
|
|
165
218
|
name=name,
|
|
166
|
-
description=description,
|
|
167
|
-
depends_on=depends_on,
|
|
219
|
+
description=_coerce_optional_str(data.get('description')),
|
|
220
|
+
depends_on=_parse_depends_on(data.get('depends_on')),
|
|
168
221
|
extract=ExtractRef.from_obj(data.get('extract')),
|
|
169
222
|
validate=ValidationRef.from_obj(data.get('validate')),
|
|
170
223
|
transform=TransformRef.from_obj(data.get('transform')),
|
|
@@ -213,8 +266,7 @@ class LoadRef:
|
|
|
213
266
|
data = maybe_mapping(obj)
|
|
214
267
|
if not data:
|
|
215
268
|
return None
|
|
216
|
-
target
|
|
217
|
-
if not isinstance(target, str):
|
|
269
|
+
if (target := _require_str(data, 'target')) is None:
|
|
218
270
|
return None
|
|
219
271
|
return cls(
|
|
220
272
|
target=target,
|
|
@@ -260,8 +312,7 @@ class TransformRef:
|
|
|
260
312
|
data = maybe_mapping(obj)
|
|
261
313
|
if not data:
|
|
262
314
|
return None
|
|
263
|
-
pipeline
|
|
264
|
-
if not isinstance(pipeline, str):
|
|
315
|
+
if (pipeline := _require_str(data, 'pipeline')) is None:
|
|
265
316
|
return None
|
|
266
317
|
return cls(pipeline=pipeline)
|
|
267
318
|
|
|
@@ -311,17 +362,10 @@ class ValidationRef:
|
|
|
311
362
|
data = maybe_mapping(obj)
|
|
312
363
|
if not data:
|
|
313
364
|
return None
|
|
314
|
-
ruleset
|
|
315
|
-
if not isinstance(ruleset, str):
|
|
365
|
+
if (ruleset := _require_str(data, 'ruleset')) is None:
|
|
316
366
|
return None
|
|
317
|
-
severity = data.get('severity')
|
|
318
|
-
if severity is not None and not isinstance(severity, str):
|
|
319
|
-
severity = str(severity)
|
|
320
|
-
phase = data.get('phase')
|
|
321
|
-
if phase is not None and not isinstance(phase, str):
|
|
322
|
-
phase = str(phase)
|
|
323
367
|
return cls(
|
|
324
368
|
ruleset=ruleset,
|
|
325
|
-
severity=severity,
|
|
326
|
-
phase=phase,
|
|
369
|
+
severity=_coerce_optional_str(data.get('severity')),
|
|
370
|
+
phase=_coerce_optional_str(data.get('phase')),
|
|
327
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,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: etlplus
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.6
|
|
4
4
|
Summary: A Swiss Army knife for simple ETL operations
|
|
5
5
|
Home-page: https://github.com/Dagitali/ETLPlus
|
|
6
6
|
Author: ETLPlus Team
|
|
@@ -805,12 +805,12 @@ Navigate to detailed documentation for each subpackage:
|
|
|
805
805
|
|
|
806
806
|
- [etlplus.api](etlplus/api/README.md): Lightweight HTTP client and paginated REST helpers
|
|
807
807
|
- [etlplus.file](etlplus/file/README.md): Unified file format support and helpers
|
|
808
|
-
- [etlplus.
|
|
809
|
-
and profiles
|
|
810
|
-
- [etlplus.cli](etlplus/cli/README.md): Command-line interface for ETLPlus workflows
|
|
808
|
+
- [etlplus.cli](etlplus/cli/README.md): Command-line interface definitions for `etlplus`
|
|
811
809
|
- [etlplus.database](etlplus/database/README.md): Database engine, schema, and ORM helpers
|
|
812
810
|
- [etlplus.templates](etlplus/templates/README.md): SQL and DDL template helpers
|
|
813
811
|
- [etlplus.validation](etlplus/validation/README.md): Data validation utilities and helpers
|
|
812
|
+
- [etlplus.workflow](etlplus/workflow/README.md): Helpers for data connectors, pipelines, jobs, and
|
|
813
|
+
profiles
|
|
814
814
|
|
|
815
815
|
### Community Health
|
|
816
816
|
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
etlplus/README.md,sha256=L3un9q7Q7Mstfh0dmSjpsZMZzsOz2tvlWw4_-Y_LZEs,1887
|
|
2
|
+
etlplus/__init__.py,sha256=yHZt-sjjfPjB_CrNhcT9bcMlZCfwiul39ZhQ2VfxpRs,318
|
|
3
|
+
etlplus/__main__.py,sha256=btoROneNiigyfBU7BSzPKZ1R9gzBMpxcpsbPwmuHwTM,479
|
|
4
|
+
etlplus/__version__.py,sha256=1E0GMK_yUWCMQFKxXjTvyMwofi0qT2k4CDNiHWiymWE,327
|
|
5
|
+
etlplus/config.py,sha256=6BCI9hC1yWYAy5WclIHJlg90FYeWn5vAVrT1NWUTwpE,8817
|
|
6
|
+
etlplus/enums.py,sha256=MfQhy3XDpN7oqLrF7_WwZojl7n8cW3RAzsZGRnAbWgc,4073
|
|
7
|
+
etlplus/mixins.py,sha256=ifGpHwWv7U00yqGf-kN93vJax2IiK4jaGtTsPsO3Oak,1350
|
|
8
|
+
etlplus/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
etlplus/types.py,sha256=Op2H1dcmv0Srm9prFnBZjt7f1S4Mqrus7XrdsjoZkIM,3461
|
|
10
|
+
etlplus/utils.py,sha256=X-k_Y8i6oDjlE5aQu9sw3gPw7O2ikiSn4uoheVv_ERc,17091
|
|
11
|
+
etlplus/api/README.md,sha256=amxS_eIcsnNuVvD0x_w8nkyfedOTYbhlY0gGhaFg0DE,8705
|
|
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
|
|
16
|
+
etlplus/api/enums.py,sha256=Tvkru6V8fzQh2JM2FDLcA_yaPENOKz5JgzxLhieqEvc,1141
|
|
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
|
|
24
|
+
etlplus/api/pagination/client.py,sha256=yMEpWqRxTCD4zRc9OYtEyUtShpGH5atiHFEAt95v2FE,5394
|
|
25
|
+
etlplus/api/pagination/config.py,sha256=pt4yAGr03Esr1gEZg3Nm6kfBOM1FpWwf_t6XTpvBd4s,13596
|
|
26
|
+
etlplus/api/pagination/paginator.py,sha256=B0OK_0FVmUz3-lCDeKgDOqYJOoEQtjO6I5eSmK58tbY,24433
|
|
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
|
|
30
|
+
etlplus/cli/README.md,sha256=8H_G2d3HteYIU6ReX9K9DM485QjWDT5vHMQbGD_vv20,1237
|
|
31
|
+
etlplus/cli/__init__.py,sha256=J97-Rv931IL1_b4AXnB7Fbbd7HKnHBpx18NQfC_kE6c,299
|
|
32
|
+
etlplus/cli/commands.py,sha256=Mbnu_YYUrOumbDjkul9x5VjP8VXW5u08xNi4nLF9Yyo,25048
|
|
33
|
+
etlplus/cli/constants.py,sha256=0F7dXIQKWUhhVu2Us527GJeknJIWpBqz7CK2e5OQgcE,1947
|
|
34
|
+
etlplus/cli/handlers.py,sha256=JdN7W7mqmQL9xyU7PkBtsQf7eu3j5-E2AhAQvbfy-4g,18470
|
|
35
|
+
etlplus/cli/io.py,sha256=tGGNQ4ecezqj-mD285fgBVrYdphdeqApsyV9VojOj1I,7836
|
|
36
|
+
etlplus/cli/main.py,sha256=68_uJwmWajhOC9o4R_ns8IQloC9BFmAKC_9GlQOxKWg,5239
|
|
37
|
+
etlplus/cli/options.py,sha256=vfXT3YLh7wG1iC-aTdSg6ItMC8l6n0Lozmy53XjqLbA,1199
|
|
38
|
+
etlplus/cli/state.py,sha256=3Dq5BKct0uAvRajtc2yHbsX7wqepZOwlAMKsyvQcnqk,7918
|
|
39
|
+
etlplus/cli/types.py,sha256=tclhKVJXDqHzlTQBYKARfqMgDOcuBJ-Zej2pvFy96WM,652
|
|
40
|
+
etlplus/connector/__init__.py,sha256=C1nMuEvCnYS07kpoP91aWEg1utV1D4bO603OzveF7s0,1012
|
|
41
|
+
etlplus/connector/api.py,sha256=uXoQvOGGnZEP96H0O19nMgu7uiBfTqEFNuFl0r9oBbQ,4531
|
|
42
|
+
etlplus/connector/connector.py,sha256=OQP4kK_1O6g9FnDBrE3L58LOSfImsK5EBHtKI4N71u8,574
|
|
43
|
+
etlplus/connector/core.py,sha256=0GeXjlZFnyS-4j7jR_AtclQtELE6x-vodHJ4rfjFLL8,2795
|
|
44
|
+
etlplus/connector/database.py,sha256=Y8fzcbzucIZW64g9zkqO-M_H02CiW5lB0IDk0RynWJo,3014
|
|
45
|
+
etlplus/connector/enums.py,sha256=43NziUOpol4YvBtM13WJJzY1EAQOjaWESxLl7J2ZT8U,1069
|
|
46
|
+
etlplus/connector/file.py,sha256=AsEXUHOokP2s5NQoTazF3Skz7qMj-1FNdvRZj9LfdbM,2858
|
|
47
|
+
etlplus/connector/types.py,sha256=51UPD4edtMRiRL35ZVfbmKTodhrLUiRP5P067SZGzms,953
|
|
48
|
+
etlplus/connector/utils.py,sha256=fS2hPAfuhKTg_L2xDxF5fJnsO1SuuDIiEWU7GuaJKUM,2933
|
|
49
|
+
etlplus/database/README.md,sha256=3Af5BEGLkBmMoGOLtS1GQuj4wKPh_CwSp5NEPMf2uaY,1435
|
|
50
|
+
etlplus/database/__init__.py,sha256=AKJsDl2RHuRGPS-eXgNJeh4aSncJP5Y0yLApBF6i7i8,1052
|
|
51
|
+
etlplus/database/ddl.py,sha256=-7EAbyLkU8m3eYlHSNLFOQr1I4fPEbF0hTyByzjyvsU,7909
|
|
52
|
+
etlplus/database/engine.py,sha256=eDFnp4vzhoKuyLJSeHYpndHLUr27neS7CgdvMw8mNok,4384
|
|
53
|
+
etlplus/database/orm.py,sha256=ZCHkeVEUns2eievlFzmLyVKA3YVPea1xs6vrcUBZ7Jw,10010
|
|
54
|
+
etlplus/database/schema.py,sha256=813C0Dd3WE53KTYot4dgjAxctgKXLXx-8_Rk_4r2e28,7022
|
|
55
|
+
etlplus/database/types.py,sha256=_pkQyC14TzAlgyeIqZG4F5LWYknZbHw3TW68Auk7Ya0,795
|
|
56
|
+
etlplus/file/README.md,sha256=ivU8svVs1fktQiW5ozvh1N-IOSLCAQ3oM9bW8DUFwIw,3630
|
|
57
|
+
etlplus/file/__init__.py,sha256=X03bosSM-uSd6dh3ur0un6_ozFRw2Tm4PE6kVUjtXK8,475
|
|
58
|
+
etlplus/file/_imports.py,sha256=Cozv7d5G2P9PNgy2M4vrz0Wzo7hx9FTC0WcGcuVqga0,3193
|
|
59
|
+
etlplus/file/_io.py,sha256=Z3aTujy0rpbMKJHvO2UZ6bA1ohO-6ZiemyxF4GsayRc,3951
|
|
60
|
+
etlplus/file/accdb.py,sha256=mMwnNXd3rB0Z_1uN6wpiF0jL4flUmZbMBoiIS3Fq5mg,1691
|
|
61
|
+
etlplus/file/arrow.py,sha256=nkSXiDCFOSbEJX387h-c91WeYPFZehj2r3_iznVy5HE,1704
|
|
62
|
+
etlplus/file/avro.py,sha256=GR9GbDNcQ7TpaPKhcC6JL79XicSmNDIhH3cP0QDmLJg,4447
|
|
63
|
+
etlplus/file/bson.py,sha256=CYpA1PSPzyM9Dtv5ik3RG0GUwLjucJGbrhyo7THcVa0,1623
|
|
64
|
+
etlplus/file/cbor.py,sha256=NNQkCRenh9YOYdeR-w-AbUfK9sjGkwoA0Idtr-dclm4,1677
|
|
65
|
+
etlplus/file/cfg.py,sha256=HuGuxNIKPWyg14mIBlVB5Ch_npf9zObRt2mgoymzB_A,1720
|
|
66
|
+
etlplus/file/conf.py,sha256=x6OH9in-VKkTIPtlwbYEsYDJ703oFJjUFHVCoFULhvk,1778
|
|
67
|
+
etlplus/file/core.py,sha256=IzcG4pQLq3QCQhswbgdWKxHSvmzvWzYweBrz7t6HDDo,8888
|
|
68
|
+
etlplus/file/csv.py,sha256=FTdxlVs3vsaj_t7vGY-unNiCpJI2TWuiaf2_8dJan6M,1754
|
|
69
|
+
etlplus/file/dat.py,sha256=o4FN-6_HCVXuD-If3aYfIqU4QTZMvECNZ5Yx4wr15ew,1652
|
|
70
|
+
etlplus/file/dta.py,sha256=7DuvvKSgbpBoKZHm7CWJ7NKstRasp0fUEj1XF02YgsE,1626
|
|
71
|
+
etlplus/file/duckdb.py,sha256=kCFxNUEI9gEeeMWJuCHyfKVsqvhij4Q7LJVpZ3AMDYw,1641
|
|
72
|
+
etlplus/file/enums.py,sha256=5cwIfcoYGEjaX0AzaJzY0PjztKykzFTQ1HBnb2NTEXs,11065
|
|
73
|
+
etlplus/file/feather.py,sha256=joOdQf_oIu__i8hwy5X4eK6MSqh6O0kKnub2VWD_Clg,2679
|
|
74
|
+
etlplus/file/fwf.py,sha256=ktXIKatOPUs6YeB30K7BNvfwwB4BkXoYEomsvCjk_ss,1599
|
|
75
|
+
etlplus/file/gz.py,sha256=NfiXiE37rS2YC7dk1YC1ELbbEpzJdypIy-no9cVoaco,2641
|
|
76
|
+
etlplus/file/hbs.py,sha256=jxAPY10R_2vhP-1QWGBmANCI1dJ9vetaLo5Mp8kMa3Y,1624
|
|
77
|
+
etlplus/file/hdf5.py,sha256=hjpBUue5ss6R8ljZ-gYxDxpOLGBKgNvmAvn97uNmYAw,1634
|
|
78
|
+
etlplus/file/ini.py,sha256=ZL_0Wq5-yNcveyKF-minH2AFh-RmspM06myHquAobao,1711
|
|
79
|
+
etlplus/file/ion.py,sha256=ZK0g-47GQi9fCDT4EeXCgiVbWmmj7SU1WHwt-CrLwCU,1720
|
|
80
|
+
etlplus/file/jinja2.py,sha256=TV-ZIzsJIg4hJyvWI7TWaMRjqL2s18Dg3ig3Hs50_pE,1640
|
|
81
|
+
etlplus/file/json.py,sha256=vY3UYjzQzmJUAY0avR2cm70hTTED4xEF38WEEj0DhDQ,2140
|
|
82
|
+
etlplus/file/log.py,sha256=6Te617oy8RWrzCa6hC0O65ygPIpfzkLBcP-x9glwM9g,1691
|
|
83
|
+
etlplus/file/mat.py,sha256=JbZ7SziCqYZR8LljyLoSn05_-bPSzNH16KNB-wvzdpM,1664
|
|
84
|
+
etlplus/file/mdb.py,sha256=Xlxx9RZlnErOrzYRFnzzOZltc99FalhoUY-oAiiQpPg,1667
|
|
85
|
+
etlplus/file/msgpack.py,sha256=GOYfgxyK2N8Opy8kLsz4uDhVrT1vyOcVQ4eJvdhrNdA,1668
|
|
86
|
+
etlplus/file/mustache.py,sha256=qOddtbtZwDyoXzHzqxpnUoO_lWKf3NPyfp-V21o0cRw,1657
|
|
87
|
+
etlplus/file/nc.py,sha256=a1_er7Fco0FVw3GtDrd_OzZAI7U_sP9x-wi9qRgebaw,1680
|
|
88
|
+
etlplus/file/ndjson.py,sha256=jpZgLZL-Vy4a6tsm5cxy0G9kW-x-X5kFSbnUn-XjIJw,2442
|
|
89
|
+
etlplus/file/numbers.py,sha256=HkG3ISk35FZnorwECuciIiI4HZWFp9E-mRhOfhYclx8,1620
|
|
90
|
+
etlplus/file/ods.py,sha256=MVEM1E2uLFmnTyCnyhljsrgdBC8psUGSVUGLmiuZTLM,1810
|
|
91
|
+
etlplus/file/orc.py,sha256=RdK4IERoLWnGSgpBclfDmwMmtac8VYyet3Z9AFCyj2E,2612
|
|
92
|
+
etlplus/file/parquet.py,sha256=6klk-GgNnFBbsRU0J8LiGm5c67A6FcX1AEZNf-cNSPM,2768
|
|
93
|
+
etlplus/file/pb.py,sha256=0OOSmuFUfmB-DZILSA9FO2JgXfJmt9TnigH3E2gW4AI,1625
|
|
94
|
+
etlplus/file/pbf.py,sha256=89fF58WkXmOBJh8Jh2zcA0cKBkB5neXMWyz95toPnXo,1630
|
|
95
|
+
etlplus/file/properties.py,sha256=4KSRGWo_-fthVdOnJKXqUvHA2I6igcGWW9fnWJK7oLA,1728
|
|
96
|
+
etlplus/file/proto.py,sha256=LjHFWVYEIyADwpd9Lzzd1FAcM8pFXN1pwoptxEDOvfQ,1678
|
|
97
|
+
etlplus/file/psv.py,sha256=J-fPTMgTZFHZWJL6kLKaFgLXhtEtK66hJW59YLaWe9E,1736
|
|
98
|
+
etlplus/file/rda.py,sha256=dSrHwLl_qu8bhnltWIuYqxpguP3JLH39JLOVxHsHLhE,1678
|
|
99
|
+
etlplus/file/rds.py,sha256=o1IKY6CmLXSp-Iv7kBDFkT8X5QVTy5uVAZMm-7sUo4Y,1635
|
|
100
|
+
etlplus/file/sas7bdat.py,sha256=yyX7YrnmZ91EY9WeTB_eZAqjCSEgD_9WTLGpD4Sv5AY,1716
|
|
101
|
+
etlplus/file/sav.py,sha256=ij02gnYOevRV9e8dbDwi3plulkw-qEQoxccvydHXZK4,1607
|
|
102
|
+
etlplus/file/sqlite.py,sha256=NRb93RuIDlu1eRMZnYDjDBhFO88gkDT7tvpmfgA4hQE,1662
|
|
103
|
+
etlplus/file/stub.py,sha256=4vlqjIo_bBy69dIU2y2iy5fqnezt_bOuS218zyijQfs,1749
|
|
104
|
+
etlplus/file/sylk.py,sha256=QwciGJVWxEKz3TH4s7hshHHLAfKiCqBxyV4umg9EVQI,1667
|
|
105
|
+
etlplus/file/tab.py,sha256=Y9u5J-efoKIMIYnARhrPXA2KEF0pJ7deZF4zkz7ZID0,1994
|
|
106
|
+
etlplus/file/toml.py,sha256=0kGJEF2353kNQWFbYd8G4XWjuPHvdl7vPILCWglsyk0,1636
|
|
107
|
+
etlplus/file/tsv.py,sha256=SUe-UeL3zExX2idvpHiMWuRm5VQ8AyqqlNJckc9CDCU,1776
|
|
108
|
+
etlplus/file/txt.py,sha256=Ys7MmKBOiHQnRK0Bb3VuIIny2_1Ejr-V_YdPlUfOEjc,2321
|
|
109
|
+
etlplus/file/vm.py,sha256=K3EE-4TpXECcHxS1EEVmLOidkqj-MJeeztTRTRUaQ1o,1599
|
|
110
|
+
etlplus/file/wks.py,sha256=dZtf_6ObJVUj_m7XIUAzuTDQkmYk0mhA9LF3rVltatI,1665
|
|
111
|
+
etlplus/file/xls.py,sha256=dNfhaDSbSy-xQrE3qriCrmfXRQY7HqAtog91b-7RmpA,1782
|
|
112
|
+
etlplus/file/xlsm.py,sha256=pZHybknmipUHEwjQBHWiU4HfVMLkGG7Zxe3rxBrxPT0,1748
|
|
113
|
+
etlplus/file/xlsx.py,sha256=UOwz-IIeRU2GyAI8Upx2hn7v3KPZalpIaGO9hXuaOGo,2192
|
|
114
|
+
etlplus/file/xml.py,sha256=lor8KsclDSy1tdOExL1GmYpaQVcZGRNEwOd2liiPPbk,4389
|
|
115
|
+
etlplus/file/xpt.py,sha256=L70o8cIGWPeBdbfVJk-b9I9PE2MICtLkwhJjzqIeBgU,1712
|
|
116
|
+
etlplus/file/yaml.py,sha256=b_SxDSEQPVXQv9a9Ih4wAcI940pE5Ksy5pQE6K6ckhw,2062
|
|
117
|
+
etlplus/file/zip.py,sha256=8wnmnGW_pGTx65736CzAG67XIi5y98KxucRT8sNDeuQ,4195
|
|
118
|
+
etlplus/file/zsav.py,sha256=5hMuBjYeHw--UL2ZCCDn6TzJkr_YNhdQhvKI6nr3WW0,1674
|
|
119
|
+
etlplus/ops/README.md,sha256=8omi7DYZhelc26JKk8Cm8QR8I3OGwziysPj1ivx41iQ,1380
|
|
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
|
|
129
|
+
etlplus/templates/README.md,sha256=IfPXlj1TGVA-uFWosHJhE2rabFW-znxOlOMazO9Z5cE,1361
|
|
130
|
+
etlplus/templates/__init__.py,sha256=tsniN7XJYs3NwYxJ6c2HD5upHP3CDkLx-bQCMt97UOM,106
|
|
131
|
+
etlplus/templates/ddl.sql.j2,sha256=s8fMWvcb4eaJVXkifuib1aQPljtZ8buuyB_uA-ZdU3Q,4734
|
|
132
|
+
etlplus/templates/view.sql.j2,sha256=Iy8DHfhq5yyvrUKDxqp_aHIEXY4Tm6j4wT7YDEFWAhk,2180
|
|
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,,
|
etlplus/config/README.md
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# `etlplus.config` Subpackage
|
|
2
|
-
|
|
3
|
-
Documentation for the `etlplus.config` subpackage: type definitions and config shape helpers for
|
|
4
|
-
ETLPlus.
|
|
5
|
-
|
|
6
|
-
- Exposes TypedDict-based config schemas for API profiles and endpoints
|
|
7
|
-
- Provides exported type aliases for API configuration maps
|
|
8
|
-
- Designed for Python 3.13 typing and editor assistance (runtime parsing lives elsewhere)
|
|
9
|
-
|
|
10
|
-
Back to project overview: see the top-level [README](../../README.md).
|
|
11
|
-
|
|
12
|
-
- [`etlplus.config` Subpackage](#etlplusconfig-subpackage)
|
|
13
|
-
- [Modules](#modules)
|
|
14
|
-
- [Exported Types](#exported-types)
|
|
15
|
-
- [Example: Typing an API Config](#example-typing-an-api-config)
|
|
16
|
-
- [See Also](#see-also)
|
|
17
|
-
|
|
18
|
-
## Modules
|
|
19
|
-
|
|
20
|
-
- `etlplus.config.__init__`: package exports and high-level package notes
|
|
21
|
-
- `etlplus.config.types`: TypedDict-based config schemas
|
|
22
|
-
|
|
23
|
-
## Exported Types
|
|
24
|
-
|
|
25
|
-
- `ApiConfigMap`: top-level API config shape
|
|
26
|
-
- `ApiProfileConfigMap`: per-profile API config shape
|
|
27
|
-
- `ApiProfileDefaultsMap`: defaults block within a profile
|
|
28
|
-
- `EndpointMap`: endpoint config shape
|
|
29
|
-
|
|
30
|
-
## Example: Typing an API Config
|
|
31
|
-
|
|
32
|
-
```python
|
|
33
|
-
from etlplus.config import ApiConfigMap
|
|
34
|
-
|
|
35
|
-
api_cfg: ApiConfigMap = {
|
|
36
|
-
"base_url": "https://example.test",
|
|
37
|
-
"headers": {"Authorization": "Bearer token"},
|
|
38
|
-
"endpoints": {
|
|
39
|
-
"users": {
|
|
40
|
-
"path": "/users",
|
|
41
|
-
"method": "GET",
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## See Also
|
|
48
|
-
|
|
49
|
-
- Top-level CLI and library usage in the main [README](../../README.md)
|
|
50
|
-
- Config type definitions in [types.py](types.py)
|
etlplus/config/__init__.py
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
:mod:`etlplus.config` package.
|
|
3
|
-
|
|
4
|
-
Configuration models and helpers for ETLPlus.
|
|
5
|
-
|
|
6
|
-
This package defines models for data sources/targets ("connectors"), APIs,
|
|
7
|
-
pagination/rate limits, pipeline orchestration, and related utilities. The
|
|
8
|
-
parsers are permissive (accepting ``Mapping[str, Any]``) and normalize to
|
|
9
|
-
concrete types without raising on unknown/optional fields.
|
|
10
|
-
|
|
11
|
-
Notes
|
|
12
|
-
-----
|
|
13
|
-
- The models use ``@dataclass(slots=True)`` and avoid mutating inputs.
|
|
14
|
-
- TypedDicts are editor/type-checking hints and are not enforced at runtime.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
from __future__ import annotations
|
|
18
|
-
|
|
19
|
-
from .types import ApiConfigMap
|
|
20
|
-
from .types import ApiProfileConfigMap
|
|
21
|
-
from .types import ApiProfileDefaultsMap
|
|
22
|
-
from .types import EndpointMap
|
|
23
|
-
|
|
24
|
-
# SECTION: EXPORTS ========================================================== #
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
__all__ = [
|
|
28
|
-
# Typed Dicts
|
|
29
|
-
'ApiConfigMap',
|
|
30
|
-
'ApiProfileConfigMap',
|
|
31
|
-
'ApiProfileDefaultsMap',
|
|
32
|
-
'EndpointMap',
|
|
33
|
-
]
|