floe-python 0.5.2__tar.gz → 0.5.4__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.5.2 → floe_python-0.5.4}/Cargo.lock +3 -3
- {floe_python-0.5.2 → floe_python-0.5.4}/PKG-INFO +1 -1
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/Cargo.toml +1 -1
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/lineage/mod.rs +73 -56
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/run/lineage.rs +182 -74
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/Cargo.toml +2 -2
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/pyproject.duckdb.toml +2 -2
- {floe_python-0.5.2 → floe_python-0.5.4}/pyproject.toml +1 -1
- {floe_python-0.5.2 → floe_python-0.5.4}/python/floe/__init__.py +26 -8
- {floe_python-0.5.2 → floe_python-0.5.4}/Cargo.toml +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/README.md +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/README.md +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/add_entity.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/checks/cast.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/checks/mismatch.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/checks/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/checks/normalize.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/checks/not_null.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/checks/unique.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/config/catalog.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/config/location.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/config/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/config/parse.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/config/storage.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/config/template.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/config/types.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/config/validate.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/config/yaml_decode.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/errors.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/format.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/read/avro.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/read/csv.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/read/fixed_width.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/read/json.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/read/json_selector.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/read/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/read/orc.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/read/parquet.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/read/xlsx.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/read/xml.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/read/xml_selector.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/core/extensions.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/core/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/core/paths.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/core/placement.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/core/planner.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/core/uri.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/core/validation.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/object_store.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/ops/archive.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/ops/inputs.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/ops/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/ops/output.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/providers/adls.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/providers/gcs.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/providers/local.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/providers/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/providers/s3.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/storage/target.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/unique_seed/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/accepted.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/arrow_convert.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/csv.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/delta/commit_metrics.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/delta/options.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/delta/record_batch.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/delta/unity.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/delta/unity_tests.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/delta.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/duckdb/conn.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/duckdb/merge.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/duckdb.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/iceberg/context.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/iceberg/data_files.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/iceberg/glue.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/iceberg/metadata.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/iceberg/rest.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/iceberg/schema.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/iceberg.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/metrics.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/parquet.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/parts.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/sink_format.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/strategy/append.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/strategy/merge/keys.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/strategy/merge/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/strategy/merge/scd1.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/strategy/merge/scd2.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/strategy/merge/shared.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/strategy/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/io/write/strategy/overwrite.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/lib.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/log.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/manifest/builder.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/manifest/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/manifest/model.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/manifest/reconstruct.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/profile/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/profile/parse.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/profile/types.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/profile/validate.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/report/build.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/report/entity.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/report/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/report/output.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/context.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/entity/accepted_buffer.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/entity/accepted_write.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/entity/incremental.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/entity/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/entity/pii.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/entity/precheck.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/entity/process.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/entity/resolve.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/entity/validate_split.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/events.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/file.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/output.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/run/perf.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/runner/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/runner/outcome.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/runtime.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/state/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/vars/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/vars/resolve.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/src/warnings.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/archive_run.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/composite_unique.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/delta_run.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/dry_run.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/duckdb_run.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/fixed_width.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/iceberg_gcs_run.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/iceberg_glue_run.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/iceberg_run.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/iceberg_s3_run.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/json_selectors.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/local_run.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/path_normalization.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration/run_entities_filter.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/integration.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/common.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/add_entity.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/adls_storage.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/adls_validation.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/catalogs.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/config_validation.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/duckdb_validation.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/gcs_storage.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/gcs_validation.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/lineage_validation.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/local_storage.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/parse.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/pii_validation.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/remote_base.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/storage_resolver_uri.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/config/templating.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/format.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/avro_input.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/csv_nulls.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/json_array.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/json_ndjson.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/json_selector.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/orc_input.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/parquet_input.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/tsv.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/xlsx_input.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/xml.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/read/xml_selector.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/storage/adls.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/storage/adls_integration.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/storage/gcs.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/storage/inputs.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/storage/local.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/storage/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/storage/paths.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/storage/planner.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/storage/s3.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/storage/target.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/write/delta_merge.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/write/delta_write.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/write/iceberg_write.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/write/metrics.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/write/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/write/object_store.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/write/parquet_write.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/write/parts.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/io/write/rejected_csv.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/manifest/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/profile/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/profile/parse.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/profile/validate.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/report/accepted_output.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/report/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/report/storage.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/run/check_order.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/run/checks.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/run/entity/accepted_output.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/run/entity/incremental.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/run/entity/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/run/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/run/normalize.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/run/pii.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/run/report.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/run/schema_mismatch.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/runner/adapter.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/runner/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/state/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/vars/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit/vars/resolve.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-core/tests/unit.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/.gitignore +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/README.md +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/src/functions.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/src/lib.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/src/observer.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/src/types/config.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/src/types/errors.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/src/types/mod.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/src/types/outcome.rs +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/tests/fixtures/config.yml +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/tests/fixtures/in/customer/customers_valid.csv +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/tests/fixtures/invalid_config.yml +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/tests/fixtures/profile.yml +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/crates/floe-python/tests/test_floe.py +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/python/floe/_floe.pyi +0 -0
- {floe_python-0.5.2 → floe_python-0.5.4}/python/floe/py.typed +0 -0
|
@@ -3508,7 +3508,7 @@ dependencies = [
|
|
|
3508
3508
|
|
|
3509
3509
|
[[package]]
|
|
3510
3510
|
name = "floe-cli"
|
|
3511
|
-
version = "0.5.
|
|
3511
|
+
version = "0.5.4"
|
|
3512
3512
|
dependencies = [
|
|
3513
3513
|
"assert_cmd",
|
|
3514
3514
|
"clap",
|
|
@@ -3521,7 +3521,7 @@ dependencies = [
|
|
|
3521
3521
|
|
|
3522
3522
|
[[package]]
|
|
3523
3523
|
name = "floe-core"
|
|
3524
|
-
version = "0.5.
|
|
3524
|
+
version = "0.5.4"
|
|
3525
3525
|
dependencies = [
|
|
3526
3526
|
"apache-avro 0.16.0",
|
|
3527
3527
|
"arrow",
|
|
@@ -3565,7 +3565,7 @@ dependencies = [
|
|
|
3565
3565
|
|
|
3566
3566
|
[[package]]
|
|
3567
3567
|
name = "floe-python"
|
|
3568
|
-
version = "0.5.
|
|
3568
|
+
version = "0.5.4"
|
|
3569
3569
|
dependencies = [
|
|
3570
3570
|
"floe-core",
|
|
3571
3571
|
"pyo3",
|
|
@@ -4,6 +4,7 @@ use std::sync::{Arc, Mutex};
|
|
|
4
4
|
use std::time::Duration;
|
|
5
5
|
|
|
6
6
|
use serde_json::{json, Value};
|
|
7
|
+
use uuid::Uuid;
|
|
7
8
|
|
|
8
9
|
use crate::config::{EntityConfig, LineageConfig};
|
|
9
10
|
use crate::run::events::{RunEvent, RunObserver};
|
|
@@ -20,10 +21,15 @@ struct ColumnMapping {
|
|
|
20
21
|
source_field: Option<String>,
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
struct OlDataset {
|
|
25
|
+
namespace: String,
|
|
26
|
+
name: String,
|
|
27
|
+
}
|
|
28
|
+
|
|
23
29
|
struct EntityUris {
|
|
24
|
-
source:
|
|
25
|
-
accepted:
|
|
26
|
-
rejected: Option<
|
|
30
|
+
source: OlDataset,
|
|
31
|
+
accepted: OlDataset,
|
|
32
|
+
rejected: Option<OlDataset>,
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
pub struct OpenLineageObserver {
|
|
@@ -32,6 +38,7 @@ pub struct OpenLineageObserver {
|
|
|
32
38
|
entity_start_ms: Mutex<HashMap<String, u128>>,
|
|
33
39
|
entity_run_ids: Mutex<HashMap<String, String>>,
|
|
34
40
|
run_start_ms: Mutex<Option<u128>>,
|
|
41
|
+
run_uuid: Mutex<Option<String>>,
|
|
35
42
|
entity_schemas: HashMap<String, Vec<ColumnMapping>>,
|
|
36
43
|
entity_uris: HashMap<String, EntityUris>,
|
|
37
44
|
run_job_name: String,
|
|
@@ -87,12 +94,44 @@ impl OpenLineageObserver {
|
|
|
87
94
|
let entity_uris = entities
|
|
88
95
|
.iter()
|
|
89
96
|
.map(|e| {
|
|
97
|
+
let (src_ns, src_name) = split_storage_uri(&e.source.path);
|
|
98
|
+
let source = OlDataset {
|
|
99
|
+
namespace: src_ns,
|
|
100
|
+
name: src_name,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
let accepted = match e.sink.accepted.iceberg.as_ref() {
|
|
104
|
+
Some(iceberg) => {
|
|
105
|
+
let ns = iceberg.namespace.as_deref().unwrap_or(e.name.as_str());
|
|
106
|
+
let tbl = iceberg.table.as_deref().unwrap_or(e.name.as_str());
|
|
107
|
+
OlDataset {
|
|
108
|
+
namespace: config.namespace.clone(),
|
|
109
|
+
name: format!("{ns}.{tbl}"),
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
None => {
|
|
113
|
+
let (acc_ns, acc_name) = split_storage_uri(&e.sink.accepted.path);
|
|
114
|
+
OlDataset {
|
|
115
|
+
namespace: acc_ns,
|
|
116
|
+
name: acc_name,
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
let rejected = e.sink.rejected.as_ref().map(|r| {
|
|
122
|
+
let (rej_ns, rej_name) = split_storage_uri(&r.path);
|
|
123
|
+
OlDataset {
|
|
124
|
+
namespace: rej_ns,
|
|
125
|
+
name: rej_name,
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
90
129
|
(
|
|
91
130
|
e.name.clone(),
|
|
92
131
|
EntityUris {
|
|
93
|
-
source
|
|
94
|
-
accepted
|
|
95
|
-
rejected
|
|
132
|
+
source,
|
|
133
|
+
accepted,
|
|
134
|
+
rejected,
|
|
96
135
|
},
|
|
97
136
|
)
|
|
98
137
|
})
|
|
@@ -104,6 +143,7 @@ impl OpenLineageObserver {
|
|
|
104
143
|
entity_start_ms: Mutex::new(HashMap::new()),
|
|
105
144
|
entity_run_ids: Mutex::new(HashMap::new()),
|
|
106
145
|
run_start_ms: Mutex::new(None),
|
|
146
|
+
run_uuid: Mutex::new(None),
|
|
107
147
|
entity_schemas,
|
|
108
148
|
entity_uris,
|
|
109
149
|
run_job_name,
|
|
@@ -236,15 +276,12 @@ impl OpenLineageObserver {
|
|
|
236
276
|
uris: Option<&EntityUris>,
|
|
237
277
|
) {
|
|
238
278
|
let event_time = ms_to_iso8601(ts_ms);
|
|
239
|
-
let job_name = format!("{}.{name}", self.config.namespace);
|
|
240
279
|
|
|
241
280
|
let mut run_facets = json!({});
|
|
242
281
|
if let Some(parent) = self.parent_run_facet() {
|
|
243
282
|
run_facets["parent"] = parent;
|
|
244
283
|
}
|
|
245
284
|
|
|
246
|
-
// Build inputs/outputs based on whether stats and uris are present (COMPLETE/FAIL)
|
|
247
|
-
// or absent (START — keep both empty).
|
|
248
285
|
let (inputs, outputs) = match (stats.as_ref(), uris) {
|
|
249
286
|
(Some(s), Some(u)) => {
|
|
250
287
|
let rejection_rate = if s.rows > 0 {
|
|
@@ -253,18 +290,11 @@ impl OpenLineageObserver {
|
|
|
253
290
|
0.0
|
|
254
291
|
};
|
|
255
292
|
|
|
256
|
-
// Input: source dataset — sub-namespace avoids collision with real entity names.
|
|
257
|
-
let (src_ns, src_path) = split_storage_uri(&u.source);
|
|
258
293
|
let inputs = json!([{
|
|
259
|
-
"namespace":
|
|
260
|
-
"name": name
|
|
261
|
-
"facets": {
|
|
262
|
-
"symlinks": symlinks_facet(self.producer(), &src_ns, &src_path, "DIRECTORY")
|
|
263
|
-
}
|
|
294
|
+
"namespace": u.source.namespace,
|
|
295
|
+
"name": u.source.name
|
|
264
296
|
}]);
|
|
265
297
|
|
|
266
|
-
// Accepted output: entity name as logical identifier, TABLE type.
|
|
267
|
-
let (acc_ns, acc_path) = split_storage_uri(&u.accepted);
|
|
268
298
|
let schema_facet = json!({
|
|
269
299
|
"fields": s.schema_fields.iter().map(|col| {
|
|
270
300
|
json!({ "name": col.output_name, "type": col.column_type })
|
|
@@ -291,7 +321,6 @@ impl OpenLineageObserver {
|
|
|
291
321
|
});
|
|
292
322
|
|
|
293
323
|
let mut accepted_facets = json!({
|
|
294
|
-
"symlinks": symlinks_facet(self.producer(), &acc_ns, &acc_path, "TABLE"),
|
|
295
324
|
"schema": schema_facet,
|
|
296
325
|
"dataQualityMetrics": accepted_dq_facet,
|
|
297
326
|
"floeQualityRun": floe_facet
|
|
@@ -305,8 +334,8 @@ impl OpenLineageObserver {
|
|
|
305
334
|
let src = col.source_field.as_deref().unwrap_or(&col.output_name);
|
|
306
335
|
let entry = json!({
|
|
307
336
|
"inputFields": [{
|
|
308
|
-
"namespace":
|
|
309
|
-
"name": name,
|
|
337
|
+
"namespace": u.source.namespace,
|
|
338
|
+
"name": u.source.name,
|
|
310
339
|
"field": src
|
|
311
340
|
}]
|
|
312
341
|
});
|
|
@@ -321,14 +350,12 @@ impl OpenLineageObserver {
|
|
|
321
350
|
}
|
|
322
351
|
|
|
323
352
|
let mut out = vec![json!({
|
|
324
|
-
"namespace":
|
|
325
|
-
"name": name,
|
|
353
|
+
"namespace": u.accepted.namespace,
|
|
354
|
+
"name": u.accepted.name,
|
|
326
355
|
"facets": accepted_facets
|
|
327
356
|
})];
|
|
328
357
|
|
|
329
|
-
// Rejected output (when configured): DIRECTORY type, rejected-row quality metrics.
|
|
330
358
|
if let Some(ref rej) = u.rejected {
|
|
331
|
-
let (rej_ns, rej_path) = split_storage_uri(rej);
|
|
332
359
|
let rejected_dq_facet = json!({
|
|
333
360
|
"rowCount": s.rejected,
|
|
334
361
|
"validCount": 0u64,
|
|
@@ -337,10 +364,9 @@ impl OpenLineageObserver {
|
|
|
337
364
|
"_schemaURL": "https://openlineage.io/spec/facets/1-0-2/DataQualityMetricsOutputDatasetFacet.json"
|
|
338
365
|
});
|
|
339
366
|
out.push(json!({
|
|
340
|
-
"namespace":
|
|
341
|
-
"name": name,
|
|
367
|
+
"namespace": rej.namespace,
|
|
368
|
+
"name": rej.name,
|
|
342
369
|
"facets": {
|
|
343
|
-
"symlinks": symlinks_facet(self.producer(), &rej_ns, &rej_path, "DIRECTORY"),
|
|
344
370
|
"dataQualityMetrics": rejected_dq_facet
|
|
345
371
|
}
|
|
346
372
|
}));
|
|
@@ -360,7 +386,7 @@ impl OpenLineageObserver {
|
|
|
360
386
|
},
|
|
361
387
|
"job": {
|
|
362
388
|
"namespace": self.config.namespace,
|
|
363
|
-
"name":
|
|
389
|
+
"name": name,
|
|
364
390
|
"facets": {}
|
|
365
391
|
},
|
|
366
392
|
"inputs": inputs,
|
|
@@ -403,27 +429,19 @@ fn split_storage_uri(uri: &str) -> (String, String) {
|
|
|
403
429
|
if let Some(after_scheme) = uri.strip_prefix(prefix) {
|
|
404
430
|
if let Some(slash) = after_scheme.find('/') {
|
|
405
431
|
let authority = uri[..prefix.len() + slash].to_string();
|
|
406
|
-
let path = after_scheme[slash..].to_string();
|
|
432
|
+
let path = after_scheme[slash + 1..].to_string();
|
|
407
433
|
return (authority, path);
|
|
408
434
|
}
|
|
409
|
-
return (uri.to_string(),
|
|
435
|
+
return (uri.to_string(), String::new());
|
|
410
436
|
}
|
|
411
437
|
}
|
|
412
438
|
("file".to_string(), uri.to_string())
|
|
413
439
|
}
|
|
414
440
|
|
|
415
|
-
fn symlinks_facet(producer: &str, namespace: &str, name: &str, ds_type: &str) -> Value {
|
|
416
|
-
json!({
|
|
417
|
-
"identifiers": [{ "namespace": namespace, "name": name, "type": ds_type }],
|
|
418
|
-
"_producer": producer,
|
|
419
|
-
"_schemaURL": "https://openlineage.io/spec/facets/1-0-0/SymlinksDatasetFacet.json"
|
|
420
|
-
})
|
|
421
|
-
}
|
|
422
|
-
|
|
423
441
|
impl RunObserver for OpenLineageObserver {
|
|
424
442
|
fn on_event(&self, event: RunEvent) {
|
|
425
443
|
match event {
|
|
426
|
-
RunEvent::RunStarted {
|
|
444
|
+
RunEvent::RunStarted { ts_ms, .. } => {
|
|
427
445
|
// Reset circuit breaker at the start of each run so a recovered endpoint
|
|
428
446
|
// is retried in subsequent runs within the same long-lived process.
|
|
429
447
|
self.consecutive_failures.store(0, Ordering::Relaxed);
|
|
@@ -431,6 +449,10 @@ impl RunObserver for OpenLineageObserver {
|
|
|
431
449
|
if let Ok(mut guard) = self.run_start_ms.lock() {
|
|
432
450
|
*guard = Some(ts_ms);
|
|
433
451
|
}
|
|
452
|
+
let run_uuid = Uuid::new_v4().to_string();
|
|
453
|
+
if let Ok(mut guard) = self.run_uuid.lock() {
|
|
454
|
+
*guard = Some(run_uuid.clone());
|
|
455
|
+
}
|
|
434
456
|
let event_time = ms_to_iso8601(ts_ms);
|
|
435
457
|
let mut run_facets = json!({});
|
|
436
458
|
if let Some(parent) = self.parent_run_facet() {
|
|
@@ -440,7 +462,7 @@ impl RunObserver for OpenLineageObserver {
|
|
|
440
462
|
"eventType": "START",
|
|
441
463
|
"eventTime": event_time,
|
|
442
464
|
"run": {
|
|
443
|
-
"runId":
|
|
465
|
+
"runId": run_uuid,
|
|
444
466
|
"facets": run_facets
|
|
445
467
|
},
|
|
446
468
|
"job": {
|
|
@@ -455,14 +477,8 @@ impl RunObserver for OpenLineageObserver {
|
|
|
455
477
|
});
|
|
456
478
|
self.post_event(body);
|
|
457
479
|
}
|
|
458
|
-
RunEvent::EntityStarted {
|
|
459
|
-
|
|
460
|
-
name,
|
|
461
|
-
ts_ms,
|
|
462
|
-
} => {
|
|
463
|
-
// Use a per-entity run_id (overall_run_id.entity.name) so that
|
|
464
|
-
// the START and COMPLETE events for the same entity share the same run_id.
|
|
465
|
-
let entity_run_id = format!("{run_id}.entity.{name}");
|
|
480
|
+
RunEvent::EntityStarted { name, ts_ms, .. } => {
|
|
481
|
+
let entity_run_id = Uuid::new_v4().to_string();
|
|
466
482
|
if let Ok(mut guard) = self.entity_start_ms.lock() {
|
|
467
483
|
guard.insert(name.clone(), ts_ms);
|
|
468
484
|
}
|
|
@@ -515,17 +531,18 @@ impl RunObserver for OpenLineageObserver {
|
|
|
515
531
|
uris,
|
|
516
532
|
);
|
|
517
533
|
}
|
|
518
|
-
RunEvent::RunFinished {
|
|
519
|
-
run_id,
|
|
520
|
-
status,
|
|
521
|
-
ts_ms,
|
|
522
|
-
..
|
|
523
|
-
} => {
|
|
534
|
+
RunEvent::RunFinished { status, ts_ms, .. } => {
|
|
524
535
|
let event_type = if status == "failed" || status == "aborted" {
|
|
525
536
|
"FAIL"
|
|
526
537
|
} else {
|
|
527
538
|
"COMPLETE"
|
|
528
539
|
};
|
|
540
|
+
let run_uuid = self
|
|
541
|
+
.run_uuid
|
|
542
|
+
.lock()
|
|
543
|
+
.ok()
|
|
544
|
+
.and_then(|g| g.clone())
|
|
545
|
+
.unwrap_or_else(|| Uuid::new_v4().to_string());
|
|
529
546
|
let event_time = ms_to_iso8601(ts_ms);
|
|
530
547
|
let mut run_facets = json!({});
|
|
531
548
|
if let Some(parent) = self.parent_run_facet() {
|
|
@@ -535,7 +552,7 @@ impl RunObserver for OpenLineageObserver {
|
|
|
535
552
|
"eventType": event_type,
|
|
536
553
|
"eventTime": event_time,
|
|
537
554
|
"run": {
|
|
538
|
-
"runId":
|
|
555
|
+
"runId": run_uuid,
|
|
539
556
|
"facets": run_facets
|
|
540
557
|
},
|
|
541
558
|
"job": {
|