floe-python 0.6.7__tar.gz → 0.6.9__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 (241) hide show
  1. {floe_python-0.6.7 → floe_python-0.6.9}/Cargo.lock +13 -13
  2. {floe_python-0.6.7 → floe_python-0.6.9}/PKG-INFO +1 -1
  3. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/Cargo.toml +1 -1
  4. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/config/parse.rs +4 -0
  5. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/config/template.rs +14 -0
  6. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/config/types.rs +2 -0
  7. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/providers/s3.rs +22 -1
  8. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/lineage/mod.rs +20 -2
  9. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/lineage_validation.rs +18 -0
  10. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/templating.rs +79 -0
  11. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/storage/s3.rs +22 -1
  12. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/lineage.rs +63 -2
  13. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/Cargo.toml +2 -2
  14. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/pyproject.duckdb.toml +2 -2
  15. {floe_python-0.6.7 → floe_python-0.6.9}/pyproject.toml +1 -1
  16. {floe_python-0.6.7 → floe_python-0.6.9}/Cargo.toml +0 -0
  17. {floe_python-0.6.7 → floe_python-0.6.9}/README.md +0 -0
  18. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/README.md +0 -0
  19. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/add_entity.rs +0 -0
  20. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/checks/cast.rs +0 -0
  21. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/checks/mismatch.rs +0 -0
  22. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/checks/mod.rs +0 -0
  23. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/checks/normalize.rs +0 -0
  24. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/checks/not_null.rs +0 -0
  25. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/checks/unique.rs +0 -0
  26. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/config/catalog.rs +0 -0
  27. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/config/location.rs +0 -0
  28. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/config/mod.rs +0 -0
  29. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/config/storage.rs +0 -0
  30. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/config/validate.rs +0 -0
  31. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/config/yaml_decode.rs +0 -0
  32. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/errors.rs +0 -0
  33. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/format.rs +0 -0
  34. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/mod.rs +0 -0
  35. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/read/avro.rs +0 -0
  36. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/read/csv.rs +0 -0
  37. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/read/fixed_width.rs +0 -0
  38. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/read/json.rs +0 -0
  39. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/read/json_selector.rs +0 -0
  40. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/read/mod.rs +0 -0
  41. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/read/orc.rs +0 -0
  42. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/read/parquet.rs +0 -0
  43. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/read/xlsx.rs +0 -0
  44. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/read/xml.rs +0 -0
  45. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/read/xml_selector.rs +0 -0
  46. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/core/extensions.rs +0 -0
  47. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/core/mod.rs +0 -0
  48. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/core/paths.rs +0 -0
  49. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/core/placement.rs +0 -0
  50. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/core/planner.rs +0 -0
  51. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/core/uri.rs +0 -0
  52. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/core/validation.rs +0 -0
  53. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/mod.rs +0 -0
  54. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/object_store.rs +0 -0
  55. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/ops/archive.rs +0 -0
  56. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/ops/inputs.rs +0 -0
  57. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/ops/mod.rs +0 -0
  58. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/ops/output.rs +0 -0
  59. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/providers/adls.rs +0 -0
  60. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/providers/gcs.rs +0 -0
  61. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/providers/local.rs +0 -0
  62. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/providers/mod.rs +0 -0
  63. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/storage/target.rs +0 -0
  64. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/unique_seed/mod.rs +0 -0
  65. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/accepted.rs +0 -0
  66. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/arrow_convert.rs +0 -0
  67. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/csv.rs +0 -0
  68. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/delta/commit_metrics.rs +0 -0
  69. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/delta/options.rs +0 -0
  70. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/delta/record_batch.rs +0 -0
  71. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/delta/unity.rs +0 -0
  72. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/delta/unity_tests.rs +0 -0
  73. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/delta.rs +0 -0
  74. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/duckdb/conn.rs +0 -0
  75. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/duckdb/merge.rs +0 -0
  76. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/duckdb.rs +0 -0
  77. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/iceberg/context.rs +0 -0
  78. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/iceberg/data_files.rs +0 -0
  79. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/iceberg/glue.rs +0 -0
  80. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/iceberg/metadata.rs +0 -0
  81. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/iceberg/rest.rs +0 -0
  82. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/iceberg/schema.rs +0 -0
  83. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/iceberg.rs +0 -0
  84. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/metrics.rs +0 -0
  85. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/mod.rs +0 -0
  86. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/parquet.rs +0 -0
  87. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/parts.rs +0 -0
  88. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/sink_format.rs +0 -0
  89. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/strategy/append.rs +0 -0
  90. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/strategy/merge/keys.rs +0 -0
  91. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/strategy/merge/mod.rs +0 -0
  92. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/strategy/merge/scd1.rs +0 -0
  93. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/strategy/merge/scd2.rs +0 -0
  94. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/strategy/merge/shared.rs +0 -0
  95. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/strategy/mod.rs +0 -0
  96. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/io/write/strategy/overwrite.rs +0 -0
  97. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/lib.rs +0 -0
  98. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/log.rs +0 -0
  99. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/manifest/builder.rs +0 -0
  100. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/manifest/mod.rs +0 -0
  101. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/manifest/model.rs +0 -0
  102. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/manifest/reconstruct.rs +0 -0
  103. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/manifest/runtime.rs +0 -0
  104. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/profile/mod.rs +0 -0
  105. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/profile/parse.rs +0 -0
  106. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/profile/types.rs +0 -0
  107. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/profile/validate.rs +0 -0
  108. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/report/build.rs +0 -0
  109. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/report/entity.rs +0 -0
  110. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/report/mod.rs +0 -0
  111. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/report/output.rs +0 -0
  112. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/context.rs +0 -0
  113. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/entity/accepted_buffer.rs +0 -0
  114. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/entity/accepted_write.rs +0 -0
  115. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/entity/incremental.rs +0 -0
  116. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/entity/mod.rs +0 -0
  117. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/entity/pii.rs +0 -0
  118. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/entity/precheck.rs +0 -0
  119. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/entity/process.rs +0 -0
  120. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/entity/resolve.rs +0 -0
  121. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/entity/validate_split.rs +0 -0
  122. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/events.rs +0 -0
  123. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/file.rs +0 -0
  124. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/mod.rs +0 -0
  125. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/output.rs +0 -0
  126. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/run/perf.rs +0 -0
  127. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/runner/mod.rs +0 -0
  128. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/runner/outcome.rs +0 -0
  129. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/runtime.rs +0 -0
  130. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/secret.rs +0 -0
  131. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/state/mod.rs +0 -0
  132. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/vars/mod.rs +0 -0
  133. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/vars/resolve.rs +0 -0
  134. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/src/warnings.rs +0 -0
  135. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/archive_run.rs +0 -0
  136. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/composite_unique.rs +0 -0
  137. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/delta_run.rs +0 -0
  138. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/dry_run.rs +0 -0
  139. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/duckdb_run.rs +0 -0
  140. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/fixed_width.rs +0 -0
  141. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/iceberg_gcs_run.rs +0 -0
  142. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/iceberg_glue_run.rs +0 -0
  143. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/iceberg_run.rs +0 -0
  144. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/iceberg_s3_run.rs +0 -0
  145. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/json_selectors.rs +0 -0
  146. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/local_run.rs +0 -0
  147. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/mod.rs +0 -0
  148. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/path_normalization.rs +0 -0
  149. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration/run_entities_filter.rs +0 -0
  150. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/integration.rs +0 -0
  151. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/common.rs +0 -0
  152. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/add_entity.rs +0 -0
  153. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/adls_storage.rs +0 -0
  154. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/adls_validation.rs +0 -0
  155. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/catalogs.rs +0 -0
  156. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/config_validation.rs +0 -0
  157. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/duckdb_validation.rs +0 -0
  158. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/gcs_storage.rs +0 -0
  159. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/gcs_validation.rs +0 -0
  160. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/local_storage.rs +0 -0
  161. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/location.rs +0 -0
  162. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/mod.rs +0 -0
  163. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/parse.rs +0 -0
  164. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/pii_validation.rs +0 -0
  165. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/remote_base.rs +0 -0
  166. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/config/storage_resolver_uri.rs +0 -0
  167. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/format.rs +0 -0
  168. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/mod.rs +0 -0
  169. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/avro_input.rs +0 -0
  170. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/csv_nulls.rs +0 -0
  171. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/json_array.rs +0 -0
  172. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/json_ndjson.rs +0 -0
  173. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/json_selector.rs +0 -0
  174. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/mod.rs +0 -0
  175. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/orc_input.rs +0 -0
  176. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/parquet_input.rs +0 -0
  177. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/tsv.rs +0 -0
  178. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/xlsx_input.rs +0 -0
  179. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/xml.rs +0 -0
  180. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/read/xml_selector.rs +0 -0
  181. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/storage/adls.rs +0 -0
  182. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/storage/adls_integration.rs +0 -0
  183. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/storage/gcs.rs +0 -0
  184. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/storage/inputs.rs +0 -0
  185. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/storage/local.rs +0 -0
  186. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/storage/mod.rs +0 -0
  187. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/storage/paths.rs +0 -0
  188. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/storage/planner.rs +0 -0
  189. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/storage/target.rs +0 -0
  190. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/write/delta_merge.rs +0 -0
  191. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/write/delta_write.rs +0 -0
  192. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/write/iceberg_write.rs +0 -0
  193. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/write/metrics.rs +0 -0
  194. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/write/mod.rs +0 -0
  195. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/write/object_store.rs +0 -0
  196. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/write/parquet_write.rs +0 -0
  197. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/write/parts.rs +0 -0
  198. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/io/write/rejected_csv.rs +0 -0
  199. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/manifest/mod.rs +0 -0
  200. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/manifest/runtime.rs +0 -0
  201. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/mod.rs +0 -0
  202. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/profile/mod.rs +0 -0
  203. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/profile/parse.rs +0 -0
  204. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/profile/validate.rs +0 -0
  205. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/report/accepted_output.rs +0 -0
  206. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/report/mod.rs +0 -0
  207. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/report/storage.rs +0 -0
  208. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/check_order.rs +0 -0
  209. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/checks.rs +0 -0
  210. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/entity/accepted_output.rs +0 -0
  211. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/entity/incremental.rs +0 -0
  212. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/entity/mod.rs +0 -0
  213. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/mod.rs +0 -0
  214. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/normalize.rs +0 -0
  215. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/pii.rs +0 -0
  216. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/replay_base.rs +0 -0
  217. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/report.rs +0 -0
  218. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/run/schema_mismatch.rs +0 -0
  219. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/runner/adapter.rs +0 -0
  220. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/runner/mod.rs +0 -0
  221. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/state/mod.rs +0 -0
  222. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/vars/mod.rs +0 -0
  223. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit/vars/resolve.rs +0 -0
  224. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-core/tests/unit.rs +0 -0
  225. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/.gitignore +0 -0
  226. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/README.md +0 -0
  227. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/src/functions.rs +0 -0
  228. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/src/lib.rs +0 -0
  229. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/src/observer.rs +0 -0
  230. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/src/types/config.rs +0 -0
  231. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/src/types/errors.rs +0 -0
  232. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/src/types/mod.rs +0 -0
  233. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/src/types/outcome.rs +0 -0
  234. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/tests/fixtures/config.yml +0 -0
  235. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/tests/fixtures/in/customer/customers_valid.csv +0 -0
  236. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/tests/fixtures/invalid_config.yml +0 -0
  237. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/tests/fixtures/profile.yml +0 -0
  238. {floe_python-0.6.7 → floe_python-0.6.9}/crates/floe-python/tests/test_floe.py +0 -0
  239. {floe_python-0.6.7 → floe_python-0.6.9}/python/floe/__init__.py +0 -0
  240. {floe_python-0.6.7 → floe_python-0.6.9}/python/floe/_floe.pyi +0 -0
  241. {floe_python-0.6.7 → floe_python-0.6.9}/python/floe/py.typed +0 -0
