etlplus 0.10.4__tar.gz → 0.10.5__tar.gz

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 (151) hide show
  1. {etlplus-0.10.4/etlplus.egg-info → etlplus-0.10.5}/PKG-INFO +1 -1
  2. {etlplus-0.10.4 → etlplus-0.10.5/etlplus.egg-info}/PKG-INFO +1 -1
  3. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus.egg-info/SOURCES.txt +1 -0
  4. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/cli/conftest.py +105 -4
  5. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/cli/test_u_cli_handlers.py +90 -370
  6. etlplus-0.10.5/tests/unit/cli/test_u_cli_io.py +326 -0
  7. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/cli/test_u_cli_main.py +59 -25
  8. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/cli/test_u_cli_state.py +45 -41
  9. {etlplus-0.10.4 → etlplus-0.10.5}/.coveragerc +0 -0
  10. {etlplus-0.10.4 → etlplus-0.10.5}/.editorconfig +0 -0
  11. {etlplus-0.10.4 → etlplus-0.10.5}/.gitattributes +0 -0
  12. {etlplus-0.10.4 → etlplus-0.10.5}/.github/actions/python-bootstrap/action.yml +0 -0
  13. {etlplus-0.10.4 → etlplus-0.10.5}/.github/workflows/ci.yml +0 -0
  14. {etlplus-0.10.4 → etlplus-0.10.5}/.gitignore +0 -0
  15. {etlplus-0.10.4 → etlplus-0.10.5}/.pre-commit-config.yaml +0 -0
  16. {etlplus-0.10.4 → etlplus-0.10.5}/.ruff.toml +0 -0
  17. {etlplus-0.10.4 → etlplus-0.10.5}/CODE_OF_CONDUCT.md +0 -0
  18. {etlplus-0.10.4 → etlplus-0.10.5}/CONTRIBUTING.md +0 -0
  19. {etlplus-0.10.4 → etlplus-0.10.5}/DEMO.md +0 -0
  20. {etlplus-0.10.4 → etlplus-0.10.5}/LICENSE +0 -0
  21. {etlplus-0.10.4 → etlplus-0.10.5}/MANIFEST.in +0 -0
  22. {etlplus-0.10.4 → etlplus-0.10.5}/Makefile +0 -0
  23. {etlplus-0.10.4 → etlplus-0.10.5}/README.md +0 -0
  24. {etlplus-0.10.4 → etlplus-0.10.5}/REFERENCES.md +0 -0
  25. {etlplus-0.10.4 → etlplus-0.10.5}/docs/README.md +0 -0
  26. {etlplus-0.10.4 → etlplus-0.10.5}/docs/pipeline-guide.md +0 -0
  27. {etlplus-0.10.4 → etlplus-0.10.5}/docs/snippets/installation_version.md +0 -0
  28. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/__init__.py +0 -0
  29. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/__main__.py +0 -0
  30. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/__version__.py +0 -0
  31. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/README.md +0 -0
  32. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/__init__.py +0 -0
  33. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/auth.py +0 -0
  34. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/config.py +0 -0
  35. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/endpoint_client.py +0 -0
  36. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/errors.py +0 -0
  37. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/pagination/__init__.py +0 -0
  38. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/pagination/client.py +0 -0
  39. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/pagination/config.py +0 -0
  40. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/pagination/paginator.py +0 -0
  41. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/rate_limiting/__init__.py +0 -0
  42. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/rate_limiting/config.py +0 -0
  43. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/rate_limiting/rate_limiter.py +0 -0
  44. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/request_manager.py +0 -0
  45. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/retry_manager.py +0 -0
  46. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/transport.py +0 -0
  47. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/api/types.py +0 -0
  48. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/__init__.py +0 -0
  49. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/commands.py +0 -0
  50. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/constants.py +0 -0
  51. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/handlers.py +0 -0
  52. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/io.py +0 -0
  53. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/main.py +0 -0
  54. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/options.py +0 -0
  55. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/state.py +0 -0
  56. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/cli/types.py +0 -0
  57. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/__init__.py +0 -0
  58. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/connector.py +0 -0
  59. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/jobs.py +0 -0
  60. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/pipeline.py +0 -0
  61. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/profile.py +0 -0
  62. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/types.py +0 -0
  63. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/config/utils.py +0 -0
  64. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/__init__.py +0 -0
  65. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/ddl.py +0 -0
  66. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/engine.py +0 -0
  67. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/orm.py +0 -0
  68. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/schema.py +0 -0
  69. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/database/types.py +0 -0
  70. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/enums.py +0 -0
  71. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/extract.py +0 -0
  72. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/file.py +0 -0
  73. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/load.py +0 -0
  74. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/mixins.py +0 -0
  75. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/py.typed +0 -0
  76. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/run.py +0 -0
  77. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/run_helpers.py +0 -0
  78. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/templates/__init__.py +0 -0
  79. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/templates/ddl.sql.j2 +0 -0
  80. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/templates/view.sql.j2 +0 -0
  81. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/transform.py +0 -0
  82. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/types.py +0 -0
  83. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/utils.py +0 -0
  84. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/validate.py +0 -0
  85. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/validation/__init__.py +0 -0
  86. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus/validation/utils.py +0 -0
  87. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus.egg-info/dependency_links.txt +0 -0
  88. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus.egg-info/entry_points.txt +0 -0
  89. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus.egg-info/requires.txt +0 -0
  90. {etlplus-0.10.4 → etlplus-0.10.5}/etlplus.egg-info/top_level.txt +0 -0
  91. {etlplus-0.10.4 → etlplus-0.10.5}/examples/README.md +0 -0
  92. {etlplus-0.10.4 → etlplus-0.10.5}/examples/configs/ddl_spec.yml +0 -0
  93. {etlplus-0.10.4 → etlplus-0.10.5}/examples/configs/pipeline.yml +0 -0
  94. {etlplus-0.10.4 → etlplus-0.10.5}/examples/data/sample.csv +0 -0
  95. {etlplus-0.10.4 → etlplus-0.10.5}/examples/data/sample.json +0 -0
  96. {etlplus-0.10.4 → etlplus-0.10.5}/examples/data/sample.xml +0 -0
  97. {etlplus-0.10.4 → etlplus-0.10.5}/examples/data/sample.xsd +0 -0
  98. {etlplus-0.10.4 → etlplus-0.10.5}/examples/data/sample.yaml +0 -0
  99. {etlplus-0.10.4 → etlplus-0.10.5}/examples/quickstart_python.py +0 -0
  100. {etlplus-0.10.4 → etlplus-0.10.5}/pyproject.toml +0 -0
  101. {etlplus-0.10.4 → etlplus-0.10.5}/pytest.ini +0 -0
  102. {etlplus-0.10.4 → etlplus-0.10.5}/setup.cfg +0 -0
  103. {etlplus-0.10.4 → etlplus-0.10.5}/setup.py +0 -0
  104. {etlplus-0.10.4 → etlplus-0.10.5}/tests/__init__.py +0 -0
  105. {etlplus-0.10.4 → etlplus-0.10.5}/tests/conftest.py +0 -0
  106. {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/conftest.py +0 -0
  107. {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_cli.py +0 -0
  108. {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_examples_data_parity.py +0 -0
  109. {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_pagination_strategy.py +0 -0
  110. {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_pipeline_smoke.py +0 -0
  111. {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_pipeline_yaml_load.py +0 -0
  112. {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_run.py +0 -0
  113. {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_run_profile_pagination_defaults.py +0 -0
  114. {etlplus-0.10.4 → etlplus-0.10.5}/tests/integration/test_i_run_profile_rate_limit_defaults.py +0 -0
  115. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/conftest.py +0 -0
  116. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_auth.py +0 -0
  117. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_config.py +0 -0
  118. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_endpoint_client.py +0 -0
  119. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_mocks.py +0 -0
  120. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_pagination_client.py +0 -0
  121. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_pagination_config.py +0 -0
  122. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_paginator.py +0 -0
  123. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_rate_limit_config.py +0 -0
  124. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_rate_limiter.py +0 -0
  125. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_request_manager.py +0 -0
  126. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_retry_manager.py +0 -0
  127. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_transport.py +0 -0
  128. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/api/test_u_types.py +0 -0
  129. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/config/test_u_config_utils.py +0 -0
  130. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/config/test_u_connector.py +0 -0
  131. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/config/test_u_jobs.py +0 -0
  132. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/config/test_u_pipeline.py +0 -0
  133. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/conftest.py +0 -0
  134. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/database/test_u_database_ddl.py +0 -0
  135. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/database/test_u_database_engine.py +0 -0
  136. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/database/test_u_database_orm.py +0 -0
  137. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/database/test_u_database_schema.py +0 -0
  138. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_enums.py +0 -0
  139. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_extract.py +0 -0
  140. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_file.py +0 -0
  141. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_load.py +0 -0
  142. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_main.py +0 -0
  143. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_mixins.py +0 -0
  144. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_run.py +0 -0
  145. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_run_helpers.py +0 -0
  146. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_transform.py +0 -0
  147. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_utils.py +0 -0
  148. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_validate.py +0 -0
  149. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/test_u_version.py +0 -0
  150. {etlplus-0.10.4 → etlplus-0.10.5}/tests/unit/validation/test_u_validation_utils.py +0 -0
  151. {etlplus-0.10.4 → etlplus-0.10.5}/tools/update_demo_snippets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: etlplus
3
- Version: 0.10.4
3
+ Version: 0.10.5
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: etlplus
3
- Version: 0.10.4
3
+ Version: 0.10.5
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
@@ -134,6 +134,7 @@ tests/unit/api/test_u_transport.py
134
134
  tests/unit/api/test_u_types.py
135
135
  tests/unit/cli/conftest.py
136
136
  tests/unit/cli/test_u_cli_handlers.py
137
+ tests/unit/cli/test_u_cli_io.py
137
138
  tests/unit/cli/test_u_cli_main.py
138
139
  tests/unit/cli/test_u_cli_state.py
139
140
  tests/unit/config/test_u_config_utils.py
@@ -14,6 +14,7 @@ from __future__ import annotations
14
14
  import json
15
15
  import types
16
16
  from collections.abc import Callable
17
+ from collections.abc import Mapping
17
18
  from dataclasses import dataclass
18
19
  from dataclasses import field
19
20
  from pathlib import Path
@@ -33,6 +34,84 @@ from etlplus.config import PipelineConfig
33
34
 
34
35
  CSV_TEXT: Final[str] = 'a,b\n1,2\n3,4\n'
35
36
 
37
+ type CaptureHandler = Callable[[object, str], dict[str, object]]
38
+ type CaptureIo = dict[str, list[tuple[tuple[object, ...], dict[str, object]]]]
39
+ type InvokeCli = Callable[..., Result]
40
+ type StubCommand = Callable[[Callable[..., object]], None]
41
+
42
+
43
+ def assert_emit_json(
44
+ calls: CaptureIo,
45
+ payload: object,
46
+ *,
47
+ pretty: bool,
48
+ ) -> None:
49
+ """
50
+ Assert that :func:`emit_json` was called once with expected payload.
51
+
52
+ Parameters
53
+ ----------
54
+ calls : CaptureIo
55
+ Captured IO calls from the CLI fixtures.
56
+ payload : object
57
+ Expected JSON payload.
58
+ pretty : bool
59
+ Expected pretty-print flag.
60
+ """
61
+ assert calls['emit_json'] == [((payload,), {'pretty': pretty})]
62
+
63
+
64
+ def assert_emit_or_write(
65
+ calls: CaptureIo,
66
+ payload: object,
67
+ target: object,
68
+ *,
69
+ pretty: bool,
70
+ ) -> dict[str, object]:
71
+ """
72
+ Assert that :func:`emit_or_write` was called once and return kwargs.
73
+
74
+ Parameters
75
+ ----------
76
+ calls : CaptureIo
77
+ Captured IO calls from the CLI fixtures.
78
+ payload : object
79
+ Expected payload argument.
80
+ target : object
81
+ Expected output path argument.
82
+ pretty : bool
83
+ Expected pretty-print flag.
84
+
85
+ Returns
86
+ -------
87
+ dict[str, object]
88
+ Captured keyword arguments for the call.
89
+ """
90
+ assert len(calls['emit_or_write']) == 1
91
+ args, kwargs = calls['emit_or_write'][0]
92
+ assert args[0] == payload
93
+ assert args[1] == target
94
+ assert kwargs['pretty'] is pretty
95
+ return kwargs
96
+
97
+
98
+ def assert_mapping_contains(
99
+ actual: Mapping[str, object],
100
+ expected: Mapping[str, object],
101
+ ) -> None:
102
+ """
103
+ Assert that ``actual`` contains the ``expected`` key/value pairs.
104
+
105
+ Parameters
106
+ ----------
107
+ actual : Mapping[str, object]
108
+ Mapping returned by the handler capture fixture.
109
+ expected : Mapping[str, object]
110
+ Expected key/value pairs that must be present in ``actual``.
111
+ """
112
+ for key, value in expected.items():
113
+ assert actual[key] == value
114
+
36
115
 
37
116
  @dataclass(frozen=True, slots=True)
38
117
  class DummyCfg:
@@ -60,8 +139,20 @@ class DummyCfg:
60
139
  @pytest.fixture(name='capture_handler')
61
140
  def capture_handler_fixture(
62
141
  monkeypatch: pytest.MonkeyPatch,
63
- ) -> Callable[[object, str], dict[str, object]]:
64
- """Patch a handler function and capture the kwargs it receives."""
142
+ ) -> CaptureHandler:
143
+ """
144
+ Patch a handler function and capture the kwargs it receives.
145
+
146
+ Parameters
147
+ ----------
148
+ monkeypatch : pytest.MonkeyPatch
149
+ Pytest monkeypatch fixture.
150
+
151
+ Returns
152
+ -------
153
+ CaptureHandler
154
+ Callable that records handler keyword arguments.
155
+ """
65
156
 
66
157
  def _capture(module: object, attr: str) -> dict[str, object]:
67
158
  calls: dict[str, object] = {}
@@ -77,14 +168,24 @@ def capture_handler_fixture(
77
168
 
78
169
 
79
170
  @pytest.fixture(name='capture_io')
80
- def capture_io_fixture(monkeypatch: pytest.MonkeyPatch):
171
+ def capture_io_fixture(monkeypatch: pytest.MonkeyPatch) -> CaptureIo:
81
172
  """
82
173
  Patch handler functions and capture CLI output.
83
174
  Returns a dict with lists of call args for each function.
175
+
176
+ Parameters
177
+ ----------
178
+ monkeypatch : pytest.MonkeyPatch
179
+ Pytest monkeypatch fixture.
180
+
181
+ Returns
182
+ -------
183
+ CaptureIo
184
+ Mapping of captured IO call arguments by function name.
84
185
  """
85
186
  import etlplus.cli.io as _io
86
187
 
87
- calls: dict[str, list] = {
188
+ calls: CaptureIo = {
88
189
  'emit_or_write': [],
89
190
  'emit_json': [],
90
191
  'print_json': [],