etlplus 0.10.1__tar.gz → 0.10.2__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 (150) hide show
  1. {etlplus-0.10.1/etlplus.egg-info → etlplus-0.10.2}/PKG-INFO +1 -1
  2. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/enums.py +23 -1
  3. {etlplus-0.10.1 → etlplus-0.10.2/etlplus.egg-info}/PKG-INFO +1 -1
  4. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_enums.py +16 -9
  5. {etlplus-0.10.1 → etlplus-0.10.2}/.coveragerc +0 -0
  6. {etlplus-0.10.1 → etlplus-0.10.2}/.editorconfig +0 -0
  7. {etlplus-0.10.1 → etlplus-0.10.2}/.gitattributes +0 -0
  8. {etlplus-0.10.1 → etlplus-0.10.2}/.github/actions/python-bootstrap/action.yml +0 -0
  9. {etlplus-0.10.1 → etlplus-0.10.2}/.github/workflows/ci.yml +0 -0
  10. {etlplus-0.10.1 → etlplus-0.10.2}/.gitignore +0 -0
  11. {etlplus-0.10.1 → etlplus-0.10.2}/.pre-commit-config.yaml +0 -0
  12. {etlplus-0.10.1 → etlplus-0.10.2}/.ruff.toml +0 -0
  13. {etlplus-0.10.1 → etlplus-0.10.2}/CODE_OF_CONDUCT.md +0 -0
  14. {etlplus-0.10.1 → etlplus-0.10.2}/CONTRIBUTING.md +0 -0
  15. {etlplus-0.10.1 → etlplus-0.10.2}/DEMO.md +0 -0
  16. {etlplus-0.10.1 → etlplus-0.10.2}/LICENSE +0 -0
  17. {etlplus-0.10.1 → etlplus-0.10.2}/MANIFEST.in +0 -0
  18. {etlplus-0.10.1 → etlplus-0.10.2}/Makefile +0 -0
  19. {etlplus-0.10.1 → etlplus-0.10.2}/README.md +0 -0
  20. {etlplus-0.10.1 → etlplus-0.10.2}/REFERENCES.md +0 -0
  21. {etlplus-0.10.1 → etlplus-0.10.2}/docs/README.md +0 -0
  22. {etlplus-0.10.1 → etlplus-0.10.2}/docs/pipeline-guide.md +0 -0
  23. {etlplus-0.10.1 → etlplus-0.10.2}/docs/snippets/installation_version.md +0 -0
  24. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/__init__.py +0 -0
  25. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/__main__.py +0 -0
  26. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/__version__.py +0 -0
  27. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/README.md +0 -0
  28. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/__init__.py +0 -0
  29. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/auth.py +0 -0
  30. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/config.py +0 -0
  31. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/endpoint_client.py +0 -0
  32. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/errors.py +0 -0
  33. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/pagination/__init__.py +0 -0
  34. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/pagination/client.py +0 -0
  35. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/pagination/config.py +0 -0
  36. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/pagination/paginator.py +0 -0
  37. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/rate_limiting/__init__.py +0 -0
  38. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/rate_limiting/config.py +0 -0
  39. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/rate_limiting/rate_limiter.py +0 -0
  40. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/request_manager.py +0 -0
  41. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/retry_manager.py +0 -0
  42. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/transport.py +0 -0
  43. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/api/types.py +0 -0
  44. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/cli/__init__.py +0 -0
  45. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/cli/commands.py +0 -0
  46. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/cli/constants.py +0 -0
  47. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/cli/handlers.py +0 -0
  48. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/cli/io.py +0 -0
  49. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/cli/main.py +0 -0
  50. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/cli/options.py +0 -0
  51. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/cli/state.py +0 -0
  52. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/cli/types.py +0 -0
  53. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/config/__init__.py +0 -0
  54. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/config/connector.py +0 -0
  55. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/config/jobs.py +0 -0
  56. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/config/pipeline.py +0 -0
  57. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/config/profile.py +0 -0
  58. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/config/types.py +0 -0
  59. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/config/utils.py +0 -0
  60. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/database/__init__.py +0 -0
  61. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/database/ddl.py +0 -0
  62. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/database/engine.py +0 -0
  63. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/database/orm.py +0 -0
  64. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/database/schema.py +0 -0
  65. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/database/types.py +0 -0
  66. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/extract.py +0 -0
  67. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/file.py +0 -0
  68. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/load.py +0 -0
  69. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/mixins.py +0 -0
  70. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/py.typed +0 -0
  71. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/run.py +0 -0
  72. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/run_helpers.py +0 -0
  73. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/templates/__init__.py +0 -0
  74. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/templates/ddl.sql.j2 +0 -0
  75. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/templates/view.sql.j2 +0 -0
  76. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/transform.py +0 -0
  77. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/types.py +0 -0
  78. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/utils.py +0 -0
  79. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/validate.py +0 -0
  80. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/validation/__init__.py +0 -0
  81. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus/validation/utils.py +0 -0
  82. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus.egg-info/SOURCES.txt +0 -0
  83. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus.egg-info/dependency_links.txt +0 -0
  84. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus.egg-info/entry_points.txt +0 -0
  85. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus.egg-info/requires.txt +0 -0
  86. {etlplus-0.10.1 → etlplus-0.10.2}/etlplus.egg-info/top_level.txt +0 -0
  87. {etlplus-0.10.1 → etlplus-0.10.2}/examples/README.md +0 -0
  88. {etlplus-0.10.1 → etlplus-0.10.2}/examples/configs/ddl_spec.yml +0 -0
  89. {etlplus-0.10.1 → etlplus-0.10.2}/examples/configs/pipeline.yml +0 -0
  90. {etlplus-0.10.1 → etlplus-0.10.2}/examples/data/sample.csv +0 -0
  91. {etlplus-0.10.1 → etlplus-0.10.2}/examples/data/sample.json +0 -0
  92. {etlplus-0.10.1 → etlplus-0.10.2}/examples/data/sample.xml +0 -0
  93. {etlplus-0.10.1 → etlplus-0.10.2}/examples/data/sample.xsd +0 -0
  94. {etlplus-0.10.1 → etlplus-0.10.2}/examples/data/sample.yaml +0 -0
  95. {etlplus-0.10.1 → etlplus-0.10.2}/examples/quickstart_python.py +0 -0
  96. {etlplus-0.10.1 → etlplus-0.10.2}/pyproject.toml +0 -0
  97. {etlplus-0.10.1 → etlplus-0.10.2}/pytest.ini +0 -0
  98. {etlplus-0.10.1 → etlplus-0.10.2}/setup.cfg +0 -0
  99. {etlplus-0.10.1 → etlplus-0.10.2}/setup.py +0 -0
  100. {etlplus-0.10.1 → etlplus-0.10.2}/tests/__init__.py +0 -0
  101. {etlplus-0.10.1 → etlplus-0.10.2}/tests/conftest.py +0 -0
  102. {etlplus-0.10.1 → etlplus-0.10.2}/tests/integration/conftest.py +0 -0
  103. {etlplus-0.10.1 → etlplus-0.10.2}/tests/integration/test_i_cli.py +0 -0
  104. {etlplus-0.10.1 → etlplus-0.10.2}/tests/integration/test_i_examples_data_parity.py +0 -0
  105. {etlplus-0.10.1 → etlplus-0.10.2}/tests/integration/test_i_pagination_strategy.py +0 -0
  106. {etlplus-0.10.1 → etlplus-0.10.2}/tests/integration/test_i_pipeline_smoke.py +0 -0
  107. {etlplus-0.10.1 → etlplus-0.10.2}/tests/integration/test_i_pipeline_yaml_load.py +0 -0
  108. {etlplus-0.10.1 → etlplus-0.10.2}/tests/integration/test_i_run.py +0 -0
  109. {etlplus-0.10.1 → etlplus-0.10.2}/tests/integration/test_i_run_profile_pagination_defaults.py +0 -0
  110. {etlplus-0.10.1 → etlplus-0.10.2}/tests/integration/test_i_run_profile_rate_limit_defaults.py +0 -0
  111. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/conftest.py +0 -0
  112. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_auth.py +0 -0
  113. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_config.py +0 -0
  114. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_endpoint_client.py +0 -0
  115. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_mocks.py +0 -0
  116. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_pagination_client.py +0 -0
  117. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_pagination_config.py +0 -0
  118. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_paginator.py +0 -0
  119. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_rate_limit_config.py +0 -0
  120. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_rate_limiter.py +0 -0
  121. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_request_manager.py +0 -0
  122. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_retry_manager.py +0 -0
  123. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_transport.py +0 -0
  124. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/api/test_u_types.py +0 -0
  125. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/cli/conftest.py +0 -0
  126. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/cli/test_u_cli_handlers.py +0 -0
  127. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/cli/test_u_cli_main.py +0 -0
  128. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/cli/test_u_cli_state.py +0 -0
  129. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/config/test_u_config_utils.py +0 -0
  130. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/config/test_u_connector.py +0 -0
  131. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/config/test_u_jobs.py +0 -0
  132. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/config/test_u_pipeline.py +0 -0
  133. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/conftest.py +0 -0
  134. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/database/test_u_database_ddl.py +0 -0
  135. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/database/test_u_database_engine.py +0 -0
  136. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/database/test_u_database_orm.py +0 -0
  137. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/database/test_u_database_schema.py +0 -0
  138. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_extract.py +0 -0
  139. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_file.py +0 -0
  140. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_load.py +0 -0
  141. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_main.py +0 -0
  142. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_mixins.py +0 -0
  143. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_run.py +0 -0
  144. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_run_helpers.py +0 -0
  145. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_transform.py +0 -0
  146. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_utils.py +0 -0
  147. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_validate.py +0 -0
  148. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/test_u_version.py +0 -0
  149. {etlplus-0.10.1 → etlplus-0.10.2}/tests/unit/validation/test_u_validation_utils.py +0 -0
  150. {etlplus-0.10.1 → etlplus-0.10.2}/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.1