@@ -1805,7 +1805,7 @@ dependencies = [
1805
1805
  "crc",
1806
1806
  "digest",
1807
1807
  "rustversion",
1808
- "spin 0.10.0",
1808
+ "spin 0.10.1",
1809
1809
  ]
1810
1810
 
1811
1811
  [[package]]
@@ -1847,9 +1847,9 @@ dependencies = [
1847
1847
 
1848
1848
  [[package]]
1849
1849
  name = "crossbeam-epoch"
1850
- version = "0.9.18"
1850
+ version = "0.9.20"
1851
1851
  source = "registry+https://github.com/rust-lang/crates.io-index"
1852
- checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
1852
+ checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
1853
1853
  dependencies = [
1854
1854
  "crossbeam-utils",
1855
1855
  ]
@@ -3205,9 +3205,9 @@ dependencies = [
3205
3205
 
3206
3206
  [[package]]
3207
3207
  name = "ethnum"
3208
- version = "1.5.2"
3208
+ version = "1.5.3"
3209
3209
  source = "registry+https://github.com/rust-lang/crates.io-index"
3210
- checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b"
3210
+ checksum = "40404c3f5f511ec4da6fe866ddf6a717c309fdbb69fbbad7b0f3edab8f2e835f"
3211
3211
 
3212
3212
  [[package]]
3213
3213
  name = "event-listener"
@@ -3340,7 +3340,7 @@ dependencies = [
3340
3340
 
3341
3341
  [[package]]
3342
3342
  name = "floe-cli"
3343
- version = "0.6.7"
3343
+ version = "0.6.9"
3344
3344
  dependencies = [
3345
3345
  "assert_cmd",
3346
3346
  "clap",
@@ -3353,7 +3353,7 @@ dependencies = [
3353
3353
 
3354
3354
  [[package]]
3355
3355
  name = "floe-core"
3356
- version = "0.6.7"
3356
+ version = "0.6.9"
3357
3357
  dependencies = [
3358
3358
  "apache-avro",
3359
3359
  "arrow",
@@ -3399,7 +3399,7 @@ dependencies = [
3399
3399
 
3400
3400
  [[package]]
3401
3401
  name = "floe-python"
3402
- version = "0.6.7"
3402
+ version = "0.6.9"
3403
3403
  dependencies = [
3404
3404
  "floe-core",
3405
3405
  "pyo3",
@@ -4535,7 +4535,7 @@ version = "1.5.0"
4535
4535
  source = "registry+https://github.com/rust-lang/crates.io-index"
4536
4536
  checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
4537
4537
  dependencies = [
4538
- "spin 0.9.8",
4538
+ "spin 0.9.9",
4539
4539
  ]
4540
4540
 
4541
4541
  [[package]]
@@ -7535,15 +7535,15 @@ dependencies = [
7535
7535
 
7536
7536
  [[package]]
7537
7537
  name = "spin"
7538
- version = "0.9.8"
7538
+ version = "0.9.9"
7539
7539
  source = "registry+https://github.com/rust-lang/crates.io-index"
7540
- checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
7540
+ checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
7541
7541
 
7542
7542
  [[package]]
7543
7543
  name = "spin"
7544
- version = "0.10.0"
7544
+ version = "0.10.1"
7545
7545
  source = "registry+https://github.com/rust-lang/crates.io-index"
7546
- checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591"
7546
+ checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3"
7547
7547
 
7548
7548
  [[package]]
7549
7549
  name = "spki"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: floe-python
3
- Version: 0.6.7
3
+ Version: 0.6.9
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: Intended Audience :: Science/Research
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "floe-core"
3
- version = "0.6.7"
3
+ version = "0.6.9"
4
4
  edition = "2021"
5
5
  description = "Core library for Floe, a YAML-driven technical ingestion tool."
6
6
  license = "MIT"
@@ -1190,9 +1190,11 @@ pub(crate) fn parse_lineage_config(value: &Yaml) -> FloeResult<LineageConfig> {
1190
1190
  "lineage",
1191
1191
  &[
1192
1192
  "url",
1193
+ "endpoint",
1193
1194
  "api_key",
1194
1195
  "timeout_secs",
1195
1196
  "namespace",
1197
+ "dataset_namespace",
1196
1198
  "producer",
1197
1199
  "max_failures",
1198
1200
  "job_name",
@@ -1200,9 +1202,11 @@ pub(crate) fn parse_lineage_config(value: &Yaml) -> FloeResult<LineageConfig> {
1200
1202
  )?;
1201
1203
  Ok(LineageConfig {
1202
1204
  url: get_string(hash, "url", "lineage")?,
1205
+ endpoint: opt_string(hash, "endpoint", "lineage")?,
1203
1206
  api_key: opt_string(hash, "api_key", "lineage")?,
1204
1207
  timeout_secs: opt_u64(hash, "timeout_secs", "lineage")?,
1205
1208
  namespace: get_string(hash, "namespace", "lineage")?,
1209
+ dataset_namespace: opt_string(hash, "dataset_namespace", "lineage")?,
1206
1210
  producer: opt_string(hash, "producer", "lineage")?,
1207
1211
  max_failures: opt_u32(hash, "max_failures", "lineage")?,
1208
1212
  job_name: opt_string(hash, "job_name", "lineage")?,
@@ -34,9 +34,11 @@ pub fn apply_templates_with_vars(
34
34
 
35
35
  if let Some(lineage) = config.lineage.as_mut() {
36
36
  lineage.url = replace_placeholders(&lineage.url, &vars, "lineage.url", None)?;
37
+ replace_lineage_field(&mut lineage.endpoint, &vars, "endpoint")?;
37
38
  if let Some(api_key) = lineage.api_key.as_mut() {
38
39
  *api_key = replace_placeholders(api_key, &vars, "lineage.api_key", None)?;
39
40
  }
41
+ replace_lineage_field(&mut lineage.dataset_namespace, &vars, "dataset_namespace")?;
40
42
  }
41
43
 
42
44
  if let Some(storages) = config.storages.as_mut() {
@@ -96,6 +98,18 @@ pub fn apply_templates_with_vars(
96
98
  Ok(())
97
99
  }
98
100
 
101
+ fn replace_lineage_field(
102
+ value: &mut Option<String>,
103
+ vars: &HashMap<String, String>,
104
+ field_name: &str,
105
+ ) -> FloeResult<()> {
106
+ if let Some(current) = value.as_mut() {
107
+ let field = format!("lineage.{field_name}");
108
+ *current = replace_placeholders(current, vars, &field, None)?;
109
+ }
110
+ Ok(())
111
+ }
112
+
99
113
  fn replace_storage_definition_field(
100
114
  value: &mut Option<String>,
101
115
  vars: &HashMap<String, String>,
@@ -28,9 +28,11 @@ pub struct RootConfig {
28
28
  #[derive(Debug, Clone, Serialize, Deserialize)]
29
29
  pub struct LineageConfig {
30
30
  pub url: String,
31
+ pub endpoint: Option<String>,
31
32
  pub api_key: Option<String>,
32
33
  pub timeout_secs: Option<u64>,
33
34
  pub namespace: String,
35
+ pub dataset_namespace: Option<String>,
34
36
  pub producer: Option<String>,
35
37
  pub max_failures: Option<u32>,
36
38
  pub job_name: Option<String>,
@@ -12,6 +12,8 @@ use crate::io::storage::uri::{format_bucket_uri, parse_bucket_uri, BucketLocatio
12
12
  use crate::io::storage::{planner, ConditionalWrite, ObjectRef, StorageClient, StoredObject};
13
13
  use crate::FloeResult;
14
14
 
15
+ const AWS_S3_FORCE_PATH_STYLE: &str = "AWS_S3_FORCE_PATH_STYLE";
16
+
15
17
  pub struct S3Client {
16
18
  bucket: String,
17
19
  client: Client,
@@ -44,7 +46,7 @@ impl S3Client {
44
46
  builder.load().await
45
47
  });
46
48
  let mut s3_builder = aws_sdk_s3::config::Builder::from(&config);
47
- if path_style_access.unwrap_or(false) {
49
+ if resolve_path_style_access(path_style_access) {
48
50
  s3_builder = s3_builder.force_path_style(true);
49
51
  }
50
52
  let client = Client::from_conf(s3_builder.build());
@@ -290,6 +292,25 @@ impl StorageClient for S3Client {
290
292
  }
291
293
  }
292
294
 
295
+ #[doc(hidden)]
296
+ pub fn resolve_path_style_access(configured: Option<bool>) -> bool {
297
+ let env_value = std::env::var(AWS_S3_FORCE_PATH_STYLE).ok();
298
+ resolve_path_style_access_from_env(configured, env_value.as_deref())
299
+ }
300
+
301
+ #[doc(hidden)]
302
+ pub fn resolve_path_style_access_from_env(
303
+ configured: Option<bool>,
304
+ env_value: Option<&str>,
305
+ ) -> bool {
306
+ configured.unwrap_or_else(|| {
307
+ env_value.is_some_and(|value| {
308
+ let value = value.trim();
309
+ value == "1" || value.eq_ignore_ascii_case("true")
310
+ })
311
+ })
312
+ }
313
+
293
314
  fn is_not_found<E: std::fmt::Display>(err: &E) -> bool {
294
315
  let text = err.to_string();
295
316
  text.contains("NoSuchKey") || text.contains("NotFound") || text.contains("404")
@@ -32,6 +32,18 @@ struct EntityUris {
32
32
  rejected: Option<OlDataset>,
33
33
  }
34
34
 
35
+ fn resolve_lineage_url(base: &str, endpoint: Option<&str>) -> String {
36
+ let path = endpoint
37
+ .map(str::trim)
38
+ .filter(|s| !s.is_empty())
39
+ .unwrap_or("api/v1/lineage");
40
+ format!(
41
+ "{}/{}",
42
+ base.trim_end_matches('/'),
43
+ path.trim_start_matches('/')
44
+ )
45
+ }
46
+
35
47
  pub struct OpenLineageObserver {
36
48
  client: reqwest::blocking::Client,
37
49
  config: LineageConfig,
@@ -91,6 +103,12 @@ impl OpenLineageObserver {
91
103
  })
92
104
  .collect();
93
105
 
106
+ let dataset_namespace = config
107
+ .dataset_namespace
108
+ .clone()
109
+ .filter(|s| !s.trim().is_empty())
110
+ .unwrap_or_else(|| config.namespace.clone());
111
+
94
112
  let entity_uris = entities
95
113
  .iter()
96
114
  .map(|e| {
@@ -105,7 +123,7 @@ impl OpenLineageObserver {
105
123
  let ns = iceberg.namespace.as_deref().unwrap_or(e.name.as_str());
106
124
  let tbl = iceberg.table.as_deref().unwrap_or(e.name.as_str());
107
125
  OlDataset {
108
- namespace: config.namespace.clone(),
126
+ namespace: dataset_namespace.clone(),
109
127
  name: format!("{ns}.{tbl}"),
110
128
  }
111
129
  }
@@ -177,7 +195,7 @@ impl OpenLineageObserver {
177
195
  return;
178
196
  }
179
197
 
180
- let url = format!("{}/api/v1/lineage", self.config.url.trim_end_matches('/'));
198
+ let url = resolve_lineage_url(&self.config.url, self.config.endpoint.as_deref());
181
199
  let max_failures = self.config.max_failures.unwrap_or(3) as usize;
182
200
  let retry_delays_ms: &[u64] = &[0, 100, 500];
183
201
 
@@ -74,7 +74,9 @@ report:
74
74
  path: "/tmp/reports"
75
75
  lineage:
76
76
  url: "http://marquez:5000"
77
+ endpoint: "/api/v1/openlineage/lineage"
77
78
  namespace: "my-namespace"
79
+ dataset_namespace: "iceberg.prod"
78
80
  timeout_secs: 10
79
81
  producer: "https://github.com/myorg/floe"
80
82
  entities:
@@ -95,6 +97,20 @@ entities:
95
97
  "#;
96
98
  let path = write_temp_config(config);
97
99
  validate(&path, ValidateOptions::default()).expect("valid lineage config");
100
+ let parsed = load_config_with_profile_overrides(
101
+ &path,
102
+ &std::collections::HashMap::new(),
103
+ None,
104
+ None,
105
+ None,
106
+ )
107
+ .expect("lineage config should parse");
108
+ let lineage = parsed.lineage.expect("lineage should be present");
109
+ assert_eq!(
110
+ lineage.endpoint.as_deref(),
111
+ Some("/api/v1/openlineage/lineage")
112
+ );
113
+ assert_eq!(lineage.dataset_namespace.as_deref(), Some("iceberg.prod"));
98
114
  }
99
115
 
100
116
  #[test]
@@ -180,7 +196,9 @@ entities:
180
196
  let path = write_temp_config(base);
181
197
  let profile_lineage = LineageConfig {
182
198
  url: "http://localhost:5000".to_string(),
199
+ endpoint: None,
183
200
  namespace: "floe-demo-local".to_string(),
201
+ dataset_namespace: None,
184
202
  api_key: None,
185
203
  timeout_secs: Some(2),
186
204
  producer: None,
@@ -88,6 +88,85 @@ entities:
88
88
  );
89
89
  }
90
90
 
91
+ #[test]
92
+ fn env_vars_apply_to_lineage_endpoint_and_dataset_namespace() {
93
+ let root = temp_dir("floe-lineage-vars");
94
+ let config_yaml = format!(
95
+ r#"version: "0.1"
96
+ env:
97
+ vars:
98
+ LINEAGE_ENDPOINT: "api/v1/openlineage/lineage"
99
+ DATASET_NAMESPACE: "iceberg.prod"
100
+ lineage:
101
+ url: "http://openmetadata:8585"
102
+ endpoint: "{{{{LINEAGE_ENDPOINT}}}}"
103
+ namespace: "dagster"
104
+ dataset_namespace: "{{{{DATASET_NAMESPACE}}}}"
105
+ entities:
106
+ - name: "orders"
107
+ source:
108
+ format: "csv"
109
+ path: "{root}/in/orders.csv"
110
+ sink:
111
+ accepted:
112
+ format: "parquet"
113
+ path: "{root}/out/orders"
114
+ policy:
115
+ severity: "warn"
116
+ schema:
117
+ columns:
118
+ - name: "id"
119
+ type: "string"
120
+ "#,
121
+ root = root.display(),
122
+ );
123
+ let config_path = write_config(&root, &config_yaml);
124
+ let parsed = load_config(&config_path).expect("parse config");
125
+ let lineage = parsed.lineage.expect("lineage");
126
+
127
+ assert_eq!(
128
+ lineage.endpoint.as_deref(),
129
+ Some("api/v1/openlineage/lineage")
130
+ );
131
+ assert_eq!(lineage.dataset_namespace.as_deref(), Some("iceberg.prod"));
132
+ }
133
+
134
+ #[test]
135
+ fn unresolved_lineage_placeholder_errors() {
136
+ let root = temp_dir("floe-lineage-unresolved");
137
+ let config_yaml = format!(
138
+ r#"version: "0.1"
139
+ lineage:
140
+ url: "http://openmetadata:8585"
141
+ endpoint: "{{{{OPENLINEAGE_ENDPOINT}}}}"
142
+ namespace: "dagster"
143
+ entities:
144
+ - name: "orders"
145
+ source:
146
+ format: "csv"
147
+ path: "{root}/in/orders.csv"
148
+ sink:
149
+ accepted:
150
+ format: "parquet"
151
+ path: "{root}/out/orders"
152
+ policy:
153
+ severity: "warn"
154
+ schema:
155
+ columns:
156
+ - name: "id"
157
+ type: "string"
158
+ "#,
159
+ root = root.display(),
160
+ );
161
+ let config_path = write_config(&root, &config_yaml);
162
+
163
+ let err = load_config(&config_path).expect_err("placeholder error");
164
+ assert_eq!(
165
+ err.to_string(),
166
+ "lineage.endpoint references unknown variable OPENLINEAGE_ENDPOINT"
167
+ );
168
+ }
169
+
91
170
  #[test]
92
171
  fn env_file_vars_apply_to_source_path() {
93
172
  let root = temp_dir("floe-env-file");
@@ -1,6 +1,6 @@
1
1
  use std::path::Path;
2
2
 
3
- use floe_core::io::storage::s3::parse_s3_uri;
3
+ use floe_core::io::storage::s3::{parse_s3_uri, resolve_path_style_access_from_env};
4
4
  use floe_core::io::storage::{filter_by_suffixes, stable_sort_refs, temp_path_for_key, ObjectRef};
5
5
 
6
6
  #[test]
@@ -17,6 +17,27 @@ fn parse_s3_uri_allows_bucket_only() {
17
17
  assert_eq!(loc.key, "");
18
18
  }
19
19
 
20
+ #[test]
21
+ fn path_style_access_prefers_explicit_config() {
22
+ let resolve = resolve_path_style_access_from_env;
23
+
24
+ assert!(resolve(Some(true), None));
25
+ assert!(resolve(Some(true), Some("false")));
26
+ assert!(!resolve(Some(false), Some("true")));
27
+ }
28
+
29
+ #[test]
30
+ fn path_style_access_falls_back_to_aws_env_convention() {
31
+ let resolve = resolve_path_style_access_from_env;
32
+
33
+ assert!(!resolve(None, None));
34
+ assert!(resolve(None, Some("true")));
35
+ assert!(resolve(None, Some("1")));
36
+ assert!(resolve(None, Some(" TRUE ")));
37
+ assert!(!resolve(None, Some("false")));
38
+ assert!(!resolve(None, Some("garbage")));
39
+ }
40
+
20
41
  #[test]
21
42
  fn filter_keys_by_suffix_sorts_and_filters() {
22
43
  let refs = vec![
@@ -9,15 +9,34 @@ use serde_json::json;
9
9
  fn make_config(server_url: &str, max_failures: Option<u32>) -> LineageConfig {
10
10
  LineageConfig {
11
11
  url: server_url.to_string(),
12
+ endpoint: None,
12
13
  api_key: None,
13
14
  timeout_secs: Some(2),
14
15
  namespace: "test-ns".to_string(),
16
+ dataset_namespace: None,
15
17
  producer: None,
16
18
  max_failures,
17
19
  job_name: None,
18
20
  }
19
21
  }
20
22
 
23
+ #[test]
24
+ fn custom_endpoint_is_used_for_posts() {
25
+ let mut server = mockito::Server::new();
26
+ let mock = server
27
+ .mock("POST", "/api/v1/openlineage/lineage")
28
+ .with_status(200)
29
+ .expect(1)
30
+ .create();
31
+
32
+ let mut config = make_config(&format!("{}/", server.url()), None);
33
+ config.endpoint = Some("/api/v1/openlineage/lineage".to_string());
34
+ let obs = OpenLineageObserver::new(&config, &[], "config.yml").unwrap();
35
+
36
+ obs.on_event(run_started_event());
37
+ mock.assert();
38
+ }
39
+
21
40
  fn run_started_event() -> RunEvent {
22
41
  RunEvent::RunStarted {
23
42
  run_id: "test-run-1".to_string(),
@@ -987,7 +1006,8 @@ fn iceberg_accepted_uses_catalog_namespace_and_table_name() {
987
1006
  .match_body(mockito::Matcher::PartialJson(json!({
988
1007
  "eventType": "COMPLETE",
989
1008
  "inputs": [{ "namespace": "s3://iceberg-data", "name": "bronze/sales/customers" }],
990
- "outputs": [{ "namespace": "test-ns", "name": "sales_dev.customers" }]
1009
+ "job": { "namespace": "test-ns" },
1010
+ "outputs": [{ "namespace": "iceberg.prod", "name": "sales_dev.customers" }]
991
1011
  })))
992
1012
  .with_status(200)
993
1013
  .expect(1)
@@ -1006,7 +1026,8 @@ fn iceberg_accepted_uses_catalog_namespace_and_table_name() {
1006
1026
  location: None,
1007
1027
  });
1008
1028
 
1009
- let config = make_config(&server.url(), None);
1029
+ let mut config = make_config(&server.url(), None);
1030
+ config.dataset_namespace = Some("iceberg.prod".to_string());
1010
1031
  let obs = OpenLineageObserver::new(&config, &[entity], "config.yml").unwrap();
1011
1032
 
1012
1033
  obs.on_event(RunEvent::EntityStarted {
@@ -1031,3 +1052,43 @@ fn iceberg_accepted_uses_catalog_namespace_and_table_name() {
1031
1052
  _start_mock.assert();
1032
1053
  _complete_mock.assert();
1033
1054
  }
1055
+
1056
+ #[test]
1057
+ fn iceberg_accepted_dataset_namespace_defaults_to_job_namespace() {
1058
+ let mut server = mockito::Server::new();
1059
+ let _start_mock = server
1060
+ .mock("POST", "/api/v1/lineage")
1061
+ .with_status(200)
1062
+ .expect(1)
1063
+ .create();
1064
+ let _complete_mock = server
1065
+ .mock("POST", "/api/v1/lineage")
1066
+ .match_body(mockito::Matcher::PartialJson(json!({
1067
+ "eventType": "COMPLETE",
1068
+ "job": { "namespace": "test-ns" },
1069
+ "outputs": [{ "namespace": "test-ns", "name": "sales_dev.customers" }]
1070
+ })))
1071
+ .with_status(200)
1072
+ .expect(1)
1073
+ .create();
1074
+
1075
+ let mut entity = make_entity(
1076
+ "customers",
1077
+ "s3://iceberg-data/bronze/sales/customers",
1078
+ "s3://warehouse/silver/customers",
1079
+ None,
1080
+ );
1081
+ entity.sink.accepted.iceberg = Some(IcebergSinkTargetConfig {
1082
+ catalog: None,
1083
+ namespace: Some("sales_dev".to_string()),
1084
+ table: Some("customers".to_string()),
1085
+ location: None,
1086
+ });
1087
+
1088
+ let config = make_config(&server.url(), None);
1089
+ let obs = OpenLineageObserver::new(&config, &[entity], "config.yml").unwrap();
1090
+ obs.on_event(entity_started_event());
1091
+ obs.on_event(entity_finished_event("customers", "success"));
1092
+ _start_mock.assert();
1093
+ _complete_mock.assert();
1094
+ }
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "floe-python"
3
- version = "0.6.7"
3
+ version = "0.6.9"
4
4
  edition = "2021"
5
5
  description = "Python bindings for floe-core (PyO3-based)"
6
6
  license = "Apache-2.0"
@@ -14,7 +14,7 @@ name = "_floe"
14
14
  crate-type = ["cdylib"]
15
15
 
16
16
  [dependencies]
17
- floe-core = { path = "../floe-core", version = "0.6.7", default-features = false }
17
+ floe-core = { path = "../floe-core", version = "0.6.9", default-features = false }
18
18
  pyo3 = { version = "0.29", features = ["extension-module", "abi3-py310"] }
19
19
  serde_json = "1"
20
20
 
@@ -22,7 +22,7 @@ build-backend = "maturin"
22
22
 
23
23
  [project]
24
24
  name = "floe-duckdb"
25
- version = "0.6.7"
25
+ version = "0.6.9"
26
26
  description = "DuckDB companion extension for floe — adds the native DuckDB sink to the floe Python package"
27
27
  readme = "README.md"
28
28
  requires-python = ">=3.10"
@@ -46,7 +46,7 @@ classifiers = [
46
46
  # only contributes the compiled DuckDB extension module into that package. Pin to
47
47
  # the exact lean version so the companion's `_floe_duckdb` ABI always matches the
48
48
  # `floe` package it plugs into.
49
- dependencies = ["floe-python==0.6.7"]
49
+ dependencies = ["floe-python==0.6.9"]
50
50
 
51
51
  [project.urls]
52
52
  Homepage = "https://github.com/malon64/floe"
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "floe-python"
7
- version = "0.6.7"
7
+ version = "0.6.9"
8
8
  description = "Python bindings for floe-core — run floe pipelines at Rust speed from Python and notebooks"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
File without changes
File without changes