etlplus 0.16.2__tar.gz → 0.16.3__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 (234) hide show
  1. {etlplus-0.16.2/etlplus.egg-info → etlplus-0.16.3}/PKG-INFO +1 -1
  2. etlplus-0.16.3/etlplus/enums.py +144 -0
  3. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/ops/__init__.py +1 -0
  4. {etlplus-0.16.2/etlplus → etlplus-0.16.3/etlplus/ops}/enums.py +5 -108
  5. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/ops/run.py +1 -1
  6. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/ops/transform.py +16 -16
  7. etlplus-0.16.3/etlplus/ops/types.py +147 -0
  8. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/types.py +0 -99
  9. {etlplus-0.16.2 → etlplus-0.16.3/etlplus.egg-info}/PKG-INFO +1 -1
  10. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus.egg-info/SOURCES.txt +4 -2
  11. {etlplus-0.16.2 → etlplus-0.16.3}/examples/README.md +1 -1
  12. etlplus-0.16.2/examples/quickstart_python.py → etlplus-0.16.3/examples/quickstart.py +22 -1
  13. etlplus-0.16.2/tests/unit/test_u_enums.py → etlplus-0.16.3/tests/unit/ops/test_u_ops_enums.py +8 -8
  14. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/ops/test_u_ops_transform.py +3 -3
  15. {etlplus-0.16.2 → etlplus-0.16.3}/.coveragerc +0 -0
  16. {etlplus-0.16.2 → etlplus-0.16.3}/.editorconfig +0 -0
  17. {etlplus-0.16.2 → etlplus-0.16.3}/.gitattributes +0 -0
  18. {etlplus-0.16.2 → etlplus-0.16.3}/.github/actions/python-bootstrap/action.yml +0 -0
  19. {etlplus-0.16.2 → etlplus-0.16.3}/.github/workflows/ci.yml +0 -0
  20. {etlplus-0.16.2 → etlplus-0.16.3}/.gitignore +0 -0
  21. {etlplus-0.16.2 → etlplus-0.16.3}/.pre-commit-config.yaml +0 -0
  22. {etlplus-0.16.2 → etlplus-0.16.3}/.ruff.toml +0 -0
  23. {etlplus-0.16.2 → etlplus-0.16.3}/CODE_OF_CONDUCT.md +0 -0
  24. {etlplus-0.16.2 → etlplus-0.16.3}/CONTRIBUTING.md +0 -0
  25. {etlplus-0.16.2 → etlplus-0.16.3}/DEMO.md +0 -0
  26. {etlplus-0.16.2 → etlplus-0.16.3}/LICENSE +0 -0
  27. {etlplus-0.16.2 → etlplus-0.16.3}/MANIFEST.in +0 -0
  28. {etlplus-0.16.2 → etlplus-0.16.3}/Makefile +0 -0
  29. {etlplus-0.16.2 → etlplus-0.16.3}/README.md +0 -0
  30. {etlplus-0.16.2 → etlplus-0.16.3}/REFERENCES.md +0 -0
  31. {etlplus-0.16.2 → etlplus-0.16.3}/SECURITY.md +0 -0
  32. {etlplus-0.16.2 → etlplus-0.16.3}/SUPPORT.md +0 -0
  33. {etlplus-0.16.2 → etlplus-0.16.3}/docs/README.md +0 -0
  34. {etlplus-0.16.2 → etlplus-0.16.3}/docs/pipeline-guide.md +0 -0
  35. {etlplus-0.16.2 → etlplus-0.16.3}/docs/snippets/installation_version.md +0 -0
  36. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/README.md +0 -0
  37. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/__init__.py +0 -0
  38. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/__main__.py +0 -0
  39. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/__version__.py +0 -0
  40. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/README.md +0 -0
  41. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/__init__.py +0 -0
  42. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/auth.py +0 -0
  43. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/config.py +0 -0
  44. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/endpoint_client.py +0 -0
  45. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/enums.py +0 -0
  46. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/errors.py +0 -0
  47. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/pagination/__init__.py +0 -0
  48. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/pagination/client.py +0 -0
  49. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/pagination/config.py +0 -0
  50. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/pagination/paginator.py +0 -0
  51. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/rate_limiting/__init__.py +0 -0
  52. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/rate_limiting/config.py +0 -0
  53. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/rate_limiting/rate_limiter.py +0 -0
  54. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/request_manager.py +0 -0
  55. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/retry_manager.py +0 -0
  56. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/transport.py +0 -0
  57. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/types.py +0 -0
  58. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/api/utils.py +0 -0
  59. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/cli/README.md +0 -0
  60. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/cli/__init__.py +0 -0
  61. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/cli/commands.py +0 -0
  62. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/cli/constants.py +0 -0
  63. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/cli/handlers.py +0 -0
  64. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/cli/io.py +0 -0
  65. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/cli/main.py +0 -0
  66. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/cli/options.py +0 -0
  67. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/cli/state.py +0 -0
  68. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/cli/types.py +0 -0
  69. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/connector/__init__.py +0 -0
  70. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/connector/api.py +0 -0
  71. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/connector/connector.py +0 -0
  72. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/connector/core.py +0 -0
  73. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/connector/database.py +0 -0
  74. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/connector/enums.py +0 -0
  75. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/connector/file.py +0 -0
  76. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/connector/types.py +0 -0
  77. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/connector/utils.py +0 -0
  78. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/database/README.md +0 -0
  79. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/database/__init__.py +0 -0
  80. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/database/ddl.py +0 -0
  81. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/database/engine.py +0 -0
  82. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/database/orm.py +0 -0
  83. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/database/schema.py +0 -0
  84. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/database/types.py +0 -0
  85. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/README.md +0 -0
  86. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/__init__.py +0 -0
  87. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/_imports.py +0 -0
  88. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/_io.py +0 -0
  89. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/accdb.py +0 -0
  90. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/arrow.py +0 -0
  91. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/avro.py +0 -0
  92. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/bson.py +0 -0
  93. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/cbor.py +0 -0
  94. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/cfg.py +0 -0
  95. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/conf.py +0 -0
  96. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/core.py +0 -0
  97. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/csv.py +0 -0
  98. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/dat.py +0 -0
  99. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/dta.py +0 -0
  100. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/duckdb.py +0 -0
  101. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/enums.py +0 -0
  102. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/feather.py +0 -0
  103. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/fwf.py +0 -0
  104. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/gz.py +0 -0
  105. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/hbs.py +0 -0
  106. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/hdf5.py +0 -0
  107. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/ini.py +0 -0
  108. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/ion.py +0 -0
  109. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/jinja2.py +0 -0
  110. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/json.py +0 -0
  111. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/log.py +0 -0
  112. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/mat.py +0 -0
  113. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/mdb.py +0 -0
  114. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/msgpack.py +0 -0
  115. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/mustache.py +0 -0
  116. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/nc.py +0 -0
  117. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/ndjson.py +0 -0
  118. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/numbers.py +0 -0
  119. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/ods.py +0 -0
  120. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/orc.py +0 -0
  121. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/parquet.py +0 -0
  122. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/pb.py +0 -0
  123. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/pbf.py +0 -0
  124. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/properties.py +0 -0
  125. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/proto.py +0 -0
  126. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/psv.py +0 -0
  127. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/rda.py +0 -0
  128. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/rds.py +0 -0
  129. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/sas7bdat.py +0 -0
  130. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/sav.py +0 -0
  131. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/sqlite.py +0 -0
  132. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/stub.py +0 -0
  133. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/sylk.py +0 -0
  134. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/tab.py +0 -0
  135. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/toml.py +0 -0
  136. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/tsv.py +0 -0
  137. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/txt.py +0 -0
  138. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/vm.py +0 -0
  139. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/wks.py +0 -0
  140. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/xls.py +0 -0
  141. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/xlsm.py +0 -0
  142. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/xlsx.py +0 -0
  143. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/xml.py +0 -0
  144. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/xpt.py +0 -0
  145. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/yaml.py +0 -0
  146. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/zip.py +0 -0
  147. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/file/zsav.py +0 -0
  148. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/mixins.py +0 -0
  149. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/ops/README.md +0 -0
  150. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/ops/extract.py +0 -0
  151. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/ops/load.py +0 -0
  152. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/ops/utils.py +0 -0
  153. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/ops/validate.py +0 -0
  154. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/py.typed +0 -0
  155. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/templates/README.md +0 -0
  156. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/templates/__init__.py +0 -0
  157. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/templates/ddl.sql.j2 +0 -0
  158. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/templates/view.sql.j2 +0 -0
  159. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/utils.py +0 -0
  160. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/workflow/README.md +0 -0
  161. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/workflow/__init__.py +0 -0
  162. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/workflow/dag.py +0 -0
  163. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/workflow/jobs.py +0 -0
  164. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/workflow/pipeline.py +0 -0
  165. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus/workflow/profile.py +0 -0
  166. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus.egg-info/dependency_links.txt +0 -0
  167. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus.egg-info/entry_points.txt +0 -0
  168. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus.egg-info/requires.txt +0 -0
  169. {etlplus-0.16.2 → etlplus-0.16.3}/etlplus.egg-info/top_level.txt +0 -0
  170. {etlplus-0.16.2 → etlplus-0.16.3}/examples/configs/ddl_spec.yml +0 -0
  171. {etlplus-0.16.2 → etlplus-0.16.3}/examples/configs/pipeline.yml +0 -0
  172. {etlplus-0.16.2 → etlplus-0.16.3}/examples/data/sample.csv +0 -0
  173. {etlplus-0.16.2 → etlplus-0.16.3}/examples/data/sample.json +0 -0
  174. {etlplus-0.16.2 → etlplus-0.16.3}/examples/data/sample.xml +0 -0
  175. {etlplus-0.16.2 → etlplus-0.16.3}/examples/data/sample.xsd +0 -0
  176. {etlplus-0.16.2 → etlplus-0.16.3}/examples/data/sample.yaml +0 -0
  177. {etlplus-0.16.2 → etlplus-0.16.3}/pyproject.toml +0 -0
  178. {etlplus-0.16.2 → etlplus-0.16.3}/pytest.ini +0 -0
  179. {etlplus-0.16.2 → etlplus-0.16.3}/setup.cfg +0 -0
  180. {etlplus-0.16.2 → etlplus-0.16.3}/setup.py +0 -0
  181. {etlplus-0.16.2 → etlplus-0.16.3}/tests/__init__.py +0 -0
  182. {etlplus-0.16.2 → etlplus-0.16.3}/tests/conftest.py +0 -0
  183. {etlplus-0.16.2 → etlplus-0.16.3}/tests/integration/conftest.py +0 -0
  184. {etlplus-0.16.2 → etlplus-0.16.3}/tests/integration/test_i_cli.py +0 -0
  185. {etlplus-0.16.2 → etlplus-0.16.3}/tests/integration/test_i_examples_data_parity.py +0 -0
  186. {etlplus-0.16.2 → etlplus-0.16.3}/tests/integration/test_i_pagination_strategy.py +0 -0
  187. {etlplus-0.16.2 → etlplus-0.16.3}/tests/integration/test_i_pipeline_smoke.py +0 -0
  188. {etlplus-0.16.2 → etlplus-0.16.3}/tests/integration/test_i_pipeline_yaml_load.py +0 -0
  189. {etlplus-0.16.2 → etlplus-0.16.3}/tests/integration/test_i_run.py +0 -0
  190. {etlplus-0.16.2 → etlplus-0.16.3}/tests/integration/test_i_run_profile_pagination_defaults.py +0 -0
  191. {etlplus-0.16.2 → etlplus-0.16.3}/tests/integration/test_i_run_profile_rate_limit_defaults.py +0 -0
  192. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/conftest.py +0 -0
  193. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_api_enums.py +0 -0
  194. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_api_utils.py +0 -0
  195. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_auth.py +0 -0
  196. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_config.py +0 -0
  197. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_endpoint_client.py +0 -0
  198. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_mocks.py +0 -0
  199. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_pagination_client.py +0 -0
  200. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_pagination_config.py +0 -0
  201. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_paginator.py +0 -0
  202. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_rate_limit_config.py +0 -0
  203. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_rate_limiter.py +0 -0
  204. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_request_manager.py +0 -0
  205. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_retry_manager.py +0 -0
  206. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_transport.py +0 -0
  207. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/api/test_u_types.py +0 -0
  208. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/cli/conftest.py +0 -0
  209. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/cli/test_u_cli_handlers.py +0 -0
  210. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/cli/test_u_cli_io.py +0 -0
  211. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/cli/test_u_cli_main.py +0 -0
  212. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/cli/test_u_cli_state.py +0 -0
  213. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/conftest.py +0 -0
  214. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/connector/test_u_connector_enums.py +0 -0
  215. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/connector/test_u_connector_utils.py +0 -0
  216. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/database/test_u_database_ddl.py +0 -0
  217. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/database/test_u_database_engine.py +0 -0
  218. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/database/test_u_database_orm.py +0 -0
  219. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/database/test_u_database_schema.py +0 -0
  220. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/file/test_u_file_core.py +0 -0
  221. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/file/test_u_file_enums.py +0 -0
  222. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/file/test_u_file_yaml.py +0 -0
  223. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/ops/test_u_ops_extract.py +0 -0
  224. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/ops/test_u_ops_load.py +0 -0
  225. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/ops/test_u_ops_run.py +0 -0
  226. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/ops/test_u_ops_utils.py +0 -0
  227. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/ops/test_u_ops_validate.py +0 -0
  228. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/test_u_main.py +0 -0
  229. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/test_u_mixins.py +0 -0
  230. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/test_u_utils.py +0 -0
  231. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/test_u_version.py +0 -0
  232. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/workflow/test_u_workflow_jobs.py +0 -0
  233. {etlplus-0.16.2 → etlplus-0.16.3}/tests/unit/workflow/test_u_workflow_pipeline.py +0 -0
  234. {etlplus-0.16.2 → etlplus-0.16.3}/tools/update_demo_snippets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: etlplus