3
+ Version: 0.10.2
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
@@ -524,6 +524,7 @@ def coerce_http_method(
524
524
 
525
525
  def infer_file_format_and_compression(
526
526
  value: object,
527
+ filename: object | None = None,
527
528
  ) -> tuple[FileFormat | None, CompressionFormat | None]:
528
529
  """
529
530
  Infer data format and compression from a filename, extension, or MIME type.
@@ -532,6 +533,9 @@ def infer_file_format_and_compression(
532
533
  ----------
533
534
  value : object
534
535
  A filename, extension, MIME type, or existing enum member.
536
+ filename : object | None, optional
537
+ A filename to consult for extension-based inference (e.g. when
538
+ ``value`` is ``application/octet-stream``).
535
539
 
536
540
  Returns
537
541
  -------
@@ -555,7 +559,25 @@ def infer_file_format_and_compression(
555
559
  compression = CompressionFormat.try_coerce(mime)
556
560
  fmt = FileFormat.try_coerce(mime)
557
561
 
558
- suffixes = PurePath(text).suffixes
562
+ is_mime = mime.startswith(
563
+ (
564
+ 'application/',
565
+ 'text/',
566
+ 'audio/',
567
+ 'image/',
568
+ 'video/',
569
+ 'multipart/',
570
+ ),
571
+ )
572
+ suffix_source: object | None = filename if filename is not None else text
573
+ if is_mime and filename is None:
574
+ suffix_source = None
575
+
576
+ suffixes = (
577
+ PurePath(str(suffix_source)).suffixes
578
+ if suffix_source is not None
579
+ else []
580
+ )
559
581
  if suffixes:
560
582
  normalized_suffixes = [suffix.casefold() for suffix in suffixes]
561
583
  compression = (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: etlplus
3
- Version: 0.10.1
3
+ Version: 0.10.2
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
@@ -119,25 +119,32 @@ class TestInferFileFormatAndCompression:
119
119
  """Unit test suite for :func:`infer_file_format_and_compression`."""
120
120
 
121
121
  @pytest.mark.parametrize(
122
- 'value,expected_format,expected_compression',
122
+ 'value,filename,expected_format,expected_compression',
123
123
  [
124
- ('data.csv.gz', FileFormat.CSV, CompressionFormat.GZ),
125
- ('data.jsonl.gz', FileFormat.NDJSON, CompressionFormat.GZ),
126
- ('data.zip', None, CompressionFormat.ZIP),
127
- ('application/json; charset=utf-8', FileFormat.JSON, None),
128
- ('application/gzip', None, CompressionFormat.GZ),
129
- (FileFormat.GZ, None, CompressionFormat.GZ),
130
- (CompressionFormat.ZIP, None, CompressionFormat.ZIP),
124
+ ('data.csv.gz', None, FileFormat.CSV, CompressionFormat.GZ),
125
+ ('data.jsonl.gz', None, FileFormat.NDJSON, CompressionFormat.GZ),
126
+ ('data.zip', None, None, CompressionFormat.ZIP),
127
+ ('application/json; charset=utf-8', None, FileFormat.JSON, None),
128
+ ('application/gzip', None, None, CompressionFormat.GZ),
129
+ (
130
+ 'application/octet-stream',
131
+ 'payload.csv.gz',
132
+ FileFormat.CSV,
133
+ CompressionFormat.GZ,
134
+ ),
135
+ (FileFormat.GZ, None, None, CompressionFormat.GZ),
136
+ (CompressionFormat.ZIP, None, None, CompressionFormat.ZIP),
131
137
  ],
132
138
  )
133
139
  def test_infers_format_and_compression(
134
140
  self,
135
141
  value: object,
142
+ filename: object | None,
136
143
  expected_format: FileFormat | None,
137
144
  expected_compression: CompressionFormat | None,
138
145
  ) -> None:
139
146
  """Test mixed inputs for format and compression inference."""
140
- fmt, compression = infer_file_format_and_compression(value)
147
+ fmt, compression = infer_file_format_and_compression(value, filename)
141
148
  assert fmt is expected_format
142
149
  assert compression is expected_compression
143
150
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes