loom-kernel 0.7.0__tar.gz → 0.9.0__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.
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.github/workflows/ci-main.yml +2 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.github/workflows/ci-pr.yml +2 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.github/workflows/docs.yml +2 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.github/workflows/release.yml +32 -14
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.gitignore +2 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/CHANGELOG.md +209 -0
- loom_kernel-0.9.0/CHANGELOG_RELEASE.md +98 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/PKG-INFO +5 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/pyproject.toml +17 -2
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/keys.py +1 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/observability.py +16 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/__init__.py +2 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/types.py +11 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/config.py +10 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/observer/otel.py +120 -8
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/runtime.py +75 -3
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/session_manager.py +47 -1
- loom_kernel-0.9.0/src/loom/core/schema/__init__.py +5 -0
- loom_kernel-0.9.0/src/loom/core/schema/schema_mode.py +22 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/__init__.py +5 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_predicate.py +4 -11
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_write_policy.py +47 -3
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_reader.py +140 -7
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_writer.py +147 -11
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/provider.py +33 -7
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/__init__.py +7 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_backends/_polars.py +2 -2
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_cleaners.py +29 -4
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/__init__.py +10 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/source/__init__.py +14 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/source/_from.py +5 -7
- loom_kernel-0.9.0/src/loom/etl/declarative/source/_from_clickhouse.py +106 -0
- loom_kernel-0.9.0/src/loom/etl/declarative/source/_from_mongo.py +178 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/source/_specs.py +82 -2
- loom_kernel-0.9.0/src/loom/etl/declarative/target/_schema_mode.py +5 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/executor/_executor.py +39 -7
- loom_kernel-0.9.0/src/loom/etl/io/__init__.py +29 -0
- loom_kernel-0.9.0/src/loom/etl/io/_registry.py +65 -0
- loom_kernel-0.9.0/src/loom/etl/io/sources/_clickhouse.py +153 -0
- loom_kernel-0.9.0/src/loom/etl/io/sources/_mongo.py +258 -0
- loom_kernel-0.9.0/src/loom/etl/io/sources/_mongo_batch.py +869 -0
- loom_kernel-0.9.0/src/loom/etl/io/sources/_mongo_bson.py +181 -0
- loom_kernel-0.9.0/src/loom/etl/io/sources/_mongo_predicate.py +223 -0
- loom_kernel-0.9.0/src/loom/etl/io/targets/_clickhouse.py +158 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/_records.py +23 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_step.py +1 -4
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/core.py +1 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runtime/contracts.py +14 -2
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/storage/__init__.py +4 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/storage/_config.py +98 -13
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/storage/_locator.py +11 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/_runners.py +8 -2
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/_stubs.py +8 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/spark.py +8 -2
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/__init__.py +51 -5
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_adapter.py +13 -1
- loom_kernel-0.9.0/src/loom/streaming/bytewax/_resource_manager.py +160 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_runtime_io.py +17 -5
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/_shared.py +9 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +9 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/routing.py +76 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/steps.py +59 -2
- loom_kernel-0.9.0/src/loom/streaming/bytewax/handlers/storage.py +212 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/runner.py +32 -5
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/__init__.py +4 -2
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/_bindings.py +17 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/_compiler.py +4 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/_plan.py +47 -2
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/phases/build_plan.py +151 -39
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/phases/validate.py +254 -77
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/graph/_flow.py +5 -2
- loom_kernel-0.9.0/src/loom/streaming/mongo/__init__.py +28 -0
- loom_kernel-0.9.0/src/loom/streaming/mongo/_bytewax_source.py +246 -0
- loom_kernel-0.9.0/src/loom/streaming/mongo/_config.py +55 -0
- loom_kernel-0.9.0/src/loom/streaming/mongo/_event.py +79 -0
- loom_kernel-0.9.0/src/loom/streaming/mongo/_normalize.py +287 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/__init__.py +26 -4
- loom_kernel-0.9.0/src/loom/streaming/nodes/_decompose.py +89 -0
- loom_kernel-0.9.0/src/loom/streaming/nodes/_expand_routes.py +75 -0
- loom_kernel-0.9.0/src/loom/streaming/nodes/_mongo.py +50 -0
- loom_kernel-0.9.0/src/loom/streaming/nodes/_sink.py +120 -0
- loom_kernel-0.9.0/src/loom/streaming/nodes/_table/__init__.py +23 -0
- loom_kernel-0.9.0/src/loom/streaming/nodes/_table/common.py +1177 -0
- loom_kernel-0.9.0/src/loom/streaming/nodes/_table/config.py +137 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/testing.py +8 -8
- loom_kernel-0.9.0/src/loom/testing/__init__.py +37 -0
- loom_kernel-0.9.0/tests/integration/streaming/test_into_table_integration.py +511 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/observability/test_observers.py +47 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/observability/test_runtime.py +108 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/conftest.py +2 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_backend.py +142 -1
- loom_kernel-0.9.0/tests/unit/etl/backends/test_polars/test_reader_json_columns.py +431 -0
- loom_kernel-0.9.0/tests/unit/etl/backends/test_polars/test_writer_null_schema.py +55 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/checkpoint/test_store.py +1 -1
- loom_kernel-0.9.0/tests/unit/etl/io/sources/test_clickhouse_reader.py +121 -0
- loom_kernel-0.9.0/tests/unit/etl/io/sources/test_from_clickhouse.py +106 -0
- loom_kernel-0.9.0/tests/unit/etl/io/sources/test_from_mongo.py +224 -0
- loom_kernel-0.9.0/tests/unit/etl/io/sources/test_mongo_predicate.py +188 -0
- loom_kernel-0.9.0/tests/unit/etl/io/sources/test_mongo_reader.py +1681 -0
- loom_kernel-0.9.0/tests/unit/etl/io/targets/test_clickhouse_writer.py +104 -0
- loom_kernel-0.9.0/tests/unit/etl/io/targets/test_into_clickhouse.py +66 -0
- loom_kernel-0.9.0/tests/unit/etl/io/test_registry.py +149 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_source.py +14 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_source_options.py +17 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/sql/test_merge.py +1 -1
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/sql/test_sql_runtime.py +15 -3
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_backend_factory.py +12 -4
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_locator.py +4 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_storage_config.py +99 -8
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_runner.py +102 -5
- loom_kernel-0.9.0/tests/unit/streaming/bytewax/test_resource_manager.py +52 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_runner.py +172 -7
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_runtime_io.py +17 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_steps.py +1 -1
- loom_kernel-0.9.0/tests/unit/streaming/bytewax/test_storage.py +147 -0
- loom_kernel-0.9.0/tests/unit/streaming/compiler/test_async_walk.py +182 -0
- loom_kernel-0.9.0/tests/unit/streaming/compiler/test_mongo_source.py +64 -0
- loom_kernel-0.9.0/tests/unit/streaming/contracts/__init__.py +0 -0
- loom_kernel-0.9.0/tests/unit/streaming/contracts/test_mongo_contracts.py +242 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/__init__.py +2 -0
- loom_kernel-0.9.0/tests/unit/streaming/flows/cases/explode.py +134 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/conftest.py +2 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/test_compiler_examples.py +13 -1
- loom_kernel-0.9.0/tests/unit/streaming/mongo/test_bytewax_source.py +287 -0
- loom_kernel-0.9.0/tests/unit/streaming/nodes/__init__.py +0 -0
- loom_kernel-0.9.0/tests/unit/streaming/nodes/test_delta_config.py +36 -0
- loom_kernel-0.9.0/tests/unit/streaming/nodes/test_table_package.py +19 -0
- loom_kernel-0.9.0/tests/unit/streaming/observability/__init__.py +0 -0
- loom_kernel-0.9.0/tests/unit/streaming/support/__init__.py +0 -0
- loom_kernel-0.9.0/tests/unit/streaming/test_expand_routes.py +92 -0
- loom_kernel-0.9.0/tests/unit/streaming/test_testing_mongo.py +90 -0
- loom_kernel-0.9.0/tests/unit/testing/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/uv.lock +322 -2
- loom_kernel-0.7.0/CHANGELOG_RELEASE.md +0 -96
- loom_kernel-0.7.0/src/loom/etl/declarative/target/_schema_mode.py +0 -23
- loom_kernel-0.7.0/src/loom/streaming/bytewax/_resource_manager.py +0 -68
- loom_kernel-0.7.0/src/loom/testing/__init__.py +0 -20
- loom_kernel-0.7.0/tests/unit/etl/backends/test_polars/test_reader_json_columns.py +0 -199
- loom_kernel-0.7.0/tests/unit/streaming/compiler/test_async_walk.py +0 -91
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.pre-commit-config.yaml +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.readthedocs.yaml +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/LICENSE +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/Makefile +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/README.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/codecov.yml +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/_static/.gitkeep +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/_static/custom.css +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/_static/logo-transparent.png +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/_static/logo.svg +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/architecture/adr/README.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/architecture/clean-architecture.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/architecture/overview.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/conf.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/etl/examples.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/etl/pipelines.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/etl/testing.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/examples-repo/index.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/getting-started/etl.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/getting-started/rest.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/getting-started/streaming.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/autocrud.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/celery.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/etl.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/fake-repo-examples.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/quickstart.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/use-case-dsl.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/index.rst +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/overview.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/core.rst +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/etl.rst +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/repository.rst +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/rest.rst +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/streaming.rst +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/testing.rst +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/index.rst +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/requirements.txt +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/rest/autocrud.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/rest/celery.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/rest/examples.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/rest/testing.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/rest/use-case-dsl.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/streaming/bytewax.md +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/sonar-project.properties +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/auto.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/bootstrap.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/config.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/constants.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/runner.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/service.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/async_bridge.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/backend/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/backend/core_model.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/backend/protocol.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/backend/sqlalchemy.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/bootstrap/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/bootstrap/kernel.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/abc/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/abc/backend.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/abc/config.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/abc/dependency.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/codec.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/decorators.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/dependency.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/gateway.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/keys.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/repository.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/serializer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/command/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/command/adapter.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/command/base.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/command/field.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/command/introspection.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/compiler.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/binder.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/configurable.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/context.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/errors.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/loader.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/model.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/resolver.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/contracts/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/contracts/manifest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/di/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/di/container.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/di/scope.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/_utils.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/base.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/interfaces.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/manifest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/modules.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/compilable.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/compiler.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/events.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/executor.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/metrics.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/plan.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/errors/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/errors/codes.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/errors/errors.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/expr/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/expr/eval.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/expr/nodes.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/expr/refs.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/callback.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/context.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/handle.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/job.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/service.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/logger/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/logger/abc.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/logger/config.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/logger/registry.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/logger/structlogger.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/base.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/enums.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/field.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/introspection.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/projection.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/relation.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/struct.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/timestamped.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/types_postgres.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/event.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/observer/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/observer/noop.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/observer/structlog.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/protocol.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/topology.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/projection/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/projection/loaders.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/projection/runtime.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/abc/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/abc/query.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/abc/repo_for.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/abc/repository.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/mutation.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/registration.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/registry.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/response/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/response/base.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/routing/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/routing/ref.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/routing/resolver.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/runner.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/tracing/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/tracing/context.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/transport/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/transport/adapter.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/uow/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/uow/abc.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/uow/context.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/_predicates.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/compute.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/constants.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/factory.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/field_ref.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/invoker.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/keys.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/markers.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/registry.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/rule.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/use_case.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_format_registry.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/_common.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/_log.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_merge.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_historify.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_schema.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_historify.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_reader.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_schema.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_writer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/provider.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_paths.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_scope.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_store.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_binding.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_compiler.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_errors.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_plan.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_validators.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_validators_step.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/_format.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/_read_options.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/_utils.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/_write_options.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/expr/_params.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_file.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_into.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_table.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_temp.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/executor/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/executor/_dispatcher.py +0 -0
- {loom_kernel-0.7.0/tests → loom_kernel-0.9.0/src/loom/etl/io/sources}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/golden → loom_kernel-0.9.0/src/loom/etl/io/targets}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/_config.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/_observer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_generics.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_params.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_process.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_sql.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/_providers.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/_wiring.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/config_loader.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/errors.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/filtering.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runtime/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/schema/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/schema/_contract.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/schema/_schema.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/storage/_file_locator.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/storage/routing.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/_result.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/_scenario.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/prometheus/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/prometheus/adapter.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/prometheus/kafka.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/prometheus/lifecycle.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/prometheus/middleware.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/adapter.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/autocrud.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/compiler.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/constants.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/errors.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/app.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/auto.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/openapi.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/response.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/middleware.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/model.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/rest_adapter.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_operators.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/core/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/core/_errors.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/core/_exceptions.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/core/_message.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/core/_typing.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/graph/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_codec.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_config.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_errors.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_message.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_record.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_wire.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_boundary.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_fork.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_helpers.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_protocols.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_router.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_shape.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_step.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_with.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/refs.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/testing/golden.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/testing/http_harness.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/testing/in_memory.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/testing/repository_harness.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/testing/runner.py +0 -0
- {loom_kernel-0.7.0/tests/integration → loom_kernel-0.9.0/tests}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/conftest.py +0 -0
- {loom_kernel-0.7.0/tests/integration/celery_bootstrap → loom_kernel-0.9.0/tests/golden}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/golden/baselines/.gitkeep +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/golden/outputs/.gitkeep +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/golden/plans/.gitkeep +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/helpers/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/integration/core → loom_kernel-0.9.0/tests/integration}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/integration/core/bootstrap → loom_kernel-0.9.0/tests/integration/celery_bootstrap}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/celery_bootstrap/config/conf.celery.integration.yaml +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/celery_bootstrap/test_auto_create_app_integration.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/celery_bootstrap/test_bootstrap_worker.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/conftest.py +0 -0
- {loom_kernel-0.7.0/tests/integration/core/repository → loom_kernel-0.9.0/tests/integration/core}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/integration/core/repository/sqlalchemy → loom_kernel-0.9.0/tests/integration/core/bootstrap}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/bootstrap/test_bootstrap_integration.py +0 -0
- {loom_kernel-0.7.0/tests/integration/core/rest → loom_kernel-0.9.0/tests/integration/core/repository}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/integration/core/use_case → loom_kernel-0.9.0/tests/integration/core/repository/sqlalchemy}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/repository/sqlalchemy/conftest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/repository/sqlalchemy/test_cache_integration.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/repository/sqlalchemy/test_repository_integration.py +0 -0
- {loom_kernel-0.7.0/tests/integration/fake_repo → loom_kernel-0.9.0/tests/integration/core/rest}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/rest/test_auto_interface_integration.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/rest/test_fastapi_app_integration.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/rest/test_rest_error_mapping.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/rest/test_rest_observability.py +0 -0
- {loom_kernel-0.7.0/tests/integration/fake_repo/product/category → loom_kernel-0.9.0/tests/integration/core/use_case}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/use_case/test_custom_repository_integration.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/use_case/test_use_case_crud_integration.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/etl/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/etl/test_runner_integration.py +0 -0
- {loom_kernel-0.7.0/tests/integration/fake_repo/product/review → loom_kernel-0.9.0/tests/integration/fake_repo}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/config/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/config/conf.interfaces.yaml +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/config/conf.manifest.yaml +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/config/conf.modules.yaml +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/config/conf.yaml +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/main.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/manifest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/unit → loom_kernel-0.9.0/tests/integration/fake_repo/product/category}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/category/model.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/category/schemas.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/interface.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/jobs.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/model.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/relations.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/repository.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/repository_contract.py +0 -0
- {loom_kernel-0.7.0/tests/unit/celery_bootstrap → loom_kernel-0.9.0/tests/integration/fake_repo/product/review}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/review/model.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/review/schemas.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/schemas.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/use_cases.py +0 -0
- {loom_kernel-0.7.0/tests/unit/celery_jobs → loom_kernel-0.9.0/tests/integration/streaming}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/support/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/support/logical_repo_fixtures.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core → loom_kernel-0.9.0/tests/unit}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/backend → loom_kernel-0.9.0/tests/unit/celery_bootstrap}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_bootstrap/test_async_runtime.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_bootstrap/test_bootstrap.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/bootstrap → loom_kernel-0.9.0/tests/unit/celery_jobs}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_jobs/test_auto.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_jobs/test_celery_service.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_jobs/test_config.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_jobs/test_runner.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/cache → loom_kernel-0.9.0/tests/unit/core}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/command → loom_kernel-0.9.0/tests/unit/core/backend}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/backend/test_backend_compiler.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/config → loom_kernel-0.9.0/tests/unit/core/bootstrap}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/bootstrap/test_bootstrap.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/bootstrap/test_bootstrap_metrics.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/bootstrap/test_kernel.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/di → loom_kernel-0.9.0/tests/unit/core/cache}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/cache/test_cached_repository.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/discovery → loom_kernel-0.9.0/tests/unit/core/command}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/command/test_command_base.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/command/test_command_field.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/command/test_command_patch.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/command/test_introspection.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/engine → loom_kernel-0.9.0/tests/unit/core/config}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/config/test_binder.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/config/test_config.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/config/test_configurable.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/config/test_context.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/errors → loom_kernel-0.9.0/tests/unit/core/di}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/di/test_container.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/expr → loom_kernel-0.9.0/tests/unit/core/discovery}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/discovery/test_manifest.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/job → loom_kernel-0.9.0/tests/unit/core/engine}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_compiler.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_executor.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_executor_trace.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_executor_uow.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_metrics.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_plan.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/logger → loom_kernel-0.9.0/tests/unit/core/errors}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/errors/test_errors.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/model → loom_kernel-0.9.0/tests/unit/core/expr}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/expr/test_expr.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/observability → loom_kernel-0.9.0/tests/unit/core/job}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/conftest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/test_callback.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/test_context.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/test_handle.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/test_inline_service.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/test_job.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/projection → loom_kernel-0.9.0/tests/unit/core/logger}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/logger/test_config.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/logger/test_registry.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/repository → loom_kernel-0.9.0/tests/unit/core/model}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/model/test_model.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/model/test_struct.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/model/test_timestamped.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/repository/abc → loom_kernel-0.9.0/tests/unit/core/observability}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/repository/sqlalchemy → loom_kernel-0.9.0/tests/unit/core/projection}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/projection/test_runtime.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/routing → loom_kernel-0.9.0/tests/unit/core/repository}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/tracing → loom_kernel-0.9.0/tests/unit/core/repository/abc}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/abc/conftest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/abc/test_query.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/abc/test_repository_contract.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/uow → loom_kernel-0.9.0/tests/unit/core/repository/sqlalchemy}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/sqlalchemy/conftest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/sqlalchemy/test_loaders.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/sqlalchemy/test_repository.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/sqlalchemy/test_transactional.py +0 -0
- {loom_kernel-0.7.0/tests/unit/core/use_case → loom_kernel-0.9.0/tests/unit/core/routing}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/routing/test_routing.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/test_async_bridge.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/test_compiler_contracts.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/test_runner_contracts.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl → loom_kernel-0.9.0/tests/unit/core/tracing}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/tracing/test_context.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl/backends → loom_kernel-0.9.0/tests/unit/core/uow}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/uow/test_executor_uow.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/uow/test_sqlalchemy_uow.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/uow/test_uow_protocols.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl/backends/test_polars → loom_kernel-0.9.0/tests/unit/core/use_case}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_compute.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_factory.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_field_ref.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_invoker.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_markers.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_rule.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_use_case.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl/backends/test_spark → loom_kernel-0.9.0/tests/unit/etl}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl/checkpoint → loom_kernel-0.9.0/tests/unit/etl/backends}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/_historify_contract.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_historify_common.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl/checkpoint/backends → loom_kernel-0.9.0/tests/unit/etl/backends/test_polars}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_apply_schema.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_dtype.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_file_writer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_historify_polars.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_predicate_pushdown.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_reader_columns.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_step_execution.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_upsert_writer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_writer_to_frame.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl/compiler → loom_kernel-0.9.0/tests/unit/etl/backends/test_spark}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/conftest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/test_dtype.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/test_historify_spark.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/test_spark_apply_schema.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/test_step_execution.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/test_writer_to_frame.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_write_policy_historify.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl/io → loom_kernel-0.9.0/tests/unit/etl/checkpoint}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl/schema → loom_kernel-0.9.0/tests/unit/etl/checkpoint/backends}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/checkpoint/backends/test_checkpoint_polars.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/checkpoint/test_checkpoint_paths.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/checkpoint/test_cleaners.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl/sql → loom_kernel-0.9.0/tests/unit/etl/compiler}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_catalog_validator.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_compiler.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_compiler_catalog.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_compiler_upsert.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_errors.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_errors_additional_factories.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_errors_runtime_factories.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_historify_validator.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_param_exprs_validator.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_plan_traversal.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_step_validator.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_structural.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_temp_validator.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_upsert_validator.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/conftest.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl/storage → loom_kernel-0.9.0/tests/unit/etl/io}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/unit/etl/testing → loom_kernel-0.9.0/tests/unit/etl/io/sources}/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/unit/prometheus → loom_kernel-0.9.0/tests/unit/etl/io/targets}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_history_target.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_source_json.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_target.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_utils.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_variants.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/lineage/test_observer.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/lineage/test_records.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/lineage/test_store.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/pipeline/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/pipeline/test_pipeline_process.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/pipeline/test_proxy.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/pipeline/test_step.py +0 -0
- {loom_kernel-0.7.0/tests/unit/rest → loom_kernel-0.9.0/tests/unit/etl/schema}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/schema/test_contract.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/schema/test_schema.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/schema/test_table.py +0 -0
- {loom_kernel-0.7.0/tests/unit/streaming/bytewax → loom_kernel-0.9.0/tests/unit/etl/sql}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/sql/test_predicate.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/sql/test_predicate_dialect.py +0 -0
- {loom_kernel-0.7.0/tests/unit/streaming/compiler → loom_kernel-0.9.0/tests/unit/etl/storage}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_io_protocols.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_observability_and_protocols.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_route_build.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_schema_readers.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_config_loader.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_executor.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_format_registry.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_module_contracts.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_public_api_discovery.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_record_schema_coverage.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_runner_errors.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_spark_testing.py +0 -0
- {loom_kernel-0.7.0/tests/unit/streaming/contracts → loom_kernel-0.9.0/tests/unit/etl/testing}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/testing/test_runners.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/testing/test_scenario_and_stubs.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/testing/test_spark_helpers.py +0 -0
- {loom_kernel-0.7.0/tests/unit/streaming/nodes → loom_kernel-0.9.0/tests/unit/prometheus}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/prometheus/test_adapter.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/prometheus/test_middleware.py +0 -0
- {loom_kernel-0.7.0/tests/unit/streaming/observability → loom_kernel-0.9.0/tests/unit/rest}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_autocrud.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_fastapi_auto_logger.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_middleware.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_pydantic_adapter.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_response.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_rest_adapter.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_rest_compiler.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_rest_model.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_router_runtime.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/__init__.py +0 -0
- {loom_kernel-0.7.0/tests/unit/streaming/support → loom_kernel-0.9.0/tests/unit/streaming/bytewax}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/cases.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/conftest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_adapter.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_batch_key.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_bytewax_dispatcher.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_collect_batch.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_dlq.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_error_boundary.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_operators.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_runtime_sink.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_runtime_source.py +0 -0
- {loom_kernel-0.7.0/tests/unit/testing → loom_kernel-0.9.0/tests/unit/streaming/compiler}/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/cases.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_basics.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_config_bindings.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_multi_source.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_router.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_window.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_with.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/conftest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/contracts/cases.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/contracts/test_boundary.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/contracts/test_message.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/contracts/test_multi_boundary.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/contracts/test_steps.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/batch.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/fork.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/router.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/shared.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/simple.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/test_flow_examples.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/__init__.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/cases.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/conftest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/fakes.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_client.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_config.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_key_resolver.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_message.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_message_client.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_multi_wire.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_observability.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_settings.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_wire.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/nodes/conftest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/nodes/test_broadcast.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/nodes/test_logging.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/cases.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/conftest.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/test_observability_runner.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/test_protocols.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/test_registry.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/test_structlog.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/support/flow_cases.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/test_fork.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/test_otel_observability.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/test_routing.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/test_with.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/testing/test_golden.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/testing/test_http_harness.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/testing/test_in_memory.py +0 -0
- {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/testing/test_runner.py +0 -0
|
@@ -24,7 +24,8 @@ jobs:
|
|
|
24
24
|
with:
|
|
25
25
|
python-version: "3.11"
|
|
26
26
|
|
|
27
|
-
-
|
|
27
|
+
- name: Install uv
|
|
28
|
+
run: pip install uv
|
|
28
29
|
|
|
29
30
|
- name: Quality report (strict)
|
|
30
31
|
uses: the-reacher-data/loom-actions/actions/python/quality-report@e731576f4f9cf4ec2b36fddfc895d328c856d29f # v1
|
|
@@ -37,7 +37,8 @@ jobs:
|
|
|
37
37
|
with:
|
|
38
38
|
python-version: "3.11"
|
|
39
39
|
|
|
40
|
-
-
|
|
40
|
+
- name: Install uv
|
|
41
|
+
run: pip install uv
|
|
41
42
|
|
|
42
43
|
- name: Configure uv environment path
|
|
43
44
|
shell: bash
|
|
@@ -87,7 +88,7 @@ jobs:
|
|
|
87
88
|
sed -i "0,/^version = \".*\"/s//version = \"${VERSION}\"/" pyproject.toml
|
|
88
89
|
sed -i "/^\[tool.commitizen\]/,/^\[/ s/^version = \".*\"/version = \"${VERSION}\"/" pyproject.toml
|
|
89
90
|
|
|
90
|
-
- name:
|
|
91
|
+
- name: Create or merge version bump PR
|
|
91
92
|
if: ${{ steps.version.outputs.deploy == 'true' }}
|
|
92
93
|
env:
|
|
93
94
|
VERSION: ${{ steps.version.outputs.version }}
|
|
@@ -99,22 +100,36 @@ jobs:
|
|
|
99
100
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
100
101
|
|
|
101
102
|
BRANCH="docs/release-v${VERSION}"
|
|
102
|
-
git checkout -B "${BRANCH}"
|
|
103
103
|
|
|
104
|
-
if
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
104
|
+
if git ls-remote --tags origin "refs/tags/v${VERSION}" | grep -q .; then
|
|
105
|
+
echo "Release tag v${VERSION} already exists; skipping version bump PR."
|
|
106
|
+
exit 0
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
open_pr_count=$(gh pr list --head "${BRANCH}" --state open --json number --jq 'length')
|
|
110
|
+
all_pr_count=$(gh pr list --head "${BRANCH}" --state all --json number --jq 'length')
|
|
111
|
+
|
|
112
|
+
if [ "${all_pr_count}" -gt 0 ] && [ "${open_pr_count}" -eq 0 ]; then
|
|
113
|
+
echo "Release PR ${BRANCH} already exists in a closed state; skipping duplicate creation."
|
|
114
|
+
exit 0
|
|
110
115
|
fi
|
|
111
116
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
if [ "${open_pr_count}" -eq 0 ]; then
|
|
118
|
+
git checkout -B "${BRANCH}"
|
|
119
|
+
|
|
120
|
+
if [ -f CHANGELOG_RELEASE.md ]; then
|
|
121
|
+
HEADER=$(head -1 CHANGELOG_RELEASE.md)
|
|
122
|
+
if ! grep -qF "${HEADER}" CHANGELOG.md; then
|
|
123
|
+
cat CHANGELOG_RELEASE.md CHANGELOG.md > CHANGELOG_MERGED.md
|
|
124
|
+
mv CHANGELOG_MERGED.md CHANGELOG.md
|
|
125
|
+
fi
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
git add pyproject.toml CHANGELOG.md
|
|
129
|
+
git diff --staged --quiet && exit 0
|
|
130
|
+
git commit -m "chore(release): bump version to ${VERSION}"
|
|
131
|
+
git push origin "${BRANCH}" --force
|
|
116
132
|
|
|
117
|
-
if ! gh pr list --head "${BRANCH}" --state open --json number --jq '.[0].number' | grep -qE '^[0-9]+$'; then
|
|
118
133
|
gh pr create \
|
|
119
134
|
--title "chore(release): bump version to ${VERSION}" \
|
|
120
135
|
--body "Automated version bump and changelog update after release v${VERSION}." \
|
|
@@ -136,10 +151,13 @@ jobs:
|
|
|
136
151
|
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
|
|
137
152
|
with:
|
|
138
153
|
password: ${{ env.PYPI_API_TOKEN }}
|
|
154
|
+
skip-existing: true
|
|
139
155
|
|
|
140
156
|
- name: Publish package to PyPI (trusted publisher)
|
|
141
157
|
if: ${{ steps.version.outputs.deploy == 'true' && env.PYPI_API_TOKEN == '' }}
|
|
142
158
|
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
|
|
159
|
+
with:
|
|
160
|
+
skip-existing: true
|
|
143
161
|
|
|
144
162
|
- name: Create and push tags
|
|
145
163
|
if: ${{ steps.version.outputs.deploy == 'true' }}
|
|
@@ -1,3 +1,212 @@
|
|
|
1
|
+
# 🚀 Release 0.9.0 ([#32](https://github.com/the-reacher-data/loom-py/pull/32)) ([`14072d1`](https://github.com/the-reacher-data/loom-py/commit/14072d1be9212116235f26d7a2590a4f0e622451))
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## ✨ Features
|
|
5
|
+
### streaming
|
|
6
|
+
- **streaming:** add Mongo CDC source
|
|
7
|
+
- **streaming:** add MongoObjectId and MongoDBRef domain types<br>
|
|
8
|
+
> Replace opaque str/dict BSON normalization with structured domain types:
|
|
9
|
+
> MongoObjectId(id, created_at_ms) preserves ObjectId hex and creation
|
|
10
|
+
> timestamp extracted from the embedded 4-byte BSON timestamp field
|
|
11
|
+
> MongoDBRef(id, collection, database) models cross-collection references
|
|
12
|
+
> with explicit collection and optional database fields
|
|
13
|
+
> MongoCDCEvent.document_id widened to MongoObjectId | str | None to
|
|
14
|
+
> expose rich type when _id is an ObjectId
|
|
15
|
+
> _normalize_objectid and _normalize_dbref updated to produce the new types
|
|
16
|
+
> Guard clause added to _normalize_dbref for None identifier
|
|
17
|
+
> _message_key helper centralizes MongoObjectId → str key extraction
|
|
18
|
+
> MongoObjectId and MongoDBRef exported from loom.streaming public API
|
|
19
|
+
> Contract tests cover DBRef without database, integer id, None id error,
|
|
20
|
+
> and ObjectId without generation_time (created_at_ms=None)
|
|
21
|
+
|
|
22
|
+
- **streaming:** add Backend.CLICKHOUSE with native clickhouse-connect sink<br>
|
|
23
|
+
> Add _ClickHouseTablePartition as a standalone SinkPartition backed by
|
|
24
|
+
> clickhouse-connect (HTTP/2, no SQLAlchemy). Uses a column-oriented buffer
|
|
25
|
+
> layout matching clickhouse-connect's column_oriented=True path, avoiding
|
|
26
|
+
> the internal pivot() transposition for maximum insert throughput.
|
|
27
|
+
> Resolves the _json_serializer crash that occurred when inserting list[str]
|
|
28
|
+
> fields via the SQLAlchemy backend against ClickHouseDialect_asynch. With the
|
|
29
|
+
> native client, Array(String) and all CH-native types work without workarounds.
|
|
30
|
+
|
|
31
|
+
- **streaming:** add ExpandRoutes fan-out node and JsonStr semantic type<br>
|
|
32
|
+
> ExpandRoutes: expands one event once via PayloadExpander and routes each
|
|
33
|
+
> typed output list to its own independent Process (dict-based API, optional
|
|
34
|
+
> default route); wired in Bytewax via flat_map per route branch
|
|
35
|
+
> JsonStr: Annotated[str, _JsonMarker()] sentinel type for raw JSON fields;
|
|
36
|
+
> mapped to Text() in SQLAlchemy; passes through as str in ClickHouse/Delta
|
|
37
|
+
> ProcessNode union extended to include ExpandRoutes[Any]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## 🐛 Fixes
|
|
42
|
+
### streaming
|
|
43
|
+
- **streaming:** replace assert with explicit TypeError in _adapter.py<br>
|
|
44
|
+
> Bandit B101: assert statements are stripped when running with -O.
|
|
45
|
+
> Replaced both isinstance asserts with explicit TypeError raises to
|
|
46
|
+
> preserve the runtime invariant checks under all execution modes.
|
|
47
|
+
|
|
48
|
+
- **streaming:** age-based buffer flush never fired in IntoTable sink partitions<br>
|
|
49
|
+
> Two bugs prevented buffer_max_age_s from triggering a flush:
|
|
50
|
+
> 1. write_batch([]) returned immediately on empty epochs, so quiet periods
|
|
51
|
+
> never checked the age threshold.
|
|
52
|
+
> 2. _last_append_at was updated right before _should_flush(), making the
|
|
53
|
+
> elapsed-time expression always ≈0ms.
|
|
54
|
+
> Replace _last_append_at with _buffer_started_at (set when the buffer
|
|
55
|
+
> transitions from empty, reset after each flush) in both
|
|
56
|
+
> _SQLAlchemyTablePartition and _DeltaTablePartition. Empty epoch calls
|
|
57
|
+
> now check for an age-based flush before returning.
|
|
58
|
+
|
|
59
|
+
- **streaming:** wire ExpandRoutes runtime and ClickHouse HTTP URL resolution
|
|
60
|
+
|
|
61
|
+
### compiler
|
|
62
|
+
- **compiler:** add Backend.CLICKHOUSE dispatch in build_plan storage sink resolver
|
|
63
|
+
- **compiler:** validate ExpandRoutes branches for terminal output detection
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
## ♻️ Refactor
|
|
69
|
+
### streaming
|
|
70
|
+
- **streaming:** improve Mongo CDC architecture compliance<br>
|
|
71
|
+
> Replace bare except Exception with specific OperationFailure catch
|
|
72
|
+
> Replace type(x).__name__ string dispatch with isinstance and lazy import
|
|
73
|
+
> Type watch_options as Mapping[str, object] to eliminate implicit Any
|
|
74
|
+
> Introduce _BSON_NORMALIZERS dispatch map in normalize_bson_value
|
|
75
|
+
> Define _ChangeStream and _DatabaseLike Protocols for PyMongo types
|
|
76
|
+
> Make FromMongoCDC generic with covariant MongoCDCPayloadT (PEP 696)
|
|
77
|
+
> Add needs_decode: ClassVar[bool] to compiled source types
|
|
78
|
+
> Replace isinstance type-switches with dispatch maps (_SOURCE_BUILDERS,
|
|
79
|
+
> _RUNTIME_SOURCE_BUILDERS) across compiler and bytewax runtime layers
|
|
80
|
+
> Declare typing_extensions>=4.12 as direct dependency
|
|
81
|
+
> Add contract tests for FromMongoCDC generic parametrization
|
|
82
|
+
|
|
83
|
+
- **streaming:** simplify source dispatch and pymongo error handling<br>
|
|
84
|
+
> Replace _RUNTIME_SOURCE_BUILDERS dispatch map with direct isinstance check in build_runtime_source
|
|
85
|
+
> Replace lazy _operation_failure_type() with module-level try/except import for OperationFailure
|
|
86
|
+
> Use explicit isinstance in _source_topic_or_none instead of getattr duck-typing
|
|
87
|
+
> Remove redundant empty-collections branch in _open_change_stream
|
|
88
|
+
> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## ✅ Tests
|
|
94
|
+
### streaming
|
|
95
|
+
- **streaming:** add unit tests for ExpandRoutes fan-out node
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# 🚀 Release 0.8.0 ([#30](https://github.com/the-reacher-data/loom-py/pull/30)) ([`702b99e`](https://github.com/the-reacher-data/loom-py/commit/702b99ec75a4130f273322f8eb488637a2f98a14))
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
## ✨ Features
|
|
105
|
+
### streaming
|
|
106
|
+
- **streaming:** add IntoSink/SinkPartition protocols and Decompose node<br>
|
|
107
|
+
> Introduces the two-level contract that makes storage sinks extensible at
|
|
108
|
+
> the node level. Any frozen dataclass satisfying IntoSink is a first-class
|
|
109
|
+
> terminal node — no registration, no inheritance, no framework coupling.
|
|
110
|
+
> core/schema/: new shared module; SchemaMode promoted from ETL (ETL re-exports for backwards compat)
|
|
111
|
+
> nodes/_sink.py: SinkPartition (contravariant per-worker protocol) and IntoSink (runtime-checkable terminal protocol)
|
|
112
|
+
> nodes/_decompose.py: EntityDecomposer protocol and Decompose transformation node
|
|
113
|
+
> validate.py: _is_leaf_terminal() helper unifies all terminal checks; IntoSink recognised as terminal in shape and output validation; _node_output_shape refactored to dispatch map
|
|
114
|
+
> exports: IntoSink, SinkPartition, Decompose, EntityDecomposer in public API
|
|
115
|
+
> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
116
|
+
|
|
117
|
+
- **streaming:** add IntoTable sink node and rename EntityDecomposer to PayloadExpander<br>
|
|
118
|
+
> IntoTable: frozen dataclass implementing IntoSink for SQLAlchemy and Delta backends
|
|
119
|
+
> Backend enum: SQLALCHEMY and DELTA variants
|
|
120
|
+
> _SQLAlchemyTablePartition: bulk-insert via engine.begin() per epoch batch
|
|
121
|
+
> _DeltaTablePartition: write via deltalake + polars with validated write mode
|
|
122
|
+
> Rename EntityDecomposer -> PayloadExpander, decompose() -> expand(), targets -> outputs
|
|
123
|
+
> Update both streaming.__init__ and streaming.nodes.__init__ public exports
|
|
124
|
+
> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
### streaming/compiler
|
|
128
|
+
- **streaming/compiler:** teach compiler to resolve IntoSink nodes<br>
|
|
129
|
+
> Add CompiledStorageSink to _plan: holds the IntoSink node and its
|
|
130
|
+
> pre-fetched streaming.sinks.<name> config section
|
|
131
|
+
> Add terminal_storage_sinks field to CompiledPlan (default empty dict
|
|
132
|
+
> keeps all existing tests green)
|
|
133
|
+
> Refactor _build_terminal_sinks and all branch builders to return
|
|
134
|
+
> (kafka_sinks, storage_sinks) tuple in a single walk — no duplicate
|
|
135
|
+
> traversal
|
|
136
|
+
> Add _build_storage_sink: resolves config by node.name or passes {}
|
|
137
|
+
> when name is empty (self-configured sinks)
|
|
138
|
+
> Add validate_storage_sinks phase: reports a clear error for every
|
|
139
|
+
> named IntoSink whose streaming.sinks.<name> section is absent
|
|
140
|
+
> Wire validate_storage_sinks into the compiler pipeline
|
|
141
|
+
> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
142
|
+
|
|
143
|
+
- **streaming/compiler:** add Decompose shape and structural validation<br>
|
|
144
|
+
> Import Decompose in validate.py
|
|
145
|
+
> Add RECORD to _node_input_shape for Decompose — enforces that it
|
|
146
|
+
> receives individual events, not batches
|
|
147
|
+
> Add Decompose: StreamShape.RECORD to _FIXED_OUTPUT_SHAPES — its
|
|
148
|
+
> output feeds the Router as per-type records
|
|
149
|
+
> Add structural check in _validate_shape_sequence: Decompose must be
|
|
150
|
+
> immediately followed by a Router; clear error message when it is not
|
|
151
|
+
> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
### streaming/bytewax
|
|
155
|
+
- **streaming/bytewax:** wire IntoSink nodes to Bytewax output operators<br>
|
|
156
|
+
> Add handlers/storage.py: _StorageSinkPartition wraps loom SinkPartition,
|
|
157
|
+
> extracting payload from Message envelopes; _StorageDynamicSink calls
|
|
158
|
+
> node.build_partition(config, worker_index, worker_count) once per
|
|
159
|
+
> Bytewax worker at startup; _apply_into_sink registers the DynamicSink
|
|
160
|
+
> via bw_output for any IntoSink node found in the compiled plan
|
|
161
|
+
> Register IntoSink in _NODE_HANDLERS dispatch map (dispatcher.py) so
|
|
162
|
+
> _wire_process routes any IntoSink node to _apply_into_sink
|
|
163
|
+
> Add IntoSink pass-through in _execute_router_node (routing.py)
|
|
164
|
+
> consistent with the IntoTopic/Drain pattern for inline Router execution
|
|
165
|
+
> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
## ♻️ Refactor
|
|
173
|
+
### streaming
|
|
174
|
+
- **streaming:** improve _SQLAlchemyTablePartition with typed columns and pool config<br>
|
|
175
|
+
> Extract _require_sa_url, _sa_engine_kwargs, _sa_type_for, _sa_table_from_struct,
|
|
176
|
+
> _structs_to_rows helpers for readability and single responsibility
|
|
177
|
+
> Map Python types to SA column types (_sa_type_for) with Optional unwrapping
|
|
178
|
+
> and collection → JSON fallback; mirrors _SCALAR_TYPE_MAP from introspection.py
|
|
179
|
+
> Mirror SessionManager pool defaults: pool_pre_ping, echo, pool_size,
|
|
180
|
+
> max_overflow, pool_timeout, pool_recycle, connect_args from config
|
|
181
|
+
> Replace msgspec.structs.asdict cast hack with direct call via _structs_to_rows
|
|
182
|
+
> Drop connection_string fallback — config contract is url only
|
|
183
|
+
> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
184
|
+
|
|
185
|
+
- **streaming:** merge sink config from dsl and yaml
|
|
186
|
+
- **streaming:** move table sink into package
|
|
187
|
+
- **streaming:** resolve table sink config via context
|
|
188
|
+
- **streaming:** enforce typed table sink config
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
## ✅ Tests
|
|
193
|
+
### streaming
|
|
194
|
+
- **streaming:** add IntoTable SQLAlchemy integration tests against SQLite<br>
|
|
195
|
+
> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
196
|
+
|
|
197
|
+
- **streaming:** cover resource manager session cache
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
## 🔖 Other
|
|
202
|
+
- Fix Bytewax step flat_map tests
|
|
203
|
+
- Refactor streaming validation helpers<br>
|
|
204
|
+
> --------
|
|
205
|
+
> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
1
210
|
# 🚀 Release 0.7.0 ([#25](https://github.com/the-reacher-data/loom-py/pull/25)) ([`0d8941a`](https://github.com/the-reacher-data/loom-py/commit/0d8941a724ec768b162a07e756bac3d53157ec85))
|
|
2
211
|
|
|
3
212
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# 🚀 Release 0.9.0 ([#32](https://github.com/the-reacher-data/loom-py/pull/32)) ([`14072d1`](https://github.com/the-reacher-data/loom-py/commit/14072d1be9212116235f26d7a2590a4f0e622451))
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## ✨ Features
|
|
5
|
+
### streaming
|
|
6
|
+
- **streaming:** add Mongo CDC source
|
|
7
|
+
- **streaming:** add MongoObjectId and MongoDBRef domain types<br>
|
|
8
|
+
> Replace opaque str/dict BSON normalization with structured domain types:
|
|
9
|
+
> MongoObjectId(id, created_at_ms) preserves ObjectId hex and creation
|
|
10
|
+
> timestamp extracted from the embedded 4-byte BSON timestamp field
|
|
11
|
+
> MongoDBRef(id, collection, database) models cross-collection references
|
|
12
|
+
> with explicit collection and optional database fields
|
|
13
|
+
> MongoCDCEvent.document_id widened to MongoObjectId | str | None to
|
|
14
|
+
> expose rich type when _id is an ObjectId
|
|
15
|
+
> _normalize_objectid and _normalize_dbref updated to produce the new types
|
|
16
|
+
> Guard clause added to _normalize_dbref for None identifier
|
|
17
|
+
> _message_key helper centralizes MongoObjectId → str key extraction
|
|
18
|
+
> MongoObjectId and MongoDBRef exported from loom.streaming public API
|
|
19
|
+
> Contract tests cover DBRef without database, integer id, None id error,
|
|
20
|
+
> and ObjectId without generation_time (created_at_ms=None)
|
|
21
|
+
|
|
22
|
+
- **streaming:** add Backend.CLICKHOUSE with native clickhouse-connect sink<br>
|
|
23
|
+
> Add _ClickHouseTablePartition as a standalone SinkPartition backed by
|
|
24
|
+
> clickhouse-connect (HTTP/2, no SQLAlchemy). Uses a column-oriented buffer
|
|
25
|
+
> layout matching clickhouse-connect's column_oriented=True path, avoiding
|
|
26
|
+
> the internal pivot() transposition for maximum insert throughput.
|
|
27
|
+
> Resolves the _json_serializer crash that occurred when inserting list[str]
|
|
28
|
+
> fields via the SQLAlchemy backend against ClickHouseDialect_asynch. With the
|
|
29
|
+
> native client, Array(String) and all CH-native types work without workarounds.
|
|
30
|
+
|
|
31
|
+
- **streaming:** add ExpandRoutes fan-out node and JsonStr semantic type<br>
|
|
32
|
+
> ExpandRoutes: expands one event once via PayloadExpander and routes each
|
|
33
|
+
> typed output list to its own independent Process (dict-based API, optional
|
|
34
|
+
> default route); wired in Bytewax via flat_map per route branch
|
|
35
|
+
> JsonStr: Annotated[str, _JsonMarker()] sentinel type for raw JSON fields;
|
|
36
|
+
> mapped to Text() in SQLAlchemy; passes through as str in ClickHouse/Delta
|
|
37
|
+
> ProcessNode union extended to include ExpandRoutes[Any]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## 🐛 Fixes
|
|
42
|
+
### streaming
|
|
43
|
+
- **streaming:** replace assert with explicit TypeError in _adapter.py<br>
|
|
44
|
+
> Bandit B101: assert statements are stripped when running with -O.
|
|
45
|
+
> Replaced both isinstance asserts with explicit TypeError raises to
|
|
46
|
+
> preserve the runtime invariant checks under all execution modes.
|
|
47
|
+
|
|
48
|
+
- **streaming:** age-based buffer flush never fired in IntoTable sink partitions<br>
|
|
49
|
+
> Two bugs prevented buffer_max_age_s from triggering a flush:
|
|
50
|
+
> 1. write_batch([]) returned immediately on empty epochs, so quiet periods
|
|
51
|
+
> never checked the age threshold.
|
|
52
|
+
> 2. _last_append_at was updated right before _should_flush(), making the
|
|
53
|
+
> elapsed-time expression always ≈0ms.
|
|
54
|
+
> Replace _last_append_at with _buffer_started_at (set when the buffer
|
|
55
|
+
> transitions from empty, reset after each flush) in both
|
|
56
|
+
> _SQLAlchemyTablePartition and _DeltaTablePartition. Empty epoch calls
|
|
57
|
+
> now check for an age-based flush before returning.
|
|
58
|
+
|
|
59
|
+
- **streaming:** wire ExpandRoutes runtime and ClickHouse HTTP URL resolution
|
|
60
|
+
|
|
61
|
+
### compiler
|
|
62
|
+
- **compiler:** add Backend.CLICKHOUSE dispatch in build_plan storage sink resolver
|
|
63
|
+
- **compiler:** validate ExpandRoutes branches for terminal output detection
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
## ♻️ Refactor
|
|
69
|
+
### streaming
|
|
70
|
+
- **streaming:** improve Mongo CDC architecture compliance<br>
|
|
71
|
+
> Replace bare except Exception with specific OperationFailure catch
|
|
72
|
+
> Replace type(x).__name__ string dispatch with isinstance and lazy import
|
|
73
|
+
> Type watch_options as Mapping[str, object] to eliminate implicit Any
|
|
74
|
+
> Introduce _BSON_NORMALIZERS dispatch map in normalize_bson_value
|
|
75
|
+
> Define _ChangeStream and _DatabaseLike Protocols for PyMongo types
|
|
76
|
+
> Make FromMongoCDC generic with covariant MongoCDCPayloadT (PEP 696)
|
|
77
|
+
> Add needs_decode: ClassVar[bool] to compiled source types
|
|
78
|
+
> Replace isinstance type-switches with dispatch maps (_SOURCE_BUILDERS,
|
|
79
|
+
> _RUNTIME_SOURCE_BUILDERS) across compiler and bytewax runtime layers
|
|
80
|
+
> Declare typing_extensions>=4.12 as direct dependency
|
|
81
|
+
> Add contract tests for FromMongoCDC generic parametrization
|
|
82
|
+
|
|
83
|
+
- **streaming:** simplify source dispatch and pymongo error handling<br>
|
|
84
|
+
> Replace _RUNTIME_SOURCE_BUILDERS dispatch map with direct isinstance check in build_runtime_source
|
|
85
|
+
> Replace lazy _operation_failure_type() with module-level try/except import for OperationFailure
|
|
86
|
+
> Use explicit isinstance in _source_topic_or_none instead of getattr duck-typing
|
|
87
|
+
> Remove redundant empty-collections branch in _open_change_stream
|
|
88
|
+
> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## ✅ Tests
|
|
94
|
+
### streaming
|
|
95
|
+
- **streaming:** add unit tests for ExpandRoutes fan-out node
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: loom-kernel
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: Loom Python project
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -9,6 +9,7 @@ Requires-Dist: msgspec<1.0,>=0.18
|
|
|
9
9
|
Requires-Dist: omegaconf<3.0,>=2.3
|
|
10
10
|
Requires-Dist: prometheus-client>=0.20
|
|
11
11
|
Requires-Dist: structlog<26.0,>=24.4
|
|
12
|
+
Requires-Dist: typing-extensions>=4.12
|
|
12
13
|
Provides-Extra: cache
|
|
13
14
|
Requires-Dist: aiocache<1.0,>=0.12; extra == 'cache'
|
|
14
15
|
Requires-Dist: omegaconf<3.0,>=2.3; extra == 'cache'
|
|
@@ -16,6 +17,8 @@ Provides-Extra: celery
|
|
|
16
17
|
Requires-Dist: celery<6.0,>=5.3; extra == 'celery'
|
|
17
18
|
Requires-Dist: kombu<6.0,>=5.3; extra == 'celery'
|
|
18
19
|
Requires-Dist: redis<6.0,>=5.0; extra == 'celery'
|
|
20
|
+
Provides-Extra: clickhouse
|
|
21
|
+
Requires-Dist: clickhouse-connect<1.0,>=0.7; extra == 'clickhouse'
|
|
19
22
|
Provides-Extra: config
|
|
20
23
|
Requires-Dist: fsspec>=2024.2.0; extra == 'config'
|
|
21
24
|
Requires-Dist: omegaconf<3.0,>=2.3; extra == 'config'
|
|
@@ -32,6 +35,7 @@ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2.0,>=1.20; extra == 'etl-
|
|
|
32
35
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2.0,>=1.20; extra == 'etl-polars'
|
|
33
36
|
Requires-Dist: opentelemetry-sdk<2.0,>=1.20; extra == 'etl-polars'
|
|
34
37
|
Requires-Dist: polars<2.0,>=1.0; extra == 'etl-polars'
|
|
38
|
+
Requires-Dist: pyarrow>=14.0; extra == 'etl-polars'
|
|
35
39
|
Provides-Extra: etl-spark
|
|
36
40
|
Requires-Dist: delta-spark<4.0,>=3.2; extra == 'etl-spark'
|
|
37
41
|
Requires-Dist: findspark<3.0,>=2.0; extra == 'etl-spark'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "loom-kernel"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.9.0"
|
|
4
4
|
description = "Loom Python project"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -10,6 +10,7 @@ dependencies = [
|
|
|
10
10
|
"omegaconf>=2.3,<3.0",
|
|
11
11
|
"prometheus-client>=0.20",
|
|
12
12
|
"aiocache>=0.12,<1.0",
|
|
13
|
+
"typing_extensions>=4.12",
|
|
13
14
|
]
|
|
14
15
|
|
|
15
16
|
[project.optional-dependencies]
|
|
@@ -24,6 +25,9 @@ rest = [
|
|
|
24
25
|
sqlalchemy = [
|
|
25
26
|
"sqlalchemy>=2.0,<3.0",
|
|
26
27
|
]
|
|
28
|
+
clickhouse = [
|
|
29
|
+
"clickhouse-connect>=0.7,<1.0",
|
|
30
|
+
]
|
|
27
31
|
config = [
|
|
28
32
|
"omegaconf>=2.3,<3.0",
|
|
29
33
|
"fsspec>=2024.2.0",
|
|
@@ -35,6 +39,7 @@ cache = [
|
|
|
35
39
|
etl-polars = [
|
|
36
40
|
"polars>=1.0,<2.0",
|
|
37
41
|
"deltalake>=1.5,<2.0",
|
|
42
|
+
"pyarrow>=14.0",
|
|
38
43
|
"fsspec>=2024.2.0",
|
|
39
44
|
"opentelemetry-api>=1.20,<2.0",
|
|
40
45
|
"opentelemetry-sdk>=1.20,<2.0",
|
|
@@ -110,6 +115,8 @@ dev = [
|
|
|
110
115
|
"ruff>=0.9.0,<1.0",
|
|
111
116
|
"sqlalchemy>=2.0,<3.0",
|
|
112
117
|
"polars>=1.0,<2.0",
|
|
118
|
+
"clickhouse-connect>=0.7,<1.0",
|
|
119
|
+
"pyarrow>=14.0",
|
|
113
120
|
"deltalake>=1.5,<2.0",
|
|
114
121
|
"fsspec>=2024.2.0",
|
|
115
122
|
"httpx>=0.28.1",
|
|
@@ -122,6 +129,7 @@ dev = [
|
|
|
122
129
|
"findspark>=2.0.1",
|
|
123
130
|
"confluent-kafka>=2.6,<3.0",
|
|
124
131
|
"bytewax>=0.21",
|
|
132
|
+
"pymongo>=4.6,<5.0",
|
|
125
133
|
"opentelemetry-api>=1.20,<2.0",
|
|
126
134
|
"opentelemetry-sdk>=1.20,<2.0",
|
|
127
135
|
"opentelemetry-exporter-otlp-proto-http>=1.20,<2.0",
|
|
@@ -172,6 +180,7 @@ include = [
|
|
|
172
180
|
typeCheckingMode = "standard"
|
|
173
181
|
reportMissingModuleSource = "none"
|
|
174
182
|
reportMissingImports = "none"
|
|
183
|
+
reportPrivateImportUsage = "none"
|
|
175
184
|
ignore = [
|
|
176
185
|
"src/loom/etl/testing/spark.py",
|
|
177
186
|
]
|
|
@@ -193,9 +202,15 @@ module = [
|
|
|
193
202
|
"findspark",
|
|
194
203
|
"fsspec.*",
|
|
195
204
|
"chispa.*",
|
|
205
|
+
]
|
|
206
|
+
ignore_missing_imports = true
|
|
207
|
+
|
|
208
|
+
[[tool.mypy.overrides]]
|
|
209
|
+
module = [
|
|
196
210
|
"pyarrow.*",
|
|
197
211
|
]
|
|
198
212
|
ignore_missing_imports = true
|
|
213
|
+
follow_imports = "skip"
|
|
199
214
|
|
|
200
215
|
[tool.pytest.ini_options]
|
|
201
216
|
minversion = "8.0"
|
|
@@ -220,7 +235,7 @@ markers = [
|
|
|
220
235
|
|
|
221
236
|
[tool.commitizen]
|
|
222
237
|
name = "cz_conventional_commits"
|
|
223
|
-
version = "0.
|
|
238
|
+
version = "0.9.0"
|
|
224
239
|
tag_format = "v$version"
|
|
225
240
|
version_files = [
|
|
226
241
|
"pyproject.toml:project.version",
|
|
@@ -2,10 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import warnings
|
|
5
6
|
from typing import Any
|
|
7
|
+
from urllib.parse import urlparse
|
|
6
8
|
|
|
7
9
|
from loom.core.model import LoomFrozenStruct
|
|
8
10
|
|
|
11
|
+
_LOCAL_HOSTS = {"127.0.0.1", "localhost", "::1"}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _is_local_endpoint(endpoint: str) -> bool:
|
|
15
|
+
return (urlparse(endpoint).hostname or "") in _LOCAL_HOSTS
|
|
16
|
+
|
|
9
17
|
|
|
10
18
|
class OtelConfig(LoomFrozenStruct, frozen=True):
|
|
11
19
|
"""OpenTelemetry SDK/exporter configuration.
|
|
@@ -29,7 +37,7 @@ class OtelConfig(LoomFrozenStruct, frozen=True):
|
|
|
29
37
|
tracer_version: str = ""
|
|
30
38
|
protocol: str = "http/protobuf"
|
|
31
39
|
endpoint: str = ""
|
|
32
|
-
insecure: bool =
|
|
40
|
+
insecure: bool = False
|
|
33
41
|
headers: dict[str, str] = {}
|
|
34
42
|
resource_attributes: dict[str, str] = {}
|
|
35
43
|
span_attributes: dict[str, str] = {}
|
|
@@ -46,6 +54,13 @@ class OtelConfig(LoomFrozenStruct, frozen=True):
|
|
|
46
54
|
raise ValueError(
|
|
47
55
|
"observability.otel_config.protocol must be either 'http/protobuf' or 'grpc'."
|
|
48
56
|
)
|
|
57
|
+
if self.insecure and self.endpoint and not _is_local_endpoint(self.endpoint):
|
|
58
|
+
warnings.warn(
|
|
59
|
+
f"OtelConfig.insecure=True on non-local endpoint {self.endpoint!r}."
|
|
60
|
+
" Set insecure=False for production deployments.",
|
|
61
|
+
UserWarning,
|
|
62
|
+
stacklevel=2,
|
|
63
|
+
)
|
|
49
64
|
|
|
50
65
|
|
|
51
66
|
__all__ = ["OtelConfig"]
|
|
@@ -23,6 +23,7 @@ from loom.core.model.types import (
|
|
|
23
23
|
DateTime,
|
|
24
24
|
Float,
|
|
25
25
|
Integer,
|
|
26
|
+
JsonStr,
|
|
26
27
|
Numeric,
|
|
27
28
|
String,
|
|
28
29
|
Text,
|
|
@@ -45,6 +46,7 @@ __all__ = [
|
|
|
45
46
|
"Float",
|
|
46
47
|
"Integer",
|
|
47
48
|
"JSON",
|
|
49
|
+
"JsonStr",
|
|
48
50
|
"Postgres",
|
|
49
51
|
"ProjectionField",
|
|
50
52
|
"LoomStructMeta",
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from typing import Annotated
|
|
4
|
+
|
|
3
5
|
from loom.core.model.field import ColumnType
|
|
4
6
|
|
|
5
7
|
|
|
@@ -23,3 +25,12 @@ def DateTime(*, tz: bool = True) -> ColumnType:
|
|
|
23
25
|
|
|
24
26
|
def Numeric(*, precision: int = 10, scale: int = 2) -> ColumnType:
|
|
25
27
|
return ColumnType("Numeric", args=(precision, scale))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class _JsonMarker:
|
|
31
|
+
"""Sentinel that marks a str field as containing serialized JSON."""
|
|
32
|
+
|
|
33
|
+
__slots__ = ()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
JsonStr = Annotated[str, _JsonMarker()]
|
|
@@ -13,10 +13,19 @@ class PrometheusConfig(LoomFrozenStruct, frozen=True, kw_only=True):
|
|
|
13
13
|
"""Prometheus scrape endpoint configuration.
|
|
14
14
|
|
|
15
15
|
Args:
|
|
16
|
-
path: HTTP path where ``/metrics`` is served.
|
|
16
|
+
path: HTTP path where ``/metrics`` is served. Used by REST services
|
|
17
|
+
that mount the scrape endpoint on an existing FastAPI app.
|
|
18
|
+
port: Port for the standalone HTTP scrape server. Used by long-running
|
|
19
|
+
streaming processes that have no existing HTTP server.
|
|
20
|
+
``None`` disables the standalone server (default).
|
|
21
|
+
bind_address: Network interface the standalone scrape server binds to.
|
|
22
|
+
Defaults to ``"127.0.0.1"`` (loopback only). Set to ``"0.0.0.0"``
|
|
23
|
+
only when the Prometheus scraper cannot reach the pod via loopback.
|
|
17
24
|
"""
|
|
18
25
|
|
|
19
26
|
path: str = "/metrics"
|
|
27
|
+
port: int | None = None
|
|
28
|
+
bind_address: str = "127.0.0.1"
|
|
20
29
|
|
|
21
30
|
|
|
22
31
|
class LogObservabilityConfig(LoomFrozenStruct, frozen=True, kw_only=True):
|