3
- Version: 0.16.2
3
+ Version: 0.16.3
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
@@ -0,0 +1,144 @@
1
+ """
2
+ :mod:`etlplus.enums` module.
3
+
4
+ Shared enumeration base class.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import enum
10
+ from typing import Self
11
+
12
+ from .types import StrStrMap
13
+
14
+ # SECTION: EXPORTS ========================================================== #
15
+
16
+
17
+ __all__ = [
18
+ # Enums
19
+ 'CoercibleStrEnum',
20
+ ]
21
+
22
+
23
+ # SECTION: CLASSES ========================================================== #
24
+
25
+
26
+ class CoercibleStrEnum(enum.StrEnum):
27
+ """
28
+ StrEnum with ergonomic helpers.
29
+
30
+ Provides a DRY, class-level :meth:`coerce` that normalizes inputs and
31
+ produces consistent, informative error messages. Also exposes
32
+ :meth:`choices` for UI/validation and :meth:`try_coerce` for soft parsing.
33
+
34
+ Notes
35
+ -----
36
+ - Values are normalized via ``str(value).strip().casefold()``.
37
+ - If value matching fails, the raw string is tried as a member name.
38
+ - Error messages enumerate allowed values for easier debugging.
39
+ """
40
+
41
+ # -- Class Methods -- #
42
+
43
+ @classmethod
44
+ def aliases(cls) -> StrStrMap:
45
+ """
46
+ Return a mapping of common aliases for each enum member.
47
+
48
+ Subclasses may override this method to provide custom aliases.
49
+
50
+ Returns
51
+ -------
52
+ StrStrMap
53
+ A mapping of alias strings to their corresponding enum member
54
+ values or names.
55
+
56
+ Notes
57
+ -----
58
+ - Alias keys are normalized via ``str(key).strip().casefold()``.
59
+ - Alias values should be member values or member names.
60
+ """
61
+ return {}
62
+
63
+ @classmethod
64
+ def choices(cls) -> tuple[str, ...]:
65
+ """
66
+ Return the allowed string values for this enum.
67
+
68
+ Returns
69
+ -------
70
+ tuple[str, ...]
71
+ A tuple of allowed string values for this enum.
72
+ """
73
+ return tuple(member.value for member in cls)
74
+
75
+ @classmethod
76
+ def coerce(cls, value: Self | str | object) -> Self:
77
+ """
78
+ Convert an enum member or string-like input to a member of *cls*.
79
+
80
+ Parameters
81
+ ----------
82
+ value : Self | str | object
83
+ An existing enum member or a string-like value to normalize.
84
+
85
+ Returns
86
+ -------
87
+ Self
88
+ The corresponding enum member.
89
+
90
+ Raises
91
+ ------
92
+ ValueError
93
+ If the value cannot be coerced into a valid member.
94
+ """
95
+ if isinstance(value, cls):
96
+ return value
97
+ try:
98
+ raw = str(value).strip()
99
+ normalized = raw.casefold()
100
+ aliases = {
101
+ str(key).strip().casefold(): alias
102
+ for key, alias in cls.aliases().items()
103
+ }
104
+ resolved = aliases.get(normalized)
105
+ if resolved is None:
106
+ try:
107
+ return cls(normalized) # type: ignore[arg-type]
108
+ except (ValueError, TypeError):
109
+ return cls[raw] # type: ignore[index]
110
+ if isinstance(resolved, cls):
111
+ return resolved
112
+ try:
113
+ return cls(resolved) # type: ignore[arg-type]
114
+ except (ValueError, TypeError):
115
+ # Allow aliases to reference member names.
116
+ return cls[resolved] # type: ignore[index]
117
+ except (ValueError, TypeError, KeyError) as e:
118
+ allowed = ', '.join(cls.choices())
119
+ raise ValueError(
120
+ f'Invalid {cls.__name__} value: {value!r}. Allowed: {allowed}',
121
+ ) from e
122
+
123
+ @classmethod
124
+ def try_coerce(
125
+ cls,
126
+ value: Self | str | object,
127
+ ) -> Self | None:
128
+ """
129
+ Attempt to coerce a value into the enum; return ``None`` on failure.
130
+
131
+ Parameters
132
+ ----------
133
+ value : Self | str | object
134
+ An existing enum member or a string-like value to normalize.
135
+
136
+ Returns
137
+ -------
138
+ Self | None
139
+ The corresponding enum member, or ``None`` if coercion fails.
140
+ """
141
+ try:
142
+ return cls.coerce(value)
143
+ except (ValueError, TypeError, KeyError):
144
+ return None
@@ -52,6 +52,7 @@ from .validate import validate
52
52
 
53
53
 
54
54
  __all__ = [
55
+ # Functions
55
56
  'extract',
56
57
  'load',
57
58
  'run',
@@ -1,133 +1,30 @@
1
1
  """
