floe-python 0.6.10__tar.gz → 0.6.11__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.
- {floe_python-0.6.10 → floe_python-0.6.11}/Cargo.lock +3 -3
- {floe_python-0.6.10 → floe_python-0.6.11}/PKG-INFO +1 -1
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/Cargo.toml +1 -1
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/lineage/mod.rs +17 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/manifest/reconstruct.rs +69 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/lineage.rs +226 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/Cargo.toml +2 -2
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/pyproject.duckdb.toml +2 -2
- {floe_python-0.6.10 → floe_python-0.6.11}/pyproject.toml +1 -1
- {floe_python-0.6.10 → floe_python-0.6.11}/Cargo.toml +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/README.md +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/README.md +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/add_entity.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/checks/cast.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/checks/mismatch.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/checks/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/checks/normalize.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/checks/not_null.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/checks/unique.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/config/catalog.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/config/location.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/config/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/config/parse.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/config/storage.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/config/template.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/config/types.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/config/validate.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/config/yaml_decode.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/errors.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/format.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/read/avro.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/read/csv.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/read/fixed_width.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/read/json.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/read/json_selector.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/read/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/read/orc.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/read/parquet.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/read/xlsx.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/read/xml.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/read/xml_selector.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/core/extensions.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/core/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/core/paths.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/core/placement.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/core/planner.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/core/uri.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/core/validation.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/object_store.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/ops/archive.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/ops/inputs.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/ops/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/ops/output.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/providers/adls.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/providers/gcs.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/providers/local.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/providers/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/providers/s3.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/target.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/unique_seed/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/accepted.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/arrow_convert.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/csv.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/delta/commit_metrics.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/delta/options.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/delta/record_batch.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/delta/unity.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/delta/unity_tests.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/delta.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/duckdb/conn.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/duckdb/merge.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/duckdb.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/iceberg/context.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/iceberg/data_files.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/iceberg/glue.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/iceberg/metadata.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/iceberg/rest.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/iceberg/schema.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/iceberg.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/metrics.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/parquet.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/parts.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/sink_format.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/append.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/merge/keys.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/merge/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/merge/scd1.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/merge/scd2.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/merge/shared.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/overwrite.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/lib.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/log.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/manifest/builder.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/manifest/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/manifest/model.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/manifest/runtime.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/profile/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/profile/parse.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/profile/types.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/profile/validate.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/report/build.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/report/entity.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/report/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/report/output.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/context.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/entity/accepted_buffer.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/entity/accepted_write.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/entity/incremental.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/entity/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/entity/pii.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/entity/precheck.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/entity/process.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/entity/resolve.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/entity/validate_split.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/events.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/file.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/output.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/run/perf.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/runner/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/runner/outcome.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/runtime.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/secret.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/state/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/vars/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/vars/resolve.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/warnings.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/archive_run.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/composite_unique.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/delta_run.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/dry_run.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/duckdb_run.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/fixed_width.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/iceberg_gcs_run.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/iceberg_glue_run.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/iceberg_run.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/iceberg_s3_run.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/json_selectors.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/local_run.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/path_normalization.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration/run_entities_filter.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/integration.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/common.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/add_entity.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/adls_storage.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/adls_validation.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/catalogs.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/config_validation.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/duckdb_validation.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/gcs_storage.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/gcs_validation.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/lineage_validation.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/local_storage.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/location.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/parse.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/pii_validation.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/remote_base.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/storage_resolver_uri.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/config/templating.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/format.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/avro_input.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/csv_nulls.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/json_array.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/json_ndjson.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/json_selector.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/orc_input.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/parquet_input.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/tsv.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/xlsx_input.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/xml.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/read/xml_selector.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/storage/adls.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/storage/adls_integration.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/storage/gcs.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/storage/inputs.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/storage/local.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/storage/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/storage/paths.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/storage/planner.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/storage/s3.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/storage/target.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/write/delta_merge.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/write/delta_write.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/write/iceberg_write.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/write/metrics.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/write/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/write/object_store.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/write/parquet_write.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/write/parts.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/io/write/rejected_csv.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/manifest/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/manifest/runtime.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/profile/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/profile/parse.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/profile/validate.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/report/accepted_output.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/report/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/report/storage.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/check_order.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/checks.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/entity/accepted_output.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/entity/incremental.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/entity/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/normalize.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/pii.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/replay_base.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/report.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/run/schema_mismatch.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/runner/adapter.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/runner/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/state/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/vars/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit/vars/resolve.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/tests/unit.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/.gitignore +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/README.md +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/src/functions.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/src/lib.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/src/observer.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/src/types/config.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/src/types/errors.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/src/types/mod.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/src/types/outcome.rs +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/tests/fixtures/config.yml +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/tests/fixtures/in/customer/customers_valid.csv +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/tests/fixtures/invalid_config.yml +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/tests/fixtures/profile.yml +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-python/tests/test_floe.py +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/python/floe/__init__.py +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/python/floe/_floe.pyi +0 -0
- {floe_python-0.6.10 → floe_python-0.6.11}/python/floe/py.typed +0 -0
|
@@ -3340,7 +3340,7 @@ dependencies = [
|
|
|
3340
3340
|
|
|
3341
3341
|
[[package]]
|
|
3342
3342
|
name = "floe-cli"
|
|
3343
|
-
version = "0.6.
|
|
3343
|
+
version = "0.6.11"
|
|
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.
|
|
3356
|
+
version = "0.6.11"
|
|
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.
|
|
3402
|
+
version = "0.6.11"
|
|
3403
3403
|
dependencies = [
|
|
3404
3404
|
"floe-core",
|
|
3405
3405
|
"pyo3",
|
|
@@ -635,6 +635,23 @@ pub fn build_observer(
|
|
|
635
635
|
Ok(Arc::new(obs))
|
|
636
636
|
}
|
|
637
637
|
|
|
638
|
+
/// Build a lineage observer for a `--manifest` replay from the manifest's
|
|
639
|
+
/// embedded lineage block and its entities' resolved cloud datasets, so replay
|
|
640
|
+
/// emits the same input/output lineage as a direct config run. `Ok(None)` when
|
|
641
|
+
/// the manifest has no `lineage` block. See
|
|
642
|
+
/// [`crate::manifest::reconstruct::lineage_inputs_from_manifest_json`].
|
|
643
|
+
pub fn build_observer_from_manifest_json(
|
|
644
|
+
manifest_json: &str,
|
|
645
|
+
config_path: &str,
|
|
646
|
+
) -> crate::FloeResult<Option<Arc<dyn RunObserver>>> {
|
|
647
|
+
match crate::manifest::reconstruct::lineage_inputs_from_manifest_json(manifest_json)? {
|
|
648
|
+
Some((lineage_cfg, entities)) => {
|
|
649
|
+
build_observer(&lineage_cfg, &entities, config_path).map(Some)
|
|
650
|
+
}
|
|
651
|
+
None => Ok(None),
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
638
655
|
impl OpenLineageObserver {
|
|
639
656
|
pub fn is_circuit_open(&self) -> bool {
|
|
640
657
|
self.circuit_open.load(Ordering::Relaxed)
|
|
@@ -56,6 +56,10 @@ pub struct ManifestSinksForRun {
|
|
|
56
56
|
pub struct ManifestSinkTargetForRun {
|
|
57
57
|
pub format: String,
|
|
58
58
|
pub storage: String,
|
|
59
|
+
/// Resolved cloud URI (e.g. `s3://bucket/key`). Optional so hand-authored
|
|
60
|
+
/// manifests that omit it still parse; the generator always writes it.
|
|
61
|
+
#[serde(default)]
|
|
62
|
+
pub uri: Option<String>,
|
|
59
63
|
pub path: String,
|
|
60
64
|
pub options: Option<serde_json::Value>,
|
|
61
65
|
pub partition_by: Option<Vec<String>>,
|
|
@@ -172,6 +176,71 @@ pub fn config_from_manifest_json(json: &str) -> FloeResult<(crate::config::RootC
|
|
|
172
176
|
Ok((config, manifest.report_base_uri))
|
|
173
177
|
}
|
|
174
178
|
|
|
179
|
+
/// Reconstruct the lineage config and entities for a `--manifest` replay's
|
|
180
|
+
/// OpenLineage observer, with each source/sink dataset path resolved to the
|
|
181
|
+
/// manifest's cloud `uri`.
|
|
182
|
+
///
|
|
183
|
+
/// The run reconstruction (`config_from_manifest_json`) intentionally keeps the
|
|
184
|
+
/// raw `path` fields — in the default manifest path mode those hold the original
|
|
185
|
+
/// config paths (e.g. `sales/orders`) while the resolved cloud identity lives in
|
|
186
|
+
/// `uri` (e.g. `s3://bucket/sales/orders`). The observer derives a dataset's
|
|
187
|
+
/// namespace/name from the path, so for lineage it must see the resolved cloud
|
|
188
|
+
/// URI; otherwise a named S3/GCS/ABFS source is reported under the `file`
|
|
189
|
+
/// namespace. Local and relative paths are left as reconstructed.
|
|
190
|
+
///
|
|
191
|
+
/// Returns `Ok(None)` when the manifest has no `lineage` block.
|
|
192
|
+
pub fn lineage_inputs_from_manifest_json(
|
|
193
|
+
json: &str,
|
|
194
|
+
) -> FloeResult<Option<(LineageConfig, Vec<EntityConfig>)>> {
|
|
195
|
+
let manifest: ManifestForRun =
|
|
196
|
+
serde_json::from_str(json).map_err(|err| -> Box<dyn std::error::Error + Send + Sync> {
|
|
197
|
+
FloeError::config(format!("manifest parse error: {err}")).into()
|
|
198
|
+
})?;
|
|
199
|
+
|
|
200
|
+
let lineage = match deserialize_manifest_section::<LineageConfig>(
|
|
201
|
+
manifest.lineage.as_ref(),
|
|
202
|
+
"lineage",
|
|
203
|
+
)? {
|
|
204
|
+
Some(lineage) => lineage,
|
|
205
|
+
None => return Ok(None),
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
let mut entities = manifest
|
|
209
|
+
.entities
|
|
210
|
+
.iter()
|
|
211
|
+
.map(entity_from_manifest)
|
|
212
|
+
.collect::<FloeResult<Vec<_>>>()?;
|
|
213
|
+
|
|
214
|
+
// Reconstructed entities are in manifest order, so zip pairs each with its
|
|
215
|
+
// source manifest entry to overlay the resolved cloud URIs.
|
|
216
|
+
for (entity, m) in entities.iter_mut().zip(manifest.entities.iter()) {
|
|
217
|
+
overlay_cloud_uri(&mut entity.source.path, Some(m.source.uri.as_str()));
|
|
218
|
+
overlay_cloud_uri(
|
|
219
|
+
&mut entity.sink.accepted.path,
|
|
220
|
+
m.sinks.accepted.uri.as_deref(),
|
|
221
|
+
);
|
|
222
|
+
if let (Some(rejected), Some(m_rejected)) =
|
|
223
|
+
(entity.sink.rejected.as_mut(), m.sinks.rejected.as_ref())
|
|
224
|
+
{
|
|
225
|
+
overlay_cloud_uri(&mut rejected.path, m_rejected.uri.as_deref());
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
Ok(Some((lineage, entities)))
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/// Replace `path` with `uri` when `uri` names a cloud object store; other
|
|
233
|
+
/// schemes (local / relative) keep the reconstructed path. The prefix list
|
|
234
|
+
/// mirrors `lineage::split_storage_uri` and must stay in sync with it.
|
|
235
|
+
fn overlay_cloud_uri(path: &mut String, uri: Option<&str>) {
|
|
236
|
+
const CLOUD_SCHEMES: [&str; 6] = ["s3://", "gs://", "gcs://", "az://", "abfss://", "abfs://"];
|
|
237
|
+
if let Some(uri) = uri {
|
|
238
|
+
if CLOUD_SCHEMES.iter().any(|scheme| uri.starts_with(scheme)) {
|
|
239
|
+
*path = uri.to_string();
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
175
244
|
fn entity_from_manifest(m: &ManifestEntityForRun) -> FloeResult<EntityConfig> {
|
|
176
245
|
let policy_severity = parse_policy_severity(m.policy_severity.as_deref().unwrap_or("warn"));
|
|
177
246
|
let write_mode = parse_write_mode(m.write_mode.as_deref().unwrap_or("overwrite"));
|
|
@@ -1157,3 +1157,229 @@ fn api_key_resolution_over_the_wire() {
|
|
|
1157
1157
|
|
|
1158
1158
|
std::env::remove_var("OPENLINEAGE_API_KEY");
|
|
1159
1159
|
}
|
|
1160
|
+
|
|
1161
|
+
// ---- Manifest-replay dataset lineage (issue #455) ----
|
|
1162
|
+
// build_observer_from_manifest_json must feed the manifest's entities and their
|
|
1163
|
+
// resolved cloud URIs to the observer so replay emits non-empty inputs/outputs.
|
|
1164
|
+
|
|
1165
|
+
fn replay_entity(name: &str, source_uri: &str, accepted_uri: &str) -> serde_json::Value {
|
|
1166
|
+
json!({
|
|
1167
|
+
"name": name,
|
|
1168
|
+
"source": { "format": "csv", "storage": "bronze", "uri": source_uri, "path": source_uri },
|
|
1169
|
+
"sinks": {
|
|
1170
|
+
"accepted": {
|
|
1171
|
+
"format": "parquet",
|
|
1172
|
+
"storage": "warehouse",
|
|
1173
|
+
"uri": accepted_uri,
|
|
1174
|
+
"path": accepted_uri
|
|
1175
|
+
}
|
|
1176
|
+
},
|
|
1177
|
+
"schema": { "columns": [], "primary_key": [], "unique_keys": [] }
|
|
1178
|
+
})
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
fn replay_manifest(server_url: &str, entities: serde_json::Value) -> String {
|
|
1182
|
+
json!({
|
|
1183
|
+
"spec_version": "0.3",
|
|
1184
|
+
"report_base_uri": "file:///tmp",
|
|
1185
|
+
"entities": entities,
|
|
1186
|
+
"lineage": { "url": server_url, "namespace": "test-ns" }
|
|
1187
|
+
})
|
|
1188
|
+
.to_string()
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
fn entity_started(name: &str) -> RunEvent {
|
|
1192
|
+
RunEvent::EntityStarted {
|
|
1193
|
+
run_id: "test-run-1".to_string(),
|
|
1194
|
+
name: name.to_string(),
|
|
1195
|
+
ts_ms: 1_001_000,
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
// Replaying a manifest with an entity emits the entity's source input and
|
|
1200
|
+
// accepted output — the regression from issue #455. With entities dropped
|
|
1201
|
+
// (the previous `&[]`), inputs/outputs would be empty and the subset match on
|
|
1202
|
+
// inputs[0]/outputs[0] would fail.
|
|
1203
|
+
#[test]
|
|
1204
|
+
fn manifest_replay_passes_entities_to_observer() {
|
|
1205
|
+
let mut server = mockito::Server::new();
|
|
1206
|
+
|
|
1207
|
+
let start_mock = server
|
|
1208
|
+
.mock("POST", "/api/v1/lineage")
|
|
1209
|
+
.match_body(mockito::Matcher::PartialJson(
|
|
1210
|
+
json!({ "eventType": "START" }),
|
|
1211
|
+
))
|
|
1212
|
+
.with_status(200)
|
|
1213
|
+
.expect(1)
|
|
1214
|
+
.create();
|
|
1215
|
+
|
|
1216
|
+
let complete_mock = server
|
|
1217
|
+
.mock("POST", "/api/v1/lineage")
|
|
1218
|
+
.match_body(mockito::Matcher::PartialJson(json!({
|
|
1219
|
+
"eventType": "COMPLETE",
|
|
1220
|
+
"inputs": [{
|
|
1221
|
+
"namespace": "s3://lakehouse-bronze",
|
|
1222
|
+
"name": "sales/customer_health/support_tickets"
|
|
1223
|
+
}],
|
|
1224
|
+
"outputs": [{
|
|
1225
|
+
"namespace": "s3://lakehouse-warehouse",
|
|
1226
|
+
"name": "silver/support_tickets"
|
|
1227
|
+
}]
|
|
1228
|
+
})))
|
|
1229
|
+
.with_status(200)
|
|
1230
|
+
.expect(1)
|
|
1231
|
+
.create();
|
|
1232
|
+
|
|
1233
|
+
let manifest = replay_manifest(
|
|
1234
|
+
&server.url(),
|
|
1235
|
+
json!([replay_entity(
|
|
1236
|
+
"support_tickets",
|
|
1237
|
+
"s3://lakehouse-bronze/sales/customer_health/support_tickets",
|
|
1238
|
+
"s3://lakehouse-warehouse/silver/support_tickets",
|
|
1239
|
+
)]),
|
|
1240
|
+
);
|
|
1241
|
+
|
|
1242
|
+
let obs = floe_core::lineage::build_observer_from_manifest_json(&manifest, "")
|
|
1243
|
+
.expect("observer builds from manifest")
|
|
1244
|
+
.expect("manifest has a lineage block => Some observer");
|
|
1245
|
+
|
|
1246
|
+
obs.on_event(entity_started("support_tickets"));
|
|
1247
|
+
obs.on_event(entity_finished_event("support_tickets", "success"));
|
|
1248
|
+
|
|
1249
|
+
start_mock.assert();
|
|
1250
|
+
complete_mock.assert();
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
// Default manifest path mode records raw config paths in `path` and the resolved
|
|
1254
|
+
// cloud identity in `uri`. Lineage must report the cloud dataset from `uri`, not
|
|
1255
|
+
// a `file` namespace derived from the raw path (PR #456 review).
|
|
1256
|
+
#[test]
|
|
1257
|
+
fn manifest_replay_default_path_mode_uses_resolved_cloud_uri() {
|
|
1258
|
+
let mut server = mockito::Server::new();
|
|
1259
|
+
|
|
1260
|
+
let start_mock = server
|
|
1261
|
+
.mock("POST", "/api/v1/lineage")
|
|
1262
|
+
.match_body(mockito::Matcher::PartialJson(
|
|
1263
|
+
json!({ "eventType": "START" }),
|
|
1264
|
+
))
|
|
1265
|
+
.with_status(200)
|
|
1266
|
+
.expect(1)
|
|
1267
|
+
.create();
|
|
1268
|
+
|
|
1269
|
+
let complete_mock = server
|
|
1270
|
+
.mock("POST", "/api/v1/lineage")
|
|
1271
|
+
.match_body(mockito::Matcher::PartialJson(json!({
|
|
1272
|
+
"eventType": "COMPLETE",
|
|
1273
|
+
"inputs": [{ "namespace": "s3://lakehouse-bronze", "name": "sales/orders" }],
|
|
1274
|
+
"outputs": [{ "namespace": "s3://lakehouse-warehouse", "name": "silver/orders" }]
|
|
1275
|
+
})))
|
|
1276
|
+
.with_status(200)
|
|
1277
|
+
.expect(1)
|
|
1278
|
+
.create();
|
|
1279
|
+
|
|
1280
|
+
// path = raw config paths (default mode); uri = resolved cloud identities.
|
|
1281
|
+
let entity = json!({
|
|
1282
|
+
"name": "orders",
|
|
1283
|
+
"source": {
|
|
1284
|
+
"format": "csv",
|
|
1285
|
+
"storage": "bronze",
|
|
1286
|
+
"uri": "s3://lakehouse-bronze/sales/orders",
|
|
1287
|
+
"path": "sales/orders"
|
|
1288
|
+
},
|
|
1289
|
+
"sinks": {
|
|
1290
|
+
"accepted": {
|
|
1291
|
+
"format": "parquet",
|
|
1292
|
+
"storage": "warehouse",
|
|
1293
|
+
"uri": "s3://lakehouse-warehouse/silver/orders",
|
|
1294
|
+
"path": "silver/orders"
|
|
1295
|
+
}
|
|
1296
|
+
},
|
|
1297
|
+
"schema": { "columns": [], "primary_key": [], "unique_keys": [] }
|
|
1298
|
+
});
|
|
1299
|
+
let manifest = replay_manifest(&server.url(), json!([entity]));
|
|
1300
|
+
|
|
1301
|
+
let obs = floe_core::lineage::build_observer_from_manifest_json(&manifest, "")
|
|
1302
|
+
.expect("observer builds from manifest")
|
|
1303
|
+
.expect("manifest has a lineage block => Some observer");
|
|
1304
|
+
|
|
1305
|
+
obs.on_event(entity_started("orders"));
|
|
1306
|
+
obs.on_event(entity_finished_event("orders", "success"));
|
|
1307
|
+
|
|
1308
|
+
start_mock.assert();
|
|
1309
|
+
complete_mock.assert();
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
// Firing events for only the selected entity (as `--entities orders` does)
|
|
1313
|
+
// still carries that entity's dataset context, because the observer holds all
|
|
1314
|
+
// manifest entities keyed by name.
|
|
1315
|
+
#[test]
|
|
1316
|
+
fn manifest_replay_entity_selection_keeps_dataset_context() {
|
|
1317
|
+
let mut server = mockito::Server::new();
|
|
1318
|
+
|
|
1319
|
+
let start_mock = server
|
|
1320
|
+
.mock("POST", "/api/v1/lineage")
|
|
1321
|
+
.match_body(mockito::Matcher::PartialJson(
|
|
1322
|
+
json!({ "eventType": "START" }),
|
|
1323
|
+
))
|
|
1324
|
+
.with_status(200)
|
|
1325
|
+
.expect(1)
|
|
1326
|
+
.create();
|
|
1327
|
+
|
|
1328
|
+
let complete_mock = server
|
|
1329
|
+
.mock("POST", "/api/v1/lineage")
|
|
1330
|
+
.match_body(mockito::Matcher::PartialJson(json!({
|
|
1331
|
+
"eventType": "COMPLETE",
|
|
1332
|
+
"inputs": [{ "namespace": "s3://lakehouse-bronze", "name": "sales/orders" }],
|
|
1333
|
+
"outputs": [{ "namespace": "s3://lakehouse-warehouse", "name": "silver/orders" }]
|
|
1334
|
+
})))
|
|
1335
|
+
.with_status(200)
|
|
1336
|
+
.expect(1)
|
|
1337
|
+
.create();
|
|
1338
|
+
|
|
1339
|
+
let manifest = replay_manifest(
|
|
1340
|
+
&server.url(),
|
|
1341
|
+
json!([
|
|
1342
|
+
replay_entity(
|
|
1343
|
+
"orders",
|
|
1344
|
+
"s3://lakehouse-bronze/sales/orders",
|
|
1345
|
+
"s3://lakehouse-warehouse/silver/orders",
|
|
1346
|
+
),
|
|
1347
|
+
replay_entity(
|
|
1348
|
+
"customers",
|
|
1349
|
+
"s3://lakehouse-bronze/sales/customers",
|
|
1350
|
+
"s3://lakehouse-warehouse/silver/customers",
|
|
1351
|
+
)
|
|
1352
|
+
]),
|
|
1353
|
+
);
|
|
1354
|
+
|
|
1355
|
+
let obs = floe_core::lineage::build_observer_from_manifest_json(&manifest, "")
|
|
1356
|
+
.expect("observer builds from manifest")
|
|
1357
|
+
.expect("manifest has a lineage block => Some observer");
|
|
1358
|
+
|
|
1359
|
+
// Only "orders" runs; "customers" is not selected.
|
|
1360
|
+
obs.on_event(entity_started("orders"));
|
|
1361
|
+
obs.on_event(entity_finished_event("orders", "success"));
|
|
1362
|
+
|
|
1363
|
+
start_mock.assert();
|
|
1364
|
+
complete_mock.assert();
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
// A manifest without a lineage block yields no observer (lineage disabled),
|
|
1368
|
+
// rather than erroring.
|
|
1369
|
+
#[test]
|
|
1370
|
+
fn manifest_replay_without_lineage_block_yields_no_observer() {
|
|
1371
|
+
let manifest = json!({
|
|
1372
|
+
"spec_version": "0.3",
|
|
1373
|
+
"report_base_uri": "file:///tmp",
|
|
1374
|
+
"entities": []
|
|
1375
|
+
})
|
|
1376
|
+
.to_string();
|
|
1377
|
+
|
|
1378
|
+
let obs = floe_core::lineage::build_observer_from_manifest_json(&manifest, "")
|
|
1379
|
+
.expect("no error when lineage block is absent");
|
|
1380
|
+
|
|
1381
|
+
assert!(
|
|
1382
|
+
obs.is_none(),
|
|
1383
|
+
"manifest without lineage block => no observer"
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "floe-python"
|
|
3
|
-
version = "0.6.
|
|
3
|
+
version = "0.6.11"
|
|
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.
|
|
17
|
+
floe-core = { path = "../floe-core", version = "0.6.11", 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.
|
|
25
|
+
version = "0.6.11"
|
|
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.
|
|
49
|
+
dependencies = ["floe-python==0.6.11"]
|
|
50
50
|
|
|
51
51
|
[project.urls]
|
|
52
52
|
Homepage = "https://github.com/malon64/floe"
|
|
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
|
{floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/core/extensions.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/core/validation.rs
RENAMED
|
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
|
{floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/storage/providers/local.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/delta/commit_metrics.rs
RENAMED
|
File without changes
|
|
File without changes
|
{floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/delta/record_batch.rs
RENAMED
|
File without changes
|
|
File without changes
|
{floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/delta/unity_tests.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/iceberg/data_files.rs
RENAMED
|
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
|
{floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/merge/keys.rs
RENAMED
|
File without changes
|
{floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/merge/mod.rs
RENAMED
|
File without changes
|
{floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/merge/scd1.rs
RENAMED
|
File without changes
|
{floe_python-0.6.10 → floe_python-0.6.11}/crates/floe-core/src/io/write/strategy/merge/scd2.rs
RENAMED
|
File without changes
|