etlplus 0.14.3__py3-none-any.whl → 0.16.0__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.
Files changed (122) hide show
  1. etlplus/README.md +4 -4
  2. etlplus/api/README.md +33 -2
  3. etlplus/api/auth.py +1 -1
  4. etlplus/api/config.py +5 -10
  5. etlplus/api/endpoint_client.py +4 -4
  6. etlplus/api/pagination/config.py +1 -1
  7. etlplus/api/pagination/paginator.py +6 -7
  8. etlplus/api/rate_limiting/config.py +4 -4
  9. etlplus/api/rate_limiting/rate_limiter.py +1 -1
  10. etlplus/api/retry_manager.py +2 -2
  11. etlplus/api/transport.py +1 -1
  12. etlplus/api/types.py +99 -0
  13. etlplus/api/utils.py +6 -2
  14. etlplus/cli/README.md +2 -2
  15. etlplus/cli/commands.py +75 -42
  16. etlplus/cli/constants.py +1 -1
  17. etlplus/cli/handlers.py +33 -15
  18. etlplus/cli/io.py +2 -2
  19. etlplus/cli/main.py +2 -2
  20. etlplus/cli/state.py +4 -7
  21. etlplus/connector/__init__.py +43 -0
  22. etlplus/connector/api.py +161 -0
  23. etlplus/connector/connector.py +26 -0
  24. etlplus/connector/core.py +132 -0
  25. etlplus/connector/database.py +122 -0
  26. etlplus/connector/enums.py +52 -0
  27. etlplus/connector/file.py +120 -0
  28. etlplus/connector/types.py +40 -0
  29. etlplus/connector/utils.py +122 -0
  30. etlplus/database/README.md +2 -2
  31. etlplus/database/ddl.py +2 -2
  32. etlplus/database/engine.py +19 -3
  33. etlplus/database/orm.py +2 -0
  34. etlplus/enums.py +1 -33
  35. etlplus/file/README.md +2 -2
  36. etlplus/file/_imports.py +1 -0
  37. etlplus/file/_io.py +52 -4
  38. etlplus/file/accdb.py +3 -2
  39. etlplus/file/arrow.py +3 -2
  40. etlplus/file/avro.py +3 -2
  41. etlplus/file/bson.py +3 -2
  42. etlplus/file/cbor.py +3 -2
  43. etlplus/file/cfg.py +3 -2
  44. etlplus/file/conf.py +3 -2
  45. etlplus/file/core.py +11 -8
  46. etlplus/file/csv.py +3 -2
  47. etlplus/file/dat.py +3 -2
  48. etlplus/file/dta.py +3 -2
  49. etlplus/file/duckdb.py +3 -2
  50. etlplus/file/enums.py +1 -1
  51. etlplus/file/feather.py +3 -2
  52. etlplus/file/fwf.py +3 -2
  53. etlplus/file/gz.py +3 -2
  54. etlplus/file/hbs.py +3 -2
  55. etlplus/file/hdf5.py +3 -2
  56. etlplus/file/ini.py +3 -2
  57. etlplus/file/ion.py +3 -2
  58. etlplus/file/jinja2.py +3 -2
  59. etlplus/file/json.py +5 -16
  60. etlplus/file/log.py +3 -2
  61. etlplus/file/mat.py +3 -2
  62. etlplus/file/mdb.py +3 -2
  63. etlplus/file/msgpack.py +3 -2
  64. etlplus/file/mustache.py +3 -2
  65. etlplus/file/nc.py +3 -2
  66. etlplus/file/ndjson.py +3 -2
  67. etlplus/file/numbers.py +3 -2
  68. etlplus/file/ods.py +3 -2
  69. etlplus/file/orc.py +3 -2
  70. etlplus/file/parquet.py +3 -2
  71. etlplus/file/pb.py +3 -2
  72. etlplus/file/pbf.py +3 -2
  73. etlplus/file/properties.py +3 -2
  74. etlplus/file/proto.py +3 -2
  75. etlplus/file/psv.py +3 -2
  76. etlplus/file/rda.py +3 -2
  77. etlplus/file/rds.py +3 -2
  78. etlplus/file/sas7bdat.py +3 -2
  79. etlplus/file/sav.py +3 -2
  80. etlplus/file/sqlite.py +3 -2
  81. etlplus/file/stub.py +1 -0
  82. etlplus/file/sylk.py +3 -2
  83. etlplus/file/tab.py +3 -2
  84. etlplus/file/toml.py +3 -2
  85. etlplus/file/tsv.py +3 -2
  86. etlplus/file/txt.py +4 -3
  87. etlplus/file/vm.py +3 -2
  88. etlplus/file/wks.py +3 -2
  89. etlplus/file/xls.py +3 -2
  90. etlplus/file/xlsm.py +3 -2
  91. etlplus/file/xlsx.py +3 -2
  92. etlplus/file/xml.py +9 -3
  93. etlplus/file/xpt.py +3 -2
  94. etlplus/file/yaml.py +5 -16
  95. etlplus/file/zip.py +3 -2
  96. etlplus/file/zsav.py +3 -2
  97. etlplus/ops/extract.py +13 -1
  98. etlplus/ops/load.py +15 -2
  99. etlplus/ops/run.py +18 -13
  100. etlplus/ops/transform.py +2 -2
  101. etlplus/ops/utils.py +6 -35
  102. etlplus/ops/validate.py +3 -3
  103. etlplus/templates/README.md +2 -2
  104. etlplus/types.py +3 -2
  105. etlplus/utils.py +163 -29
  106. etlplus/{config → workflow}/README.md +6 -6
  107. etlplus/workflow/__init__.py +32 -0
  108. etlplus/{dag.py → workflow/dag.py} +6 -4
  109. etlplus/{config → workflow}/jobs.py +101 -38
  110. etlplus/{config → workflow}/pipeline.py +59 -51
  111. etlplus/{config → workflow}/profile.py +8 -5
  112. {etlplus-0.14.3.dist-info → etlplus-0.16.0.dist-info}/METADATA +4 -4
  113. etlplus-0.16.0.dist-info/RECORD +141 -0
  114. {etlplus-0.14.3.dist-info → etlplus-0.16.0.dist-info}/WHEEL +1 -1
  115. etlplus/config/__init__.py +0 -56
  116. etlplus/config/connector.py +0 -372
  117. etlplus/config/types.py +0 -204
  118. etlplus/config/utils.py +0 -120
  119. etlplus-0.14.3.dist-info/RECORD +0 -135
  120. {etlplus-0.14.3.dist-info → etlplus-0.16.0.dist-info}/entry_points.txt +0 -0
  121. {etlplus-0.14.3.dist-info → etlplus-0.16.0.dist-info}/licenses/LICENSE +0 -0
  122. {etlplus-0.14.3.dist-info → etlplus-0.16.0.dist-info}/top_level.txt +0 -0
etlplus/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # etlplus package
1
+ # `etlplus` Package
2
2
 
3
3
  The `etlplus` package provides a unified Python API and CLI for ETL operations: extraction,
4
4
  validation, transformation, and loading of data from files, APIs, and databases.
@@ -13,12 +13,12 @@ Back to project overview: see the top-level [README](../README.md).
13
13
 
14
14
  - [etlplus.api](api/README.md): Lightweight HTTP client and paginated REST helpers
15
15
  - [etlplus.file](file/README.md): Unified file format support and helpers
16
- - [etlplus.config](config/README.md): Configuration helpers for connectors, pipelines, jobs, and
17
- profiles
18
- - [etlplus.cli](cli/README.md): Command-line interface for ETLPlus workflows
16
+ - [etlplus.cli](cli/README.md): Command-line interface definitions for `etlplus`
19
17
  - [etlplus.database](database/README.md): Database engine, schema, and ORM helpers
20
18
  - [etlplus.templates](templates/README.md): SQL and DDL template helpers
21
19
  - [etlplus.validation](validation/README.md): Data validation utilities and helpers
20
+ - [etlplus.workflow](etlplus/workflow/README.md): Helpers for data connectors, pipelines, jobs, and
21
+ profiles
22
22
 
23
23
  ## Quickstart
24
24
 
etlplus/api/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # etlplus.api subpackage
1
+ # `etlplus.api` Subpackage
2
2
 
3
3
  Documentation for the `etlplus.api` subpackage: a lightweight HTTP client and helpers for paginated
4
4
  REST endpoints.
@@ -12,7 +12,7 @@ REST endpoints.
12
12
 
13
13
  Back to project overview: see the top-level [README](../../README.md).
14
14
 
15
- - [etlplus.api subpackage](#etlplusapi-subpackage)
15
+ - [`etlplus.api` Subpackage](#etlplusapi-subpackage)
16
16
  - [Installation](#installation)
17
17
  - [Quickstart](#quickstart)
18
18
  - [Overriding Rate Limits Per Call](#overriding-rate-limits-per-call)
@@ -22,6 +22,7 @@ Back to project overview: see the top-level [README](../../README.md).
22
22
  - [Authentication](#authentication)
23
23
  - [Errors and Rate Limiting](#errors-and-rate-limiting)
24
24
  - [Types and Transport](#types-and-transport)
25
+ - [Config Schemas](#config-schemas)
25
26
  - [Supporting Modules](#supporting-modules)
26
27
  - [Minimal Contract](#minimal-contract)
27
28
  - [See also](#see-also)
@@ -225,6 +226,36 @@ providers can fall back to their own defaults. If you already possess a static t
225
226
  `etlplus/api/request_manager.py` wraps `requests` sessions plus retry orchestration. Advanced
226
227
  users may consult those modules to adapt behavior.
227
228
 
229
+ ## Config Schemas
230
+
231
+ `etlplus.api.types` defines TypedDict-based configuration shapes for API profiles and endpoints.
232
+ Runtime parsing remains permissive in `etlplus.api.config`, but these types improve IDE
233
+ autocomplete and static analysis.
234
+
235
+ Exported types:
236
+
237
+ - `ApiConfigMap`: top-level API config shape
238
+ - `ApiProfileConfigMap`: per-profile API config shape
239
+ - `ApiProfileDefaultsMap`: defaults block within a profile
240
+ - `EndpointMap`: endpoint config shape
241
+
242
+ Example:
243
+
244
+ ```python
245
+ from etlplus.api import ApiConfigMap
246
+
247
+ api_cfg: ApiConfigMap = {
248
+ "base_url": "https://example.test",
249
+ "headers": {"Authorization": "Bearer token"},
250
+ "endpoints": {
251
+ "users": {
252
+ "path": "/users",
253
+ "method": "GET",
254
+ },
255
+ },
256
+ }
257
+ ```
258
+
228
259
  ## Supporting Modules
229
260
 
230
261
  - `etlplus.api.types` collects friendly aliases such as `Headers`, `Params`, `Url`, and
etlplus/api/auth.py CHANGED
@@ -136,7 +136,7 @@ def _truncate(
136
136
  limit: int = MAX_LOG_BODY,
137
137
  ) -> str:
138
138
  """
139
- Return ``text`` shortened to ``limit`` characters for logging.
139
+ Return *text* shortened to *limit* characters for logging.
140
140
 
141
141
  Parameters
142
142
  ----------
etlplus/api/config.py CHANGED
@@ -3,11 +3,6 @@
3
3
 
4
4
  Configuration dataclasses for REST API services, profiles, and endpoints.
5
5
 
6
- These models used to live under :mod:`etlplus.config`, but they belong in the
7
- API layer because they compose runtime types such as
8
- :class:`etlplus.api.EndpointClient`, :class:`etlplus.api.PaginationConfig`, and
9
- :class:`etlplus.api.RateLimitConfig`.
10
-
11
6
  Notes
12
7
  -----
13
8
  - TypedDict references remain editor hints only; :meth:`from_obj` accepts
@@ -41,9 +36,9 @@ from .pagination import PaginationConfig
41
36
  from .rate_limiting import RateLimitConfig
42
37
 
43
38
  if TYPE_CHECKING:
44
- from ..config.types import ApiConfigMap
45
- from ..config.types import ApiProfileConfigMap
46
- from ..config.types import EndpointMap
39
+ from .types import ApiConfigMap
40
+ from .types import ApiProfileConfigMap
41
+ from .types import EndpointMap
47
42
 
48
43
 
49
44
  # SECTION: EXPORTS ========================================================== #
@@ -73,7 +68,7 @@ def _effective_service_defaults(
73
68
  fallback_headers: dict[str, str],
74
69
  ) -> tuple[str, dict[str, str]]:
75
70
  """
76
- Return ``(base_url, headers)`` using ``profiles`` when present.
71
+ Return ``(base_url, headers)`` using *profiles* when present.
77
72
 
78
73
  Parameters
79
74
  ----------
@@ -92,7 +87,7 @@ def _effective_service_defaults(
92
87
  Raises
93
88
  ------
94
89
  TypeError
95
- If no profiles are defined and ``fallback_base`` is not a string.
90
+ If no profiles are defined and *fallback_base* is not a string.
96
91
  """
97
92
  if profiles:
98
93
  name = 'default' if 'default' in profiles else next(iter(profiles))
@@ -759,8 +759,8 @@ class EndpointClient:
759
759
  Raises
760
760
  ------
761
761
  KeyError
762
- If ``endpoint_key`` is unknown or a required placeholder in the
763
- path has no corresponding entry in ``path_parameters``.
762
+ If *endpoint_key* is unknown or a required placeholder in the path
763
+ has no corresponding entry in *path_parameters*.
764
764
  ValueError
765
765
  If the path template is invalid.
766
766
 
@@ -836,7 +836,7 @@ class EndpointClient:
836
836
  """
837
837
  Sleep for the specified seconds if positive.
838
838
 
839
- The optional ``sleeper`` is useful for tests (e.g., pass
839
+ The optional *sleeper* is useful for tests (e.g., pass
840
840
  ``lambda s: None``). Defaults to using time.sleep when not provided.
841
841
 
842
842
  Parameters
@@ -870,7 +870,7 @@ class EndpointClient:
870
870
  rate_limit : RateLimitConfigMap | None
871
871
  Client-wide rate limit configuration.
872
872
  overrides : RateLimitOverrides, optional
873
- Per-call overrides that take precedence over ``rate_limit``.
873
+ Per-call overrides that take precedence over *rate_limit*.
874
874
 
875
875
  Returns
876
876
  -------
@@ -398,7 +398,7 @@ class PaginationConfig(BoundsWarningsMixin):
398
398
  Returns
399
399
  -------
400
400
  Self | None
401
- Parsed pagination configuration, or ``None`` if ``obj`` isn't a
401
+ Parsed pagination configuration, or ``None`` if *obj* isn't a
402
402
  mapping.
403
403
 
404
404
  Notes
@@ -66,14 +66,14 @@ def _resolve_path(
66
66
  path: str | None,
67
67
  ) -> Any:
68
68
  """
69
- Resolve dotted ``path`` within ``obj`` or return ``_MISSING``.
69
+ Resolve dotted *path* within *obj* or return ``_MISSING``.
70
70
 
71
71
  Parameters
72
72
  ----------
73
73
  obj : Any
74
74
  JSON payload from an API response.
75
75
  path : str | None
76
- Dotted path to the target value within ``obj``.
76
+ Dotted path to the target value within *obj*.
77
77
 
78
78
  Returns
79
79
  -------
@@ -665,7 +665,7 @@ class Paginator:
665
665
  records_path : str | None
666
666
  Optional dotted path to the records within the payload.
667
667
  fallback_path : str | None
668
- Secondary dotted path consulted when ``records_path`` resolves to
668
+ Secondary dotted path consulted when *records_path* resolves to
669
669
  ``None`` or an empty list.
670
670
 
671
671
  Returns
@@ -675,9 +675,8 @@ class Paginator:
675
675
 
676
676
  Notes
677
677
  -----
678
- Supports dotted path extraction via ``records_path`` and handles
679
- lists, mappings, and scalars by coercing non-dict items into
680
- ``{"value": x}``.
678
+ Supports dotted path extraction via *records_path* and handles lists,
679
+ mappings, and scalars by coercing non-dict items into ``{"value": x}``.
681
680
  """
682
681
  resolver = partial(_resolve_path, x)
683
682
  data = resolver(records_path)
@@ -729,7 +728,7 @@ class Paginator:
729
728
  Returns
730
729
  -------
731
730
  PaginationType | None
732
- Detected pagination type, or ``default`` if not found.
731
+ Detected pagination type, or *default* if not found.
733
732
  """
734
733
  if not config:
735
734
  return default
@@ -84,14 +84,14 @@ def _merge_rate_limit(
84
84
  overrides: RateLimitOverrides = None,
85
85
  ) -> dict[str, Any]:
86
86
  """
87
- Merge ``rate_limit`` and ``overrides`` honoring override precedence.
87
+ Merge *rate_limit* and *overrides* honoring override precedence.
88
88
 
89
89
  Parameters
90
90
  ----------
91
91
  rate_limit : StrAnyMap | None
92
92
  Base rate-limit configuration.
93
93
  overrides : RateLimitOverrides, optional
94
- Override configuration with precedence over ``rate_limit``.
94
+ Override configuration with precedence over *rate_limit*.
95
95
 
96
96
  Returns
97
97
  -------
@@ -274,7 +274,7 @@ class RateLimitConfig(BoundsWarningsMixin):
274
274
  rate_limit : StrAnyMap | RateLimitConfig | None, optional
275
275
  Base rate-limit configuration to normalize.
276
276
  overrides : RateLimitOverrides, optional
277
- Override values that take precedence over ``rate_limit``.
277
+ Override values that take precedence over *rate_limit*.
278
278
 
279
279
  Returns
280
280
  -------
@@ -330,7 +330,7 @@ class RateLimitConfig(BoundsWarningsMixin):
330
330
  Returns
331
331
  -------
332
332
  Self | None
333
- Parsed instance, or ``None`` if ``obj`` isn't a mapping.
333
+ Parsed instance, or ``None`` if *obj* isn't a mapping.
334
334
  """
335
335
  if obj is None:
336
336
  return None
@@ -235,7 +235,7 @@ class RateLimiter:
235
235
  Base rate-limit configuration. May contain ``"sleep_seconds"`` or
236
236
  ``"max_per_sec"``.
237
237
  overrides : RateLimitOverrides, optional
238
- Optional overrides with the same keys as ``rate_limit``.
238
+ Optional overrides with the same keys as *rate_limit*.
239
239
 
240
240
  Returns
241
241
  -------
@@ -278,7 +278,7 @@ class RetryManager:
278
278
  **kwargs: Any,
279
279
  ) -> JSONData:
280
280
  """
281
- Execute ``func`` with exponential-backoff retries.
281
+ Execute *func* with exponential-backoff retries.
282
282
 
283
283
  Parameters
284
284
  ----------
@@ -287,7 +287,7 @@ class RetryManager:
287
287
  url : str
288
288
  URL for the API request.
289
289
  **kwargs : Any
290
- Additional keyword arguments to pass to ``func``
290
+ Additional keyword arguments to pass to *func*
291
291
 
292
292
  Returns
293
293
  -------
etlplus/api/transport.py CHANGED
@@ -309,7 +309,7 @@ def build_session_with_adapters(
309
309
  adapters_cfg: Sequence[HTTPAdapterMountConfig],
310
310
  ) -> requests.Session:
311
311
  """
312
- Mount adapters described by ``adapters_cfg`` onto a new session.
312
+ Mount adapters described by *adapters_cfg* onto a new session.
313
313
 
314
314
  Ignores invalid adapter configurations so that a usable session is always
315
315
  returned.
etlplus/api/types.py CHANGED
@@ -20,9 +20,11 @@ Examples
20
20
  from __future__ import annotations
21
21
 
22
22
  from collections.abc import Callable
23
+ from collections.abc import Mapping
23
24
  from dataclasses import dataclass
24
25
  from typing import Any
25
26
  from typing import Self
27
+ from typing import TypedDict
26
28
  from typing import cast
27
29
 
28
30
  from ..types import JSONData
@@ -40,6 +42,11 @@ __all__ = [
40
42
  'Headers',
41
43
  'Params',
42
44
  'Url',
45
+ # Typed Dicts
46
+ 'ApiConfigMap',
47
+ 'ApiProfileConfigMap',
48
+ 'ApiProfileDefaultsMap',
49
+ 'EndpointMap',
43
50
  ]
44
51
 
45
52
 
@@ -49,6 +56,98 @@ __all__ = [
49
56
  _UNSET = object()
50
57
 
51
58
 
59
+ # SECTION: TYPED DICTS ====================================================== #
60
+
61
+
62
+ class ApiConfigMap(TypedDict, total=False):
63
+ """
64
+ Top-level API config shape parsed by
65
+ :meth:`etlplus.api.config.ApiConfig.from_obj`.
66
+
67
+ Either provide a :attr:`base_url` with optional :attr:`headers` and
68
+ :attr:`endpoints`, or provide :attr:`profiles` with at least one profile
69
+ having a :attr:`base_url`.
70
+
71
+ See Also
72
+ --------
73
+ - :class:`etlplus.api.config.ApiConfig`
74
+ """
75
+
76
+ base_url: str
77
+ headers: StrAnyMap
78
+ endpoints: Mapping[str, EndpointMap | str]
79
+ profiles: Mapping[str, ApiProfileConfigMap]
80
+
81
+
82
+ class ApiProfileConfigMap(TypedDict, total=False):
83
+ """
84
+ Shape accepted for a profile entry under
85
+ :meth:`etlplus.api.config.ApiConfig.from_obj`.
86
+
87
+ Notes
88
+ -----
89
+ - :attr:`base_url` is required at runtime when :attr:`profiles` key/value
90
+ pairs are provided.
91
+ - :meth:`etlplus.api.config.ApiProfileConfig.from_obj` parses this mapping.
92
+
93
+ See Also
94
+ --------
95
+ - :class:`etlplus.api.config.ApiProfileConfig`
96
+ """
97
+
98
+ base_url: str
99
+ headers: StrAnyMap
100
+ base_path: str
101
+ auth: StrAnyMap
102
+ defaults: ApiProfileDefaultsMap
103
+
104
+
105
+ class ApiProfileDefaultsMap(TypedDict, total=False):
106
+ """
107
+ Defaults block available under a profile (all keys optional).
108
+
109
+ Notes
110
+ -----
111
+ - Runtime expects header values to be ``str``; typing remains permissive.
112
+ - :meth:`etlplus.api.config.ApiProfileConfig.from_obj` consumes this block.
113
+ - :meth:`etlplus.api.pagination.PaginationConfig.from_obj` parses
114
+ :attr:`pagination`.
115
+ - :meth:`etlplus.api.rate_limiting.RateLimitConfig.from_obj` parses
116
+ :attr:`rate_limit`.
117
+
118
+ See Also
119
+ --------
120
+ - :class:`etlplus.api.config.ApiProfileConfig`
121
+ - :class:`etlplus.api.pagination.PaginationConfig`
122
+ - :class:`etlplus.api.rate_limiting.RateLimitConfig`
123
+ """
124
+
125
+ headers: StrAnyMap
126
+ pagination: StrAnyMap # PaginationConfigMap | StrAnyMap
127
+ rate_limit: StrAnyMap # RateLimitConfigMap | StrAnyMap
128
+
129
+
130
+ class EndpointMap(TypedDict, total=False):
131
+ """
132
+ Shape accepted by :meth:`etlplus.api.config.EndpointConfig.from_obj`.
133
+
134
+ One of :attr:`path` or :attr:`url` should be provided.
135
+
136
+ See Also
137
+ --------
138
+ - :class:`etlplus.api.config.EndpointConfig`
139
+ """
140
+
141
+ path: str
142
+ url: str
143
+ method: str
144
+ path_params: StrAnyMap
145
+ query_params: StrAnyMap
146
+ body: Any
147
+ pagination: StrAnyMap # PaginationConfigMap | StrAnyMap
148
+ rate_limit: StrAnyMap # RateLimitConfigMap | StrAnyMap
149
+
150
+
52
151
  # SECTION: DATA CLASSES ===================================================== #
53
152
 
54
153
 
etlplus/api/utils.py CHANGED
@@ -172,7 +172,7 @@ def _coalesce(
172
172
  *args: Any,
173
173
  ) -> Any | None:
174
174
  """
175
- Return the first non-``None`` value from ``args``.
175
+ Return the first non-``None`` value from *args*.
176
176
 
177
177
  Parameters
178
178
  ----------
@@ -892,4 +892,8 @@ def resolve_request(
892
892
  'Session object must supply a callable '
893
893
  f'"{http_method.value}" method',
894
894
  )
895
- return request_callable, request_timeout, http_method
895
+ typed_request_callable = cast(
896
+ Callable[..., requests.Response],
897
+ request_callable,
898
+ )
899
+ return typed_request_callable, request_timeout, http_method
etlplus/cli/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # etlplus.cli subpackage
1
+ # `etlplus.cli` Subpackage
2
2
 
3
3
  Documentation for the `etlplus.cli` subpackage: command-line interface for ETLPlus workflows.
4
4
 
@@ -9,7 +9,7 @@ Documentation for the `etlplus.cli` subpackage: command-line interface for ETLPl
9
9
 
10
10
  Back to project overview: see the top-level [README](../../README.md).
11
11
 
12
- - [etlplus.cli subpackage](#etlpluscli-subpackage)
12
+ - [`etlplus.cli` Subpackage](#etlpluscli-subpackage)
13
13
  - [Available Commands](#available-commands)
14
14
  - [Command Options](#command-options)
15
15
  - [Example: Running a Pipeline](#example-running-a-pipeline)
etlplus/cli/commands.py CHANGED
@@ -61,6 +61,24 @@ __all__ = ['app']
61
61
 
62
62
  # SECTION: TYPE ALIASES ==================================================== #
63
63
 
64
+
65
+ JobOption = Annotated[
66
+ str | None,
67
+ typer.Option(
68
+ '-j',
69
+ '--job',
70
+ help='Name of the job to run',
71
+ ),
72
+ ]
73
+
74
+ JobsOption = Annotated[
75
+ bool,
76
+ typer.Option(
77
+ '--jobs',
78
+ help='List available job names and exit',
79
+ ),
80
+ ]
81
+
64
82
  OperationsOption = Annotated[
65
83
  str,
66
84
  typer.Option(
@@ -89,6 +107,23 @@ PipelineConfigOption = Annotated[
89
107
  ),
90
108
  ]
91
109
 
110
+ PipelineOption = Annotated[
111
+ str | None,
112
+ typer.Option(
113
+ '-p',
114
+ '--pipeline',
115
+ help='Name of the pipeline to run',
116
+ ),
117
+ ]
118
+
119
+ PipelinesOption = Annotated[
120
+ bool,
121
+ typer.Option(
122
+ '--pipelines',
123
+ help='List ETL pipelines',
124
+ ),
125
+ ]
126
+
92
127
  RenderConfigOption = Annotated[
93
128
  str | None,
94
129
  typer.Option(
@@ -193,6 +228,22 @@ SourceTypeOption = Annotated[
193
228
  ),
194
229
  ]
195
230
 
231
+ SourcesOption = Annotated[
232
+ bool,
233
+ typer.Option(
234
+ '--sources',
235
+ help='List data sources',
236
+ ),
237
+ ]
238
+
239
+ SummaryOption = Annotated[
240
+ bool,
241
+ typer.Option(
242
+ '--summary',
243
+ help='Show pipeline summary (name, version, sources, targets, jobs)',
244
+ ),
245
+ ]
246
+
196
247
  TargetArg = Annotated[
197
248
  str,
198
249
  typer.Argument(
@@ -227,6 +278,22 @@ TargetTypeOption = Annotated[
227
278
  ),
228
279
  ]
229
280
 
281
+ TargetsOption = Annotated[
282
+ bool,
283
+ typer.Option(
284
+ '--targets',
285
+ help='List data targets',
286
+ ),
287
+ ]
288
+
289
+ TransformsOption = Annotated[
290
+ bool,
291
+ typer.Option(
292
+ '--transforms',
293
+ help='List data transforms',
294
+ ),
295
+ ]
296
+
230
297
 
231
298
  # SECTION: INTERNAL FUNCTIONS =============================================== #
232
299
 
@@ -341,36 +408,12 @@ def _root(
341
408
  def check_cmd(
342
409
  ctx: typer.Context,
343
410
  config: PipelineConfigOption,
344
- jobs: bool = typer.Option(
345
- False,
346
- '--jobs',
347
- help='List available job names and exit',
348
- ),
349
- pipelines: bool = typer.Option(
350
- False,
351
- '--pipelines',
352
- help='List ETL pipelines',
353
- ),
354
- sources: bool = typer.Option(
355
- False,
356
- '--sources',
357
- help='List data sources',
358
- ),
359
- summary: bool = typer.Option(
360
- False,
361
- '--summary',
362
- help='Show pipeline summary (name, version, sources, targets, jobs)',
363
- ),
364
- targets: bool = typer.Option(
365
- False,
366
- '--targets',
367
- help='List data targets',
368
- ),
369
- transforms: bool = typer.Option(
370
- False,
371
- '--transforms',
372
- help='List data transforms',
373
- ),
411
+ jobs: JobsOption = False,
412
+ pipelines: PipelinesOption = False,
413
+ sources: SourcesOption = False,
414
+ summary: SummaryOption = False,
415
+ targets: TargetsOption = False,
416
+ transforms: TransformsOption = False,
374
417
  ) -> int:
375
418
  """
376
419
  Inspect a pipeline configuration.
@@ -683,18 +726,8 @@ def render_cmd(
683
726
  def run_cmd(
684
727
  ctx: typer.Context,
685
728
  config: PipelineConfigOption,
686
- job: str | None = typer.Option(
687
- None,
688
- '-j',
689
- '--job',
690
- help='Name of the job to run',
691
- ),
692
- pipeline: str | None = typer.Option(
693
- None,
694
- '-p',
695
- '--pipeline',
696
- help='Name of the pipeline to run',
697
- ),
729
+ job: JobOption = None,
730
+ pipeline: PipelineOption = None,
698
731
  ) -> int:
699
732
  """
700
733
  Execute an ETL job or pipeline from a YAML configuration.
etlplus/cli/constants.py CHANGED
@@ -8,7 +8,7 @@ from __future__ import annotations
8
8
 
9
9
  from typing import Final
10
10
 
11
- from ..enums import DataConnectorType
11
+ from ..connector import DataConnectorType
12
12
  from ..file import FileFormat
13
13
 
14
14
  # SECTION: EXPORTS ========================================================== #