etlplus 0.8.2__py3-none-any.whl → 0.8.4__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/cli/state.py CHANGED
@@ -7,7 +7,6 @@ Shared state and helper utilities for the ``etlplus`` command-line interface
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
- import argparse
11
10
  import sys
12
11
  from collections.abc import Collection
13
12
  from dataclasses import dataclass
@@ -25,15 +24,12 @@ __all__ = [
25
24
  'CliState',
26
25
  # Functions
27
26
  'ensure_state',
28
- 'format_namespace_kwargs',
29
27
  'infer_resource_type',
30
28
  'infer_resource_type_or_exit',
31
29
  'infer_resource_type_soft',
32
30
  'log_inferred_resource',
33
- 'ns',
34
31
  'optional_choice',
35
32
  'resolve_resource_type',
36
- 'stateful_namespace',
37
33
  'validate_choice',
38
34
  ]
39
35
 
@@ -97,32 +93,6 @@ def ensure_state(
97
93
  return ctx.obj
98
94
 
99
95
 
100
- def format_namespace_kwargs(
101
- *,
102
- format_value: str | None,
103
- default: str,
104
- ) -> dict[str, object]:
105
- """
106
- Return common namespace kwargs for format handling.
107
-
108
- Parameters
109
- ----------
110
- format_value : str | None
111
- The explicit format value from the CLI, or ``None`` if not provided.
112
- default : str
113
- The default format to use if none is provided.
114
-
115
- Returns
116
- -------
117
- dict[str, object]
118
- The namespace keyword arguments for format handling.
119
- """
120
- return {
121
- 'format': (format_value or default),
122
- '_format_explicit': (format_value is not None),
123
- }
124
-
125
-
126
96
  def infer_resource_type(
127
97
  value: str,
128
98
  ) -> str:
@@ -236,7 +206,7 @@ def log_inferred_resource(
236
206
  resource_type : str | None
237
207
  The inferred resource type, or ``None`` if inference failed.
238
208
  """
239
- if not state.verbose or resource_type is None:
209
+ if state.quiet or not state.verbose or resource_type is None:
240
210
  return
241
211
  print(
242
212
  f'Inferred {role}_type={resource_type} for {role}={value}',
@@ -244,25 +214,6 @@ def log_inferred_resource(
244
214
  )
245
215
 
246
216
 
247
- def ns(
248
- **kwargs: object,
249
- ) -> argparse.Namespace:
250
- """
251
- Build an :class:`argparse.Namespace` for the legacy handlers.
252
-
253
- Parameters
254
- ----------
255
- **kwargs : object
256
- Keyword arguments to include in the namespace.
257
-
258
- Returns
259
- -------
260
- argparse.Namespace
261
- The constructed namespace.
262
- """
263
- return argparse.Namespace(**kwargs)
264
-
265
-
266
217
  def optional_choice(
267
218
  value: str | None,
268
219
  choices: Collection[str],
@@ -342,40 +293,8 @@ def resolve_resource_type(
342
293
  return validate_choice(candidate, DATA_CONNECTORS, label=label)
343
294
 
344
295
 
345
- def stateful_namespace(
346
- state: CliState,
347
- *,
348
- command: str,
349
- **kwargs: object,
350
- ) -> argparse.Namespace:
351
- """
352
- Attach CLI state toggles to a handler namespace.
353
-
354
- Parameters
355
- ----------
356
- state : CliState
357
- The current CLI state.
358
- command : str
359
- The command name.
360
- **kwargs : object
361
- Additional keyword arguments for the namespace.
362
-
363
- Returns
364
- -------
365
- argparse.Namespace
366
- The constructed namespace with state toggles.
367
- """
368
- return ns(
369
- command=command,
370
- pretty=state.pretty,
371
- quiet=state.quiet,
372
- verbose=state.verbose,
373
- **kwargs,
374
- )
375
-
376
-
377
296
  def validate_choice(
378
- value: str,
297
+ value: str | object,
379
298
  choices: Collection[str],
380
299
  *,
381
300
  label: str,
@@ -402,8 +321,13 @@ def validate_choice(
402
321
  typer.BadParameter
403
322
  If the input value is not in the set of valid choices.
404
323
  """
405
- v = (value or '').strip()
406
- if v in choices:
324
+ v = str(value or '').strip().lower()
325
+ normalized_choices = {c.lower() for c in choices}
326
+ if v in normalized_choices:
327
+ # Preserve original casing from choices when possible for messages
328
+ for choice in choices:
329
+ if choice.lower() == v:
330
+ return choice
407
331
  return v
408
332
  allowed = ', '.join(sorted(choices))
409
333
  raise typer.BadParameter(
etlplus/utils.py CHANGED
@@ -6,7 +6,6 @@ Small shared helpers used across modules.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- import argparse
10
9
  import json
11
10
  from collections.abc import Callable
12
11
  from collections.abc import Mapping
@@ -22,7 +21,6 @@ from .types import StrAnyMap
22
21
  __all__ = [
23
22
  # Data utilities
24
23
  'count_records',
25
- 'json_type',
26
24
  'print_json',
27
25
  # Mapping utilities
28
26
  'cast_str_dict',
@@ -119,35 +117,6 @@ def count_records(
119
117
  return len(data) if isinstance(data, list) else 1
120
118
 
121
119
 
122
- def json_type(
123
- option: str,
124
- ) -> Any:
125
- """
126
- Argparse ``type=`` hook that parses a JSON string.
127
-
128
- Parameters
129
- ----------
130
- option : str
131
- Raw CLI string to parse as JSON.
132
-
133
- Returns
134
- -------
135
- Any
136
- Parsed JSON value.
137
-
138
- Raises
139
- ------
140
- argparse.ArgumentTypeError
141
- If the input cannot be parsed as JSON.
142
- """
143
- try:
144
- return json.loads(option)
145
- except json.JSONDecodeError as e: # pragma: no cover - argparse path
146
- raise argparse.ArgumentTypeError(
147
- f'Invalid JSON: {e.msg} (pos {e.pos})',
148
- ) from e
149
-
150
-
151
120
  def maybe_mapping(
152
121
  value: Any,
153
122
  ) -> StrAnyMap | None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: etlplus
3
- Version: 0.8.2
3
+ Version: 0.8.4
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
@@ -64,7 +64,7 @@ package and command-line interface for data extraction, validation, transformati
64
64
  - [Quickstart](#quickstart)
65
65
  - [Usage](#usage)
66
66
  - [Command Line Interface](#command-line-interface)
67
- - [Inspect Pipelines](#inspect-pipelines)
67
+ - [Check Pipelines](#check-pipelines)
68
68
  - [Render SQL DDL](#render-sql-ddl)
69
69
  - [Extract Data](#extract-data)
70
70
  - [Validate Data](#validate-data)
@@ -182,6 +182,9 @@ etlplus --help
182
182
  etlplus --version
183
183
  ```
184
184
 
185
+ The CLI is implemented with Typer (Click-based). There is no argparse compatibility layer, so rely
186
+ on the documented commands/flags and run `etlplus <command> --help` for current options.
187
+
185
188
  #### Check Pipelines
186
189
 
187
190
  Use `etlplus check` to explore pipeline YAML definitions without running them. The command can print
@@ -11,9 +11,9 @@ etlplus/run.py,sha256=X4kp5FQlIWVf1_d9oSrchKau7BFDCE1Zkscvu7WPaWw,12340
11
11
  etlplus/run_helpers.py,sha256=bj6MkaeFxjl3CeKG1HoXKx5DwAlXNERVW-GX-z1P_qQ,24373
12
12
  etlplus/transform.py,sha256=uAUVDDHYCgx7GpVez9IK3OAZM-CnCuMa9iox3vwGGJA,25296
13
13
  etlplus/types.py,sha256=1hsDlnF6r76zAwaUYay-i6pCM-Y0IU5nP7Crj8PLCQ4,6157
14
- etlplus/utils.py,sha256=_fn8b-SAdxiw28VX-Ugr8sZUPZI9mEkWKAGExlgxhJA,13993
14
+ etlplus/utils.py,sha256=GrRH6N9u_U-4gs6PYpO0_Y2RwsyD3Ju9cup0b0byUbk,13367
15
15
  etlplus/validate.py,sha256=7rJoEI_SIILdPpoBqqh2UJqg9oeReDz34mYSlc3t7Qg,12989
16
- etlplus/api/README.md,sha256=UkK5PiZWXbbnMNP0MaPa56S88PjSqOwhMNCyswOhvKc,7329
16
+ etlplus/api/README.md,sha256=ZiyjxLz0LfFCzeYKXwtH8yY1OJ4hXCju7t2ICroFoU8,7215
17
17
  etlplus/api/__init__.py,sha256=P2JUYFy6Ep4t6xnsBiCBfQCkQLHYYhA-yXPXCobS8Y0,4295
18
18
  etlplus/api/auth.py,sha256=GOO5on-LoMS1GXTAhtK9rFcfpjbBcNeA6NE5UZwIq0g,12158
19
19
  etlplus/api/config.py,sha256=wRpOaZ31sPReVzEMme0jKl_37nqgraESwuYSNxP_xDo,17397
@@ -31,13 +31,13 @@ etlplus/api/rate_limiting/__init__.py,sha256=ZySB1dZettEDnWvI1EHf_TZ9L08M_kKsNR-
31
31
  etlplus/api/rate_limiting/config.py,sha256=2b4wIynblN-1EyMqI4aXa71SljzSjXYh5N1Nngr3jOg,9406
32
32
  etlplus/api/rate_limiting/rate_limiter.py,sha256=Uxozqd_Ej5Lsj-M-mLT2WexChgWh7x35_YP10yqYPQA,7159
33
33
  etlplus/cli/__init__.py,sha256=J97-Rv931IL1_b4AXnB7Fbbd7HKnHBpx18NQfC_kE6c,299
34
- etlplus/cli/commands.py,sha256=laIfpxnnJM1XZvxQxaH1IheZbIsELruC1V3BeT2l8y0,16299
34
+ etlplus/cli/commands.py,sha256=-lO8XX2IeTvdfZLeI_UpT2kH4qZuNpfujArw3IKS2vY,22585
35
35
  etlplus/cli/constants.py,sha256=NJ6IvNyYEI8IdB7eMcc-vteQiiIwqid5YvmUk-5DRHY,1839
36
- etlplus/cli/handlers.py,sha256=F8ZtXWdtMvhDYYDUjZ3JkGFJh2xfWsE2PKX5ZRhP0RI,11310
37
- etlplus/cli/io.py,sha256=wHoKfgl-VT15cfiVeW3uPz_U7tPQ1ag7EQkRZtxPd38,7987
38
- etlplus/cli/main.py,sha256=iD4zSgJwsfzhqlBCNxD7a7y5ZutqB9upxCnGtNaZ_B8,14006
39
- etlplus/cli/options.py,sha256=44rgksvi0c9Evt_QzITnErVEuyGTaUulkQYZZgCke7k,3060
40
- etlplus/cli/state.py,sha256=ymiGJbnEO766BOYaqm_-qZaqBwdKYnGRuttrNVhDms0,9439
36
+ etlplus/cli/handlers.py,sha256=WBzJZz7ESU4Hljog_ON4g9PLIW6U6io_F9op7daksKY,17781
37
+ etlplus/cli/io.py,sha256=hkmbDh0HFrZhDjfZbma0Lp4tc0wrTwdD9Snqa-wNAd4,7308
38
+ etlplus/cli/main.py,sha256=_ipwLgIzkf8ks8cbu2KkVBbY3gcdaqDR98WUBdwviiw,5191
39
+ etlplus/cli/options.py,sha256=dswqAdnQ4fRJGI3xEFUyMifp0ry3rm2cCaPyEqI_99c,1199
40
+ etlplus/cli/state.py,sha256=20uKdYddYvAlR-HUQJAV-ThyXMZaPiSk9cN-tevRIpw,7991
41
41
  etlplus/cli/types.py,sha256=tclhKVJXDqHzlTQBYKARfqMgDOcuBJ-Zej2pvFy96WM,652
42
42
  etlplus/config/__init__.py,sha256=VZWzOg7d2YR9NT6UwKTv44yf2FRUMjTHynkm1Dl5Qzo,1486
43
43
  etlplus/config/connector.py,sha256=0-TIwevHbKRHVmucvyGpPd-3tB1dKHB-dj0yJ6kq5eY,9809
@@ -57,9 +57,9 @@ etlplus/templates/ddl.sql.j2,sha256=s8fMWvcb4eaJVXkifuib1aQPljtZ8buuyB_uA-ZdU3Q,
57
57
  etlplus/templates/view.sql.j2,sha256=Iy8DHfhq5yyvrUKDxqp_aHIEXY4Tm6j4wT7YDEFWAhk,2180
58
58
  etlplus/validation/__init__.py,sha256=Pe5Xg1_EA4uiNZGYu5WTF3j7odjmyxnAJ8rcioaplSQ,1254
59
59
  etlplus/validation/utils.py,sha256=Mtqg449VIke0ziy_wd2r6yrwJzQkA1iulZC87FzXMjo,10201
60
- etlplus-0.8.2.dist-info/licenses/LICENSE,sha256=MuNO63i6kWmgnV2pbP2SLqP54mk1BGmu7CmbtxMmT-U,1069
61
- etlplus-0.8.2.dist-info/METADATA,sha256=djlodCP_KPtdG2OKttP5QcpxJHCy3-0enqnIXKIZZEY,19328
62
- etlplus-0.8.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
63
- etlplus-0.8.2.dist-info/entry_points.txt,sha256=6w-2-jzuPa55spzK34h-UKh2JTEShh38adFRONNP9QE,45
64
- etlplus-0.8.2.dist-info/top_level.txt,sha256=aWWF-udn_sLGuHTM6W6MLh99ArS9ROkUWO8Mi8y1_2U,8
65
- etlplus-0.8.2.dist-info/RECORD,,
60
+ etlplus-0.8.4.dist-info/licenses/LICENSE,sha256=MuNO63i6kWmgnV2pbP2SLqP54mk1BGmu7CmbtxMmT-U,1069
61
+ etlplus-0.8.4.dist-info/METADATA,sha256=awIkLa9r6rXsxSPOBHRSFqfVgOjMmjvGr-D57zCkWz0,19513
62
+ etlplus-0.8.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
63
+ etlplus-0.8.4.dist-info/entry_points.txt,sha256=6w-2-jzuPa55spzK34h-UKh2JTEShh38adFRONNP9QE,45
64
+ etlplus-0.8.4.dist-info/top_level.txt,sha256=aWWF-udn_sLGuHTM6W6MLh99ArS9ROkUWO8Mi8y1_2U,8
65
+ etlplus-0.8.4.dist-info/RECORD,,