2
- :mod:`etlplus.enums` module.
2
+ :mod:`etlplus.ops.enums` module.
3
3
 
4
- Shared enumeration types used across ETLPlus modules.
4
+ Operation-specific enums and helpers.
5
5
  """
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- import enum
10
9
  import operator as _op
11
10
  from statistics import fmean
12
- from typing import Self
13
11
 
12
+ from ..enums import CoercibleStrEnum
13
+ from ..types import StrStrMap
14
14
  from .types import AggregateFunc
15
15
  from .types import OperatorFunc
16
- from .types import StrStrMap
17
16
 
18
- # SECTION: EXPORTS ========================================================== #
17
+ # SECTION: EXPORTS ========================================================= #
19
18
 
20
19
 
21
20
  __all__ = [
22
21
  # Enums
23
22
  'AggregateName',
24
- 'CoercibleStrEnum',
25
23
  'OperatorName',
26
24
  'PipelineStep',
27
25
  ]
28
26
 
29
27
 
30
- # SECTION: CLASSES ========================================================== #
31
-
32
-
33
- class CoercibleStrEnum(enum.StrEnum):
34
- """
35
- StrEnum with ergonomic helpers.
36
-
37
- Provides a DRY, class-level :meth:`coerce` that normalizes inputs and
38
- produces consistent, informative error messages. Also exposes
39
- :meth:`choices` for UI/validation and :meth:`try_coerce` for soft parsing.
40
-
41
- Notes
42
- -----
43
- - Values are normalized via ``str(value).strip().casefold()``.
44
- - Error messages enumerate allowed values for easier debugging.
45
- """
46
-
47
- # -- Class Methods -- #
48
-
49
- @classmethod
50
- def aliases(cls) -> StrStrMap:
51
- """
52
- Return a mapping of common aliases for each enum member.
53
-
54
- Subclasses may override this method to provide custom aliases.
55
-
56
- Returns
57
- -------
58
- StrStrMap
59
- A mapping of alias names to their corresponding enum member names.
60
- """
61
- return {}
62
-
63
- @classmethod
64
- def choices(cls) -> tuple[str, ...]:
65
- """
66
- Return the allowed string values for this enum.
67
-
68
- Returns
69
- -------
70
- tuple[str, ...]
71
- A tuple of allowed string values for this enum.
72
- """
73
- return tuple(member.value for member in cls)
74
-
75
- @classmethod
76
- def coerce(cls, value: Self | str | object) -> Self:
77
- """
78
- Convert an enum member or string-like input to a member of *cls*.
79
-
80
- Parameters
81
- ----------
82
- value : Self | str | object
83
- An existing enum member or a text value to normalize.
84
-
85
- Returns
86
- -------
87
- Self
88
- The corresponding enum member.
89
-
90
- Raises
91
- ------
92
- ValueError
93
- If the value cannot be coerced into a valid member.
94
- """
95
- if isinstance(value, cls):
96
- return value
97
- try:
98
- normalized = str(value).strip().casefold()
99
- resolved = cls.aliases().get(normalized, normalized)
100
- return cls(resolved) # type: ignore[arg-type]
101
- except (ValueError, TypeError) as e:
102
- allowed = ', '.join(cls.choices())
103
- raise ValueError(
104
- f'Invalid {cls.__name__} value: {value!r}. Allowed: {allowed}',
105
- ) from e
106
-
107
- @classmethod
108
- def try_coerce(
109
- cls,
110
- value: object,
111
- ) -> Self | None:
112
- """
113
- Best-effort parse; return ``None`` on failure instead of raising.
114
-
115
- Parameters
116
- ----------
117
- value : object
118
- An existing enum member or a text value to normalize.
119
-
120
- Returns
121
- -------
122
- Self | None
123
- The corresponding enum member, or ``None`` if coercion fails.
124
- """
125
- try:
126
- return cls.coerce(value)
127
- except ValueError:
128
- return None
129
-
130
-
131
28
  # SECTION: ENUMS ============================================================ #
132
29
 
133
30
 
@@ -13,9 +13,9 @@ from typing import cast
13
13
  from ..api import HttpMethod
14
14
  from ..connector import DataConnectorType
15
15
  from ..file import FileFormat
16
+ from ..ops.types import PipelineConfig
16
17
  from ..types import JSONData
17
18
  from ..types import JSONDict
18
- from ..types import PipelineConfig
19
19
  from ..types import StrPath
20
20
  from ..utils import print_json
21
21
  from ..workflow import load_pipeline_config
@@ -44,28 +44,28 @@ from collections.abc import Sequence
44
44
  from typing import Any
45
45
  from typing import cast
46
46
 
47
- from ..enums import AggregateName
48
- from ..enums import OperatorName
49
- from ..enums import PipelineStep
50
- from ..types import AggregateFunc
51
- from ..types import AggregateSpec
52
- from ..types import FieldName
53
- from ..types import Fields
54
- from ..types import FilterSpec
47
+ from ..ops.types import PipelineConfig
55
48
  from ..types import JSONData
56
49
  from ..types import JSONDict
57
50
  from ..types import JSONList
58
- from ..types import MapSpec
59
- from ..types import OperatorFunc
60
- from ..types import PipelineConfig
61
- from ..types import PipelineStepName
62
- from ..types import SortKey
63
- from ..types import StepApplier
64
- from ..types import StepOrSteps
65
- from ..types import StepSpec
66
51
  from ..types import StrPath
67
52
  from ..utils import to_number
53
+ from .enums import AggregateName
54
+ from .enums import OperatorName
55
+ from .enums import PipelineStep
68
56
  from .load import load_data
57
+ from .types import AggregateFunc
58
+ from .types import AggregateSpec
59
+ from .types import FieldName
60
+ from .types import Fields
61
+ from .types import FilterSpec
62
+ from .types import MapSpec
63
+ from .types import OperatorFunc
64
+ from .types import PipelineStepName
65
+ from .types import SortKey
66
+ from .types import StepApplier
67
+ from .types import StepOrSteps
68
+ from .types import StepSpec
69
69
 
70
70
  # SECTION: EXPORTS ========================================================== #
71
71
 
@@ -0,0 +1,147 @@
1
+ """
2
+ :mod:`etlplus.ops.types` module.
3
+
4
+ Shared type aliases leveraged across :mod:`etlplus.ops` modules.
5
+
6
+ Notes
7
+ -----
8
+ - Centralizes ops-focused aliases (functions, specs, and pipeline helpers).
9
+ - Relies on Python 3.13 ``type`` statements for readability and IDE support.
10
+
11
+ Examples
12
+ --------
13
+ >>> from etlplus.ops.types import AggregateFunc, OperatorFunc
14
+ >>> def total(xs: list[float], _: int) -> float:
15
+ ... return sum(xs)
16
+ >>> agg: AggregateFunc = total
17
+ >>> op: OperatorFunc = lambda a, b: a == b
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from collections.abc import Callable
23
+ from collections.abc import Mapping
24
+ from collections.abc import Sequence
25
+ from typing import Any
26
+ from typing import Literal
27
+
28
+ from ..types import JSONList
29
+ from ..types import StrAnyMap
30
+ from ..types import StrSeqMap
31
+ from ..types import StrStrMap
32
+
33
+ # SECTION: EXPORTS ========================================================== #
34
+
35
+
36
+ __all__ = [
37
+ # Type Aliases (Functions)
38
+ 'AggregateFunc',
39
+ 'OperatorFunc',
40
+ # Type Aliases (Records & Fields)
41
+ 'FieldName',
42
+ 'Fields',
43
+ # Type Aliases (Transform Specs)
44
+ 'AggregateSpec',
45
+ 'FilterSpec',
46
+ 'MapSpec',
47
+ 'SelectSpec',
48
+ 'SortSpec',
49
+ # Type Aliases (Pipelines)
50
+ 'StepOrSteps',
51
+ 'StepSeq',
52
+ 'StepSpec',
53
+ 'PipelineConfig',
54
+ 'PipelineStepName',
55
+ # Type Aliases (Helpers)
56
+ 'StepApplier',
57
+ 'SortKey',
58
+ ]
59
+
60
+
61
+ # SECTION: TYPE ALIASES ===================================================== #
62
+
63
+
64
+ # -- Functions -- #
65
+
66
+
67
+ # TODO: Consider redefining to use `functools.reduce` signature.
68
+ # TODO: Consider adding `**kwargs` to support richer aggregation functions.
69
+ # TODO: Consider constraining first argument to `Sequence[float]`.
70
+ # TODO: Consider constraining return type to `float | int | None`.
71
+ # Callable reducing numeric collections into a summary value.
72
+ type AggregateFunc = Callable[[list[float], int], Any]
73
+
74
+ # Binary predicate consumed by filter operations.
75
+ type OperatorFunc = Callable[[Any, Any], bool]
76
+
77
+ # -- Records & Fields -- #
78
+
79
+ # Individual field identifier referenced inside specs.
80
+ type FieldName = str
81
+
82
+ # Ordered list of :data:`FieldName` entries preserving projection order.
83
+ type Fields = list[FieldName]
84
+
85
+ # -- Transform Specs -- #
86
+
87
+ # Filtering spec expecting ``field``, ``op``, and ``value`` keys.
88
+ type FilterSpec = StrAnyMap
89
+
90
+ # Field renaming instructions mapping old keys to new ones.
91
+ type MapSpec = StrStrMap
92
+
93
+ # Projection spec as a field list or mapping with metadata.
94
+ #
95
+ # Examples
96
+ # --------
97
+ # >>> from etlplus.ops.types import SelectSpec
98
+ # >>> spec1: SelectSpec = ['a','b']
99
+ # >>> spec2: SelectSpec = {'fields': [...]}
100
+ type SelectSpec = Fields | StrSeqMap
101
+
102
+ # Sort directive expressed as a field string or mapping with flags.
103
+ #
104
+ # Examples
105
+ # --------
106
+ # >>> from etlplus.ops.types import SortSpec
107
+ # >>> spec1: SortSpec = 'field'
108
+ # >>> spec2: SortSpec = {'field': 'x', 'reverse': True}
109
+ type SortSpec = str | StrAnyMap
110
+
111
+ # Aggregate instruction covering ``field``, ``func``, and optional alias.
112
+ #
113
+ # Supported functions: ``avg``, ``count``, ``max``, ``min``, and ``sum``.
114
+ # Examples
115
+ # --------
116
+ # >>> from etlplus.ops.types import AggregateSpec
117
+ # >>> spec: AggregateSpec = \
118
+ # ... {'field': 'x', 'func': 'sum' | 'avg' | ..., 'alias'?: '...'}
119
+ type AggregateSpec = StrAnyMap
120
+
121
+ # -- Pipelines-- #
122
+
123
+ # Unified pipeline step spec consumed by :mod:`etlplus.ops.transform`.
124
+ type StepSpec = AggregateSpec | FilterSpec | MapSpec | SelectSpec | SortSpec
125
+
126
+ # Collections of steps
127
+
128
+ # Ordered collection of :data:`StepSpec` entries.
129
+ type StepSeq = Sequence[StepSpec]
130
+
131
+ # Accepts either a single :data:`StepSpec` or a sequence of them.
132
+ type StepOrSteps = StepSpec | StepSeq
133
+
134
+ # Canonical literal names for supported transform stages.
135
+ type PipelineStepName = Literal['aggregate', 'filter', 'map', 'select', 'sort']
136
+
137
+ # Mapping from step name to its associated specification payload.
138
+ # TODO: Consider replacing with etlplus.workflow.types.PipelineConfig.
139
+ type PipelineConfig = Mapping[PipelineStepName, StepOrSteps]
140
+
141
+ # -- Helpers -- #
142
+
143
+ # Callable that applies step configuration to a batch of records.
144
+ type StepApplier = Callable[[JSONList, Any], JSONList]
145
+
146
+ # Tuple combining stable sort index and computed sort value.
147
+ type SortKey = tuple[int, Any]
@@ -53,30 +53,10 @@ __all__ = [
53
53
  'JSONRecords',
54
54
  # Type Aliases (File System)
55
55
  'StrPath',
56
- # Type Aliases (Functions)
57
- 'AggregateFunc',
58
- 'OperatorFunc',
59
- # Type Aliases (Records & Fields)
60
- 'FieldName',
61
- 'Fields',
62
56
  # Type Aliases (Transform Specs)
63
57
  'StrAnyMap',
64
58
  'StrSeqMap',
65
59
  'StrStrMap',
66
- 'AggregateSpec',
67
- 'FilterSpec',
68
- 'MapSpec',
69
- 'SelectSpec',
70
- 'SortSpec',
71
- # Type Aliases (Pipelines)
72
- 'StepOrSteps',
73
- 'StepSeq',
74
- 'StepSpec',
75
- 'PipelineStepName',
76
- 'PipelineConfig',
77
- # Type Aliases (Helpers)
78
- 'StepApplier',
79
- 'SortKey',
80
60
  # Type Aliases (Networking / Runtime)
81
61
  'Sleeper',
82
62
  'Timeout',
@@ -126,22 +106,6 @@ type JSONRecords = list[JSONRecord]
126
106
  # Path-like inputs accepted by file helpers.
127
107
  type StrPath = str | Path | PathLike[str]
128
108
 
129
- # -- Functions -- #
130
-
131
- # Callable reducing numeric collections into a summary value.
132
- type AggregateFunc = Callable[[list[float], int], Any]
133
-
134
- # Binary predicate consumed by filter operations.
135
- type OperatorFunc = Callable[[Any, Any], bool]
136
-
137
- # -- Records & Fields -- #
138
-
139
- # Individual field identifier referenced inside specs.
140
- type FieldName = str
141
-
142
- # Ordered list of :data:`FieldName` entries preserving projection order.
143
- type Fields = list[FieldName]
144
-
145
109
  # -- Transform Specs -- #
146
110
 
147
111
  # Kept intentionally broad for runtime-friendly validation in transform.py.
@@ -157,69 +121,6 @@ type StrStrMap = Mapping[str, str]
157
121
  # Mapping whose values are homogeneous sequences.
158
122
  type StrSeqMap = Mapping[str, Sequence[Any]]
159
123
 
160
- # Transform step specifications
161
-
162
- # Filtering spec expecting ``field``, ``op``, and ``value`` keys.
163
- type FilterSpec = StrAnyMap
164
-
165
- # Field renaming instructions mapping old keys to new ones.
166
- type MapSpec = StrStrMap
167
-
168
- # Projection spec as a field list or mapping with metadata.
169
- #
170
- # Examples
171
- # --------
172
- # >>> from etlplus.types import SelectSpec
173
- # >>> spec1: SelectSpec = ['a','b']
174
- # >>> spec2: SelectSpec = {'fields': [...]}
175
- type SelectSpec = Fields | StrSeqMap
176
-
177
- # Sort directive expressed as a field string or mapping with flags.
178
- #
179
- # Examples
180
- # --------
181
- # >>> from etlplus.types import SortSpec
182
- # >>> spec1: SortSpec = 'field'
183
- # >>> spec2: SortSpec = {'field': 'x', 'reverse': True}
184
- type SortSpec = str | StrAnyMap
185
-
186
- # Aggregate instruction covering ``field``, ``func``, and optional alias.
187
- #
188
- # Supported functions: ``avg``, ``count``, ``max``, ``min``, and ``sum``.
189
- # Examples
190
- # --------
191
- # >>> from etlplus.types import AggregateSpec
192
- # >>> spec: AggregateSpec = \
193
- # ... {'field': 'x', 'func': 'sum' | 'avg' | ..., 'alias'?: '...'}
194
- type AggregateSpec = StrAnyMap
195
-
196
- # -- Pipelines-- #
197
-
198
- # Unified pipeline step spec consumed by :mod:`etlplus.ops.transform`.
199
- type StepSpec = AggregateSpec | FilterSpec | MapSpec | SelectSpec | SortSpec
200
-
201
- # Collections of steps
202
-
203
- # Ordered collection of :data:`StepSpec` entries.
204
- type StepSeq = Sequence[StepSpec]
205
-
206
- # Accepts either a single :data:`StepSpec` or a sequence of them.
207
- type StepOrSteps = StepSpec | StepSeq
208
-
209
- # Canonical literal names for supported transform stages.
210
- type PipelineStepName = Literal['filter', 'map', 'select', 'sort', 'aggregate']
211
-
212
- # Mapping from step name to its associated specification payload.
213
- type PipelineConfig = Mapping[PipelineStepName, StepOrSteps]
214
-
215
- # -- Helpers -- #
216
-
217
- # Callable that applies step configuration to a batch of records.
218
- type StepApplier = Callable[[JSONList, Any], JSONList]
219
-
220
- # Tuple combining stable sort index and computed sort value.
221
- type SortKey = tuple[int, Any]
222
-
223
124
  # -- Networking / Runtime -- #
224
125
 
225
126
  # Sleep function used by retry helpers.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: etlplus
3
- Version: 0.16.2
3
+ Version: 0.16.3
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
@@ -147,10 +147,12 @@ etlplus/file/zip.py
147
147
  etlplus/file/zsav.py
148
148
  etlplus/ops/README.md
149
149
  etlplus/ops/__init__.py
150
+ etlplus/ops/enums.py
150
151
  etlplus/ops/extract.py
151
152
  etlplus/ops/load.py
152
153
  etlplus/ops/run.py
153
154
  etlplus/ops/transform.py
155
+ etlplus/ops/types.py
154
156
  etlplus/ops/utils.py
155
157
  etlplus/ops/validate.py
156
158
  etlplus/templates/README.md
@@ -164,7 +166,7 @@ etlplus/workflow/jobs.py
164
166
  etlplus/workflow/pipeline.py
165
167
  etlplus/workflow/profile.py
166
168
  examples/README.md
167
- examples/quickstart_python.py
169
+ examples/quickstart.py
168
170
  examples/configs/ddl_spec.yml
169
171
  examples/configs/pipeline.yml
170
172
  examples/data/sample.csv
@@ -184,7 +186,6 @@ tests/integration/test_i_run.py
184
186
  tests/integration/test_i_run_profile_pagination_defaults.py
185
187
  tests/integration/test_i_run_profile_rate_limit_defaults.py
186
188
  tests/unit/conftest.py
187
- tests/unit/test_u_enums.py
188
189
  tests/unit/test_u_main.py
189
190
  tests/unit/test_u_mixins.py
190
191
  tests/unit/test_u_utils.py
@@ -219,6 +220,7 @@ tests/unit/database/test_u_database_schema.py
219
220
  tests/unit/file/test_u_file_core.py
220
221
  tests/unit/file/test_u_file_enums.py
221
222
  tests/unit/file/test_u_file_yaml.py
223
+ tests/unit/ops/test_u_ops_enums.py
222
224
  tests/unit/ops/test_u_ops_extract.py
223
225
  tests/unit/ops/test_u_ops_load.py
224
226
  tests/unit/ops/test_u_ops_run.py
@@ -7,7 +7,7 @@ A few self-contained examples to get you started quickly.
7
7
  Run a tiny ETL in Python using the sample data shipped in this repo.
8
8
 
9
9
  ```bash
10
- python examples/quickstart_python.py
10
+ python examples/quickstart.py
11
11
  ```
12
12
 
13
13
  What it does: