loom-kernel 2.15.1__tar.gz → 2.16.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-2.15.1 → loom_kernel-2.16.0}/CHANGELOG.md +43 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/PKG-INFO +1 -1
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/__init__.py +2 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_write_policy.py +31 -5
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/__init__.py +2 -1
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_reader.py +60 -19
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_writer.py +4 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_writer.py +4 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/compiler/__init__.py +9 -0
- loom_kernel-2.15.1/src/loom/etl/runner/filtering.py → loom_kernel-2.16.0/src/loom/etl/compiler/_filter.py +55 -12
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/compiler/_plan.py +24 -1
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/__init__.py +3 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_from.py +10 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/__init__.py +7 -0
- loom_kernel-2.16.0/src/loom/etl/declarative/target/_errors.py +30 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_into.py +24 -6
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_table.py +4 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/runner/core.py +2 -3
- loom_kernel-2.16.0/src/loom/etl/runner/errors.py +7 -0
- loom_kernel-2.16.0/src/loom/etl/runner/filtering.py +38 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/__init__.py +4 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/deploy/_yaml_etls.py +1 -1
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/__init__.py +8 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_assemble.py +10 -2
- loom_kernel-2.15.1/src/loom/etl/runner/errors.py +0 -17
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/.gitignore +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/LICENSE +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/README.md +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/pyproject.toml +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/_concurrency.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/_filters.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/_paths.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/_roles.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/_startup.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/_transport.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/_usecase.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/a2a/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/a2a/_binding.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/a2a/_handlers.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/a2a/_rpc.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/a2a/card.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/a2a/events.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/a2a/server.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/abc.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/bootstrap.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/_compiler.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/_fingerprint.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/_plan.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_capabilities.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_conversation.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_feedable.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_hook.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_instructions.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_limits.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_model_role.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_output.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/compiler/phases/_state.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/declarative/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/declarative/_envelope.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/declarative/_schema.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/declarative/_v1.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/declarative/schemas/agent-spec-v1.schema.json +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/describe.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_a2a.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_capabilities.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_engine.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_escape.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_events.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_guards.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_history.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_instructions.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_limits.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_mcp.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_models.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_native.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_output.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_returns.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_schemas.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/_spec.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/extras/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/extras/a2a.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/extras/handlebars.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/extras/mcp.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/extras/skills.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/provider.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/_shared.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/anthropic.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/bedrock.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/gateway.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/openai.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/engines/pydantic_ai/providers/typesafe.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/etl/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/etl/_batch.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/etl/_columns.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/etl/_frames.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/etl/_ledger.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/etl/_runner.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/etl/_validation.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/fastapi/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/fastapi/endpoints.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/fastapi/response.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/fastapi/streaming.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/inference.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/pricing.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/remote_auth.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/runtime/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/runtime/_bounded.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/runtime/_chain.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/runtime/_conversation.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/runtime/_grants.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/runtime/_handle.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/runtime/_health.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/runtime/_hooks.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/runtime/_lifecycle.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/runtime/_limits.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/runtime/_mcp.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/validate/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/ai/validate/__main__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/celery/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/celery/auto.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/celery/bootstrap.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/celery/config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/celery/constants.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/celery/runner.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/celery/service.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/cli/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/cli/app.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/cli/schema.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/async_bridge.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/authz/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/authz/_decide.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/authz/_grants.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/authz/_roles.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/authz/_scope.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/authz/elevation.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/authz/product.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/backend/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/backend/core_model.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/backend/protocol.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/backend/scoped_ddl.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/backend/sqlalchemy.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/bootstrap/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/bootstrap/kernel.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/_batching.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/_single_flight.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/abc/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/abc/backend.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/abc/config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/abc/dependency.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/calls.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/codec.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/decorators.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/dependency.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/gateway.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/keys.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/memory.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/repository.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/result_codec.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/serializer.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/cache/wiring.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/command/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/command/adapter.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/command/base.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/command/field.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/command/introspection.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/compiler.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/_boto3.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/_includes.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/_resolver_utils.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/binder.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/configurable.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/context.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/keys.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/loader.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/model.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/observability.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/resolver.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/secrets.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/config/ssm.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/contracts/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/contracts/manifest.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/di/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/di/container.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/di/scope.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/discovery/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/discovery/_utils.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/discovery/base.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/discovery/interfaces.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/discovery/manifest.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/discovery/modules.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/engine/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/engine/compilable.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/engine/compiler.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/engine/events.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/engine/executor.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/engine/metrics.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/engine/plan.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/engine/post_commit.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/errors/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/errors/codes.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/errors/errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/expr/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/expr/eval.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/expr/nodes.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/expr/refs.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/identity/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/identity/context.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/identity/identity.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/identity/issuer.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/identity/wire.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/introspection/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/introspection/base.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/introspection/describe.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/job/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/job/callback.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/job/context.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/job/handle.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/job/job.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/job/service.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/locator.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/logger/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/logger/abc.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/logger/config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/logger/registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/logger/structlogger.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/_loom_type.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/base.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/convert.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/enums.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/field.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/introspection.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/partition.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/privilege.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/projection.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/relation.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/scoped.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/struct.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/timestamped.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/types.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/model/types_postgres.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/event.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/observer/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/observer/noop.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/observer/otel.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/observer/structlog.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/otel_ids.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/protocol.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/runtime.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/span.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/observability/topology.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/persistence/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/persistence/abc.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/persistence/none.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/persistence/registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/plugins/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/plugins/entrypoints.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/plugins/optional.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/projection/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/projection/loaders.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/projection/runtime.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/abc/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/abc/cursor.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/abc/errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/abc/query.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/abc/query_compiler.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/abc/repo_for.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/abc/repository.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/abc/session_scope.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/dynamodb/backend.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/dynamodb/repository.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/backend.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/ids.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/query_compiler.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/repository.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/uow.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/mongo/values.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/mutation.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/registration.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/backend.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/migrations/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/migrations/env_template.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/migrations/hook.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/migrations/operations.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/migrations/runners.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/bootstrap.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/elevate.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/guard/0001.sql +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/guard/0002.sql +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/guard/preflight.sql +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/integrity.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/partitions.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/provider.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/schema.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/sources.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/rls/verify.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/session_settings.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/response/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/response/base.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/routing/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/routing/ref.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/routing/resolver.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/runner.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/schema/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/schema/schema_mode.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/schema_names.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/abc/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/abc/contracts.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/abc/errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/caller_bound.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/roles.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/sql/service.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/symbols.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/tracing/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/tracing/context.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/transaction.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/transport/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/transport/adapter.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/uow/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/uow/abc.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/uow/context.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/_predicates.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/agent_markers.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/compute.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/constants.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/factory.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/field_ref.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/invoker.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/keys.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/markers.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/mcp_markers.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/rule.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/core/use_case/use_case.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_format_registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/_common.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/_log.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_merge.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_path_template.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_predicate.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_historify.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_schema.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/_streaming.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/polars/provider.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_historify.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_reader.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_schema.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/backends/spark/provider.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_options.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_paths.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_scope.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/checkpoint/_store.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/compiler/_binding.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/compiler/_compiler.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/compiler/_errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/compiler/_validators.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/compiler/_validators_agents.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/compiler/_validators_config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/compiler/_validators_step.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/_format.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/_read_options.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/_utils.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/_with_agent.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/_write_options.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/expr/_params.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_from_config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/source/_specs.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_client.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_file.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/declarative/target/_temp.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/executor/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/executor/_agents.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/executor/_dispatcher.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/executor/_executor.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/_registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/sources/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_mongo.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/sources/_serialization.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/targets/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/lineage/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/lineage/_config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/lineage/_observer.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/lineage/_records.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/maintenance/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/maintenance/_builder.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/maintenance/_ops.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/maintenance/_protocol.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/maintenance/_runner.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/maintenance/_step.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/pipeline/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_generics.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_params.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_process.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_sql.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_step.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_step_client.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/runner/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/runner/_agents.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/runner/_providers.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/runner/_wiring.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/runner/config_loader.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/runtime/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/runtime/_config_values.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/runtime/contracts.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/schema/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/schema/_contract.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/schema/_schema.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/storage/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/storage/_config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/storage/_file_locator.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/storage/_locator.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/storage/routing.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/testing/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/testing/_result.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/testing/_runners.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/testing/_scenario.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/testing/_stubs.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/etl/testing/spark.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/_async.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/_config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/_ctx.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/_flow_yaml.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/_meta.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/_placeholders.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/_summary.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/deploy/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/deploy/_discovery.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/deploy/_schedule.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/deploy/entrypoint.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_backfill.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_backfill_body.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_body.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_common.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_factory.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_hooks.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_maintenance.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_params.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_run_name.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_runtime.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_signature.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/flow/_stages.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/manifest/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/manifest/_model.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/manifest/_s3.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/manifest/_store.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/notify/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/notify/_event.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/notify/_factory.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/notify/_port.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/notify/_slack.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/observer/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/observer/_flow.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/observer/_logging_bridge.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/observer/_manifest.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prefect/observer/_task_run.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prometheus/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prometheus/_instruments.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prometheus/adapter.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prometheus/kafka.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prometheus/lifecycle.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/prometheus/middleware.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/py.typed +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/_body.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/adapter.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/auth/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/auth/abc.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/auth/config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/auth/jwt.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/auth/middleware.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/autocrud.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/compiler.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/constants.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/cors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/fastapi/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/fastapi/_errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/fastapi/app.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/fastapi/auto.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/fastapi/health.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/fastapi/openapi.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/fastapi/response.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/fastapi/sql.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/middleware.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/model.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/rest/rest_adapter.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_batch_spans.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_operators.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/bytewax/runner.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/compiler/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/compiler/_bindings.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/compiler/_compiler.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/compiler/_errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/compiler/_plan.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/compiler/phases/build_plan.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/compiler/phases/validate.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/core/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/core/_errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/core/_exceptions.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/core/_message.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/core/_tracing.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/core/_typing.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/graph/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/graph/_flow.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_codec.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_errors.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_message.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_record.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/_wire.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/client/_retry.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/mongo/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/mongo/_config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/mongo/_event.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/mongo/_normalize.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_boundary.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_branches.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_decompose.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_fork.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_helpers.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_mongo.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_protocols.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_router.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_shape.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_sink.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_step.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_table/common.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_table/config.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/_with.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/nodes/refs.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/streaming/testing.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/testing/__init__.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/testing/agents.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/testing/golden.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/testing/http_harness.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/testing/in_memory.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/testing/repository_harness.py +0 -0
- {loom_kernel-2.15.1 → loom_kernel-2.16.0}/src/loom/testing/runner.py +0 -0
|
@@ -225,6 +225,11 @@
|
|
|
225
225
|
downstream run inherits the placeholder text and resolves it against its own
|
|
226
226
|
creation time. Without `trigger` the deployment is registered exactly as
|
|
227
227
|
before.
|
|
228
|
+
- **prefect:** `FlowTrigger`, the decoded `trigger` block, is exported from
|
|
229
|
+
`loom.prefect` and `loom.prefect.flow`, and `check_inherited_params(trigger,
|
|
230
|
+
params_type, *, name)` from `loom.prefect.flow`, so CI can check that every
|
|
231
|
+
inherited parameter is a field declared `str`, `date` or `datetime` without
|
|
232
|
+
building the flow.
|
|
228
233
|
|
|
229
234
|
### etl
|
|
230
235
|
|
|
@@ -278,6 +283,36 @@
|
|
|
278
283
|
`MISSING_CONFIG_PARAMS`, `CONFIG_ALIAS_CONFLICT` and
|
|
279
284
|
`UNSUPPORTED_CONFIG_VALUE`. `ETLRunner`, `ETLRunner.from_config`,
|
|
280
285
|
`ETLCompiler` and `ETLExecutor` take `agents=`. Polars only.
|
|
286
|
+
- **etl:** `loom.etl.compiler.filter_plan(plan, include)` returns the plan
|
|
287
|
+
`ETLRunner.run(..., include=...)` executes: a process name keeps the whole
|
|
288
|
+
process, a step name keeps that step, and a name that is neither raises
|
|
289
|
+
`InvalidStageError`, listing the unknown names sorted, so a deployment's
|
|
290
|
+
selection can be checked without running it. A bare string as `include`
|
|
291
|
+
raises `TypeError`. The runner now filters through it. `InvalidStageError`
|
|
292
|
+
is exported from `loom.etl.compiler` as well; it is the same class as
|
|
293
|
+
`loom.etl.runner.InvalidStageError` and `loom.etl.InvalidStageError`.
|
|
294
|
+
- **etl:** `iter_processes`, `iter_steps_in_process` and `iter_all_steps` are
|
|
295
|
+
exported from `loom.etl.compiler`. They flatten a compiled plan in
|
|
296
|
+
execution order, parallel groups in declaration order, so code that walks
|
|
297
|
+
a plan no longer reimplements them over the private `_plan` module.
|
|
298
|
+
- **etl:** `loom.etl.backends.polars.decode_json_columns(frame, json_columns)`
|
|
299
|
+
decodes JSON text columns exactly as the Polars reader does for a source
|
|
300
|
+
declared with `parse_json`, normalising fields whose JSON type changes
|
|
301
|
+
between rows, and returns a frame of the same kind, eager or lazy. The
|
|
302
|
+
reader decodes through it. `FromTable.json_columns` and
|
|
303
|
+
`FromFile.json_columns` expose the declarations it takes, so a test can
|
|
304
|
+
decode a seed as the step would receive it. Spark keeps its `from_json`
|
|
305
|
+
decoding, which has no normalisation to share.
|
|
306
|
+
- **etl:** `IntoTable(...).replace(allow_empty=False)` refuses to wipe a table
|
|
307
|
+
with an empty frame: the writer raises `EmptyReplaceError` (a `ValueError`,
|
|
308
|
+
exported from `loom.etl`, carrying `table_ref`) before it creates or writes
|
|
309
|
+
anything, so a dimension rebuilt from a read that came back empty keeps its
|
|
310
|
+
rows and the step fails. Polars checks the row count of the frame the
|
|
311
|
+
replace already collects, at no extra cost; Spark runs `isEmpty()`, one
|
|
312
|
+
job that stops at the first row, before the write recomputes the frame. On
|
|
313
|
+
Polars a `Null`-typed column still fails first, with `SchemaError`.
|
|
314
|
+
The default, `allow_empty=True`, keeps today's behaviour, and `ReplaceSpec`
|
|
315
|
+
gains the `allow_empty` field.
|
|
281
316
|
|
|
282
317
|
## ⚠ Behaviour changes
|
|
283
318
|
|
|
@@ -368,6 +403,14 @@
|
|
|
368
403
|
which is harmless. The update is one attempt with a 10-second timeout; if
|
|
369
404
|
it fails, the flow logs it at `ERROR` in the run's logs and goes on.
|
|
370
405
|
|
|
406
|
+
### etl
|
|
407
|
+
|
|
408
|
+
- **etl:** the names of `loom.etl.runner.filtering` (`_filter_plan`,
|
|
409
|
+
`_filter_process`, `_collect_all_names`, `_map_pipeline_nodes`,
|
|
410
|
+
`_map_process_nodes`) are deprecated and removed in loom 3.0; each emits a
|
|
411
|
+
`DeprecationWarning` naming its replacement, `loom.etl.compiler.filter_plan`
|
|
412
|
+
or, for `_collect_all_names`, `iter_processes` and `iter_all_steps`.
|
|
413
|
+
|
|
371
414
|
## 🐛 Fixes
|
|
372
415
|
|
|
373
416
|
### core
|
|
@@ -55,6 +55,7 @@ from loom.etl.declarative import (
|
|
|
55
55
|
CsvReadOptions,
|
|
56
56
|
CsvWriteOptions,
|
|
57
57
|
DeletePolicy,
|
|
58
|
+
EmptyReplaceError,
|
|
58
59
|
ExcelReadOptions,
|
|
59
60
|
Format,
|
|
60
61
|
FromConfig,
|
|
@@ -203,6 +204,7 @@ __all__ = [
|
|
|
203
204
|
"HistorifyKeyConflictError",
|
|
204
205
|
"HistorifyDateCollisionError",
|
|
205
206
|
"HistorifyTemporalConflictError",
|
|
207
|
+
"EmptyReplaceError",
|
|
206
208
|
# intermediates
|
|
207
209
|
"CheckpointCleaner",
|
|
208
210
|
"CheckpointScope",
|
|
@@ -15,6 +15,7 @@ from loom.core.logger import get_logger
|
|
|
15
15
|
from loom.etl.declarative.target import (
|
|
16
16
|
AppendSpec,
|
|
17
17
|
ClientSpec,
|
|
18
|
+
EmptyReplaceError,
|
|
18
19
|
FileSpec,
|
|
19
20
|
ReplacePartitionsSpec,
|
|
20
21
|
ReplaceSpec,
|
|
@@ -188,6 +189,7 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
|
|
|
188
189
|
streaming: bool,
|
|
189
190
|
create_partition_cols: tuple[str, ...] = (),
|
|
190
191
|
require_physical_partitions: tuple[str, ...] | None = None,
|
|
192
|
+
allow_empty: bool = True,
|
|
191
193
|
) -> _PreparedWrite[WriteFrameT, PhysicalSchemaT] | None:
|
|
192
194
|
"""Run the shared policy up to the point where the write mode differs.
|
|
193
195
|
|
|
@@ -207,6 +209,10 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
|
|
|
207
209
|
require_physical_partitions: Partition columns the existing table
|
|
208
210
|
must physically carry, or ``None`` to
|
|
209
211
|
skip that check.
|
|
212
|
+
allow_empty: When ``False``, raise
|
|
213
|
+
:class:`EmptyReplaceError` for a
|
|
214
|
+
frame with no rows, before the table
|
|
215
|
+
is created or written.
|
|
210
216
|
|
|
211
217
|
Returns:
|
|
212
218
|
The prepared write when the table already exists and the caller
|
|
@@ -220,7 +226,9 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
|
|
|
220
226
|
schema_mode=schema_mode,
|
|
221
227
|
missing_table_policy=self._missing_table_policy,
|
|
222
228
|
)
|
|
223
|
-
materialized = self._materialize_checked(
|
|
229
|
+
materialized = self._materialize_checked(
|
|
230
|
+
frame, target, streaming, allow_empty=allow_empty
|
|
231
|
+
)
|
|
224
232
|
self._create(
|
|
225
233
|
materialized,
|
|
226
234
|
target,
|
|
@@ -232,7 +240,7 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
|
|
|
232
240
|
self._require_physical_partitions(target, require_physical_partitions)
|
|
233
241
|
aligned = self._align(frame, existing, schema_mode)
|
|
234
242
|
return _PreparedWrite(
|
|
235
|
-
frame=self._materialize_checked(aligned, target, streaming),
|
|
243
|
+
frame=self._materialize_checked(aligned, target, streaming, allow_empty=allow_empty),
|
|
236
244
|
existing_schema=existing,
|
|
237
245
|
)
|
|
238
246
|
|
|
@@ -260,7 +268,11 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
|
|
|
260
268
|
) -> None:
|
|
261
269
|
"""Replace policy: check exists → create OR align → write."""
|
|
262
270
|
prepared = self._prepare_write(
|
|
263
|
-
frame,
|
|
271
|
+
frame,
|
|
272
|
+
target,
|
|
273
|
+
schema_mode=spec.schema_mode,
|
|
274
|
+
streaming=streaming,
|
|
275
|
+
allow_empty=spec.allow_empty,
|
|
264
276
|
)
|
|
265
277
|
if prepared is None:
|
|
266
278
|
return
|
|
@@ -507,15 +519,29 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
|
|
|
507
519
|
_ = frame
|
|
508
520
|
return None
|
|
509
521
|
|
|
522
|
+
@abstractmethod
|
|
523
|
+
def _is_empty(self, frame: WriteFrameT) -> bool:
|
|
524
|
+
"""Whether the materialised *frame* has no rows."""
|
|
525
|
+
|
|
510
526
|
def _materialize_checked(
|
|
511
527
|
self,
|
|
512
528
|
frame: InputFrameT,
|
|
513
529
|
target: ResolvedTarget,
|
|
514
530
|
streaming: bool,
|
|
531
|
+
*,
|
|
532
|
+
allow_empty: bool = True,
|
|
515
533
|
) -> WriteFrameT:
|
|
516
|
-
"""Materialise *frame*, warning when the write carries no rows.
|
|
534
|
+
"""Materialise *frame*, warning when the write carries no rows.
|
|
535
|
+
|
|
536
|
+
Raises:
|
|
537
|
+
EmptyReplaceError: When *allow_empty* is ``False`` and the
|
|
538
|
+
materialised frame has no rows.
|
|
539
|
+
"""
|
|
517
540
|
materialized = self._materialize_for_write(frame, streaming)
|
|
518
|
-
if
|
|
541
|
+
if not allow_empty:
|
|
542
|
+
if self._is_empty(materialized):
|
|
543
|
+
raise EmptyReplaceError(target.logical_ref.ref)
|
|
544
|
+
elif self._row_count_if_cheap(materialized) == 0:
|
|
519
545
|
_log.warning("write_produced_no_rows", target=target.logical_ref.ref)
|
|
520
546
|
return materialized
|
|
521
547
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Polars backend for the Loom ETL framework."""
|
|
2
2
|
|
|
3
3
|
from loom.etl.backends.polars._file_writer import PolarsFileWriter
|
|
4
|
-
from loom.etl.backends.polars._reader import PolarsSourceReader
|
|
4
|
+
from loom.etl.backends.polars._reader import PolarsSourceReader, decode_json_columns
|
|
5
5
|
from loom.etl.backends.polars._schema import PolarsPhysicalSchema, read_delta_physical_schema
|
|
6
6
|
from loom.etl.backends.polars._writer import PolarsTargetWriter
|
|
7
7
|
|
|
@@ -10,5 +10,6 @@ __all__ = [
|
|
|
10
10
|
"PolarsPhysicalSchema",
|
|
11
11
|
"PolarsSourceReader",
|
|
12
12
|
"PolarsTargetWriter",
|
|
13
|
+
"decode_json_columns",
|
|
13
14
|
"read_delta_physical_schema",
|
|
14
15
|
]
|
|
@@ -5,8 +5,8 @@ from __future__ import annotations
|
|
|
5
5
|
import functools
|
|
6
6
|
import json
|
|
7
7
|
import logging
|
|
8
|
-
from collections.abc import Callable
|
|
9
|
-
from typing import TYPE_CHECKING, Any
|
|
8
|
+
from collections.abc import Callable, Iterable
|
|
9
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from loom.etl.io.sources._clickhouse import ClickHouseSourceReader
|
|
@@ -23,6 +23,7 @@ from loom.etl.declarative.source import FileSourceSpec, SourceSpec, TableSourceS
|
|
|
23
23
|
from loom.etl.declarative.source._specs import (
|
|
24
24
|
ClickHouseSourceSpec,
|
|
25
25
|
DynamoDbSourceSpec,
|
|
26
|
+
JsonColumnSpec,
|
|
26
27
|
MongoSourceSpec,
|
|
27
28
|
)
|
|
28
29
|
from loom.etl.runtime.contracts import SourceReader
|
|
@@ -43,6 +44,8 @@ from ._predicate import predicate_to_polars
|
|
|
43
44
|
|
|
44
45
|
_log = logging.getLogger(__name__)
|
|
45
46
|
|
|
47
|
+
_FrameT = TypeVar("_FrameT", pl.DataFrame, pl.LazyFrame)
|
|
48
|
+
|
|
46
49
|
|
|
47
50
|
# ---------------------------------------------------------------------------
|
|
48
51
|
# Polymorphic JSON normalization
|
|
@@ -124,6 +127,49 @@ def _normalize_json_string(json_str: str | None, *, loom_type: LoomType) -> str
|
|
|
124
127
|
return json.dumps(result, ensure_ascii=False)
|
|
125
128
|
|
|
126
129
|
|
|
130
|
+
def decode_json_columns(frame: _FrameT, json_columns: Iterable[JsonColumnSpec]) -> _FrameT:
|
|
131
|
+
"""Decode JSON string columns the way :class:`PolarsSourceReader` does at read time.
|
|
132
|
+
|
|
133
|
+
Each column named in *json_columns* holds JSON text and is replaced by the
|
|
134
|
+
value decoded into its declared :class:`~loom.etl.schema.LoomType`. Rows
|
|
135
|
+
are first normalised to that type, so a field that is a string in some rows
|
|
136
|
+
and an object in others decodes instead of raising
|
|
137
|
+
:exc:`polars.exceptions.ComputeError`. A null or unparseable value decodes
|
|
138
|
+
to null. Other columns pass through unchanged.
|
|
139
|
+
|
|
140
|
+
Use it to reproduce in a test what a step receives from a source declared
|
|
141
|
+
with ``parse_json``.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
frame: Eager or lazy frame holding the JSON text columns.
|
|
145
|
+
json_columns: Column declarations, e.g. ``FromTable(...).json_columns``
|
|
146
|
+
or ``FromFile(...).json_columns``.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
A frame of the same kind as *frame*, or *frame* itself when
|
|
150
|
+
*json_columns* is empty.
|
|
151
|
+
|
|
152
|
+
Example::
|
|
153
|
+
|
|
154
|
+
from loom.etl.backends.polars import decode_json_columns
|
|
155
|
+
|
|
156
|
+
events = FromTable("raw.events").parse_json("payload", Payload)
|
|
157
|
+
decoded = decode_json_columns(raw_frame, events.json_columns)
|
|
158
|
+
"""
|
|
159
|
+
exprs = [
|
|
160
|
+
pl.col(jc.column)
|
|
161
|
+
.map_elements(
|
|
162
|
+
functools.partial(_normalize_json_string, loom_type=jc.loom_type),
|
|
163
|
+
return_dtype=pl.String,
|
|
164
|
+
)
|
|
165
|
+
.str.json_decode(loom_type_to_polars(jc.loom_type))
|
|
166
|
+
for jc in json_columns
|
|
167
|
+
]
|
|
168
|
+
if not exprs:
|
|
169
|
+
return frame
|
|
170
|
+
return frame.with_columns(exprs)
|
|
171
|
+
|
|
172
|
+
|
|
127
173
|
class PolarsSourceReader(SourceReader):
|
|
128
174
|
"""Read table, file, and MongoDB sources using Polars."""
|
|
129
175
|
|
|
@@ -351,21 +397,10 @@ class PolarsSourceReader(SourceReader):
|
|
|
351
397
|
Applies a per-row normalization pass before ``json_decode`` so that
|
|
352
398
|
polymorphic fields (e.g. ``String`` in some rows, ``Object`` in others)
|
|
353
399
|
are coerced to the declared :class:`~loom.etl.schema.LoomType` without
|
|
354
|
-
raising :exc:`polars.exceptions.ComputeError`.
|
|
400
|
+
raising :exc:`polars.exceptions.ComputeError`. See
|
|
401
|
+
:func:`decode_json_columns`.
|
|
355
402
|
"""
|
|
356
|
-
|
|
357
|
-
return frame
|
|
358
|
-
|
|
359
|
-
exprs = [
|
|
360
|
-
pl.col(jc.column)
|
|
361
|
-
.map_elements(
|
|
362
|
-
functools.partial(_normalize_json_string, loom_type=jc.loom_type),
|
|
363
|
-
return_dtype=pl.String,
|
|
364
|
-
)
|
|
365
|
-
.str.json_decode(loom_type_to_polars(jc.loom_type))
|
|
366
|
-
for jc in json_columns
|
|
367
|
-
]
|
|
368
|
-
return frame.with_columns(exprs)
|
|
403
|
+
return decode_json_columns(frame, json_columns)
|
|
369
404
|
|
|
370
405
|
|
|
371
406
|
def _apply_source_schema(frame: pl.LazyFrame, schema: tuple[ColumnSchema, ...]) -> pl.LazyFrame:
|
|
@@ -374,8 +409,8 @@ def _apply_source_schema(frame: pl.LazyFrame, schema: tuple[ColumnSchema, ...])
|
|
|
374
409
|
|
|
375
410
|
|
|
376
411
|
def _apply_json_decode(frame: pl.LazyFrame, json_columns: tuple[Any, ...]) -> pl.LazyFrame:
|
|
377
|
-
"""Compatibility
|
|
378
|
-
return
|
|
412
|
+
"""Compatibility alias of :func:`decode_json_columns`."""
|
|
413
|
+
return decode_json_columns(frame, json_columns)
|
|
379
414
|
|
|
380
415
|
|
|
381
416
|
def execute_sql(frames: dict[str, pl.LazyFrame], query: str) -> pl.LazyFrame:
|
|
@@ -386,4 +421,10 @@ def execute_sql(frames: dict[str, pl.LazyFrame], query: str) -> pl.LazyFrame:
|
|
|
386
421
|
return ctx.execute(query, eager=False)
|
|
387
422
|
|
|
388
423
|
|
|
389
|
-
__all__ = [
|
|
424
|
+
__all__ = [
|
|
425
|
+
"PolarsSourceReader",
|
|
426
|
+
"decode_json_columns",
|
|
427
|
+
"execute_sql",
|
|
428
|
+
"_apply_source_schema",
|
|
429
|
+
"_apply_json_decode",
|
|
430
|
+
]
|
|
@@ -217,6 +217,10 @@ class PolarsTargetWriter(_WritePolicy[pl.LazyFrame, pl.DataFrame, PolarsPhysical
|
|
|
217
217
|
"""Rows in the collected frame."""
|
|
218
218
|
return frame.height
|
|
219
219
|
|
|
220
|
+
def _is_empty(self, frame: pl.DataFrame) -> bool:
|
|
221
|
+
"""Whether the collected frame has no rows."""
|
|
222
|
+
return frame.is_empty()
|
|
223
|
+
|
|
220
224
|
def _materialize_for_write(self, frame: pl.LazyFrame, streaming: bool) -> pl.DataFrame:
|
|
221
225
|
"""Collect lazy frame to DataFrame before Delta write."""
|
|
222
226
|
df = frame.collect(engine="streaming" if streaming else "auto")
|
|
@@ -143,6 +143,10 @@ class SparkTargetWriter(_WritePolicy[DataFrame, DataFrame, SparkPhysicalSchema])
|
|
|
143
143
|
_ = streaming
|
|
144
144
|
return frame
|
|
145
145
|
|
|
146
|
+
def _is_empty(self, frame: DataFrame) -> bool:
|
|
147
|
+
"""Whether *frame* has no rows; runs one Spark job that stops at the first row."""
|
|
148
|
+
return frame.isEmpty()
|
|
149
|
+
|
|
146
150
|
def _predicate_to_sql(self, predicate: Any, params: Any) -> str:
|
|
147
151
|
"""Convert predicate to SQL."""
|
|
148
152
|
return predicate_to_sql(predicate, params)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from loom.etl.compiler._compiler import ETLCompiler
|
|
4
4
|
from loom.etl.compiler._errors import ETLCompilationError, ETLErrorCode
|
|
5
|
+
from loom.etl.compiler._filter import InvalidStageError, filter_plan
|
|
5
6
|
from loom.etl.compiler._plan import (
|
|
6
7
|
AgentBinding,
|
|
7
8
|
ConfigValueBinding,
|
|
@@ -13,6 +14,9 @@ from loom.etl.compiler._plan import (
|
|
|
13
14
|
StepPlan,
|
|
14
15
|
TargetBinding,
|
|
15
16
|
flatten_step_names,
|
|
17
|
+
iter_all_steps,
|
|
18
|
+
iter_processes,
|
|
19
|
+
iter_steps_in_process,
|
|
16
20
|
)
|
|
17
21
|
from loom.etl.compiler._validators import (
|
|
18
22
|
StepCompilationContext,
|
|
@@ -31,6 +35,7 @@ __all__ = [
|
|
|
31
35
|
"ETLCompiler",
|
|
32
36
|
"ETLCompilationError",
|
|
33
37
|
"ETLErrorCode",
|
|
38
|
+
"InvalidStageError",
|
|
34
39
|
"StepPlan",
|
|
35
40
|
"ProcessPlan",
|
|
36
41
|
"PipelinePlan",
|
|
@@ -41,7 +46,11 @@ __all__ = [
|
|
|
41
46
|
"ParallelStepGroup",
|
|
42
47
|
"ParallelProcessGroup",
|
|
43
48
|
"StepCompilationContext",
|
|
49
|
+
"filter_plan",
|
|
44
50
|
"flatten_step_names",
|
|
51
|
+
"iter_all_steps",
|
|
52
|
+
"iter_processes",
|
|
53
|
+
"iter_steps_in_process",
|
|
45
54
|
"validate_execute_signature",
|
|
46
55
|
"validate_param_exprs",
|
|
47
56
|
"validate_params_compat",
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
"""Plan filtering
|
|
1
|
+
"""Plan filtering: keep the steps and processes a run selects by name.
|
|
2
|
+
|
|
3
|
+
Internal module — import :func:`filter_plan` and :class:`InvalidStageError`
|
|
4
|
+
from :mod:`loom.etl.compiler`.
|
|
5
|
+
"""
|
|
2
6
|
|
|
3
7
|
from __future__ import annotations
|
|
4
8
|
|
|
5
|
-
from collections.abc import Callable
|
|
9
|
+
from collections.abc import Callable, Iterable
|
|
6
10
|
|
|
7
11
|
from loom.etl.compiler._plan import (
|
|
8
12
|
ParallelProcessGroup,
|
|
@@ -15,26 +19,62 @@ from loom.etl.compiler._plan import (
|
|
|
15
19
|
iter_all_steps,
|
|
16
20
|
iter_processes,
|
|
17
21
|
)
|
|
18
|
-
from loom.etl.runner.errors import InvalidStageError
|
|
19
22
|
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
"""
|
|
24
|
+
class InvalidStageError(ValueError):
|
|
25
|
+
"""Raised when *include* names a step or process absent from the compiled plan.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
include: The names that match no step or process.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, include: frozenset[str]) -> None:
|
|
32
|
+
super().__init__(
|
|
33
|
+
f"No steps or processes match include={sorted(include)!r}. "
|
|
34
|
+
"Check that the names match the class names of your ETLStep or ETLProcess subclasses."
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def filter_plan(plan: PipelinePlan, include: Iterable[str]) -> PipelinePlan:
|
|
39
|
+
"""Return a new plan keeping only the steps and processes named in *include*.
|
|
40
|
+
|
|
41
|
+
This is the selection :meth:`~loom.etl.runner.ETLRunner.run` applies for
|
|
42
|
+
``include=``. A process name keeps the whole process; a step name keeps
|
|
43
|
+
that step inside its process. A process left with no step is dropped, and
|
|
44
|
+
a parallel group left with one member becomes that member. Execution
|
|
45
|
+
order and the remaining parallel groups are preserved.
|
|
23
46
|
|
|
24
47
|
Args:
|
|
25
|
-
plan:
|
|
26
|
-
|
|
48
|
+
plan: Compiled pipeline plan, as returned by
|
|
49
|
+
:meth:`~loom.etl.compiler.ETLCompiler.compile`.
|
|
50
|
+
include: Class names of steps or processes to keep. A bare string is
|
|
51
|
+
refused rather than read as its characters.
|
|
27
52
|
|
|
28
53
|
Returns:
|
|
29
|
-
|
|
54
|
+
A new :class:`PipelinePlan`; *plan* is not modified.
|
|
30
55
|
|
|
31
56
|
Raises:
|
|
32
|
-
|
|
57
|
+
TypeError: When *include* is a ``str``.
|
|
58
|
+
InvalidStageError: When a name in *include* is neither a step nor a
|
|
59
|
+
process of *plan*.
|
|
60
|
+
|
|
61
|
+
Example::
|
|
62
|
+
|
|
63
|
+
>>> from loom.etl.compiler import ETLCompiler, filter_plan, iter_all_steps
|
|
64
|
+
>>> plan = filter_plan(ETLCompiler().compile(MyPipeline), {"LoadStep"})
|
|
65
|
+
>>> [step.step_type.__name__ for step in iter_all_steps(plan)]
|
|
66
|
+
['LoadStep']
|
|
33
67
|
"""
|
|
34
|
-
|
|
68
|
+
if isinstance(include, str):
|
|
69
|
+
raise TypeError(
|
|
70
|
+
f"filter_plan() takes an iterable of names, not the string {include!r}; "
|
|
71
|
+
f"wrap it, e.g. include={{{include!r}}}."
|
|
72
|
+
)
|
|
73
|
+
names = frozenset(include)
|
|
74
|
+
unknown = names - _collect_all_names(plan)
|
|
35
75
|
if unknown:
|
|
36
|
-
raise InvalidStageError(
|
|
37
|
-
nodes = _map_pipeline_nodes(plan.nodes, lambda proc: _filter_process(proc,
|
|
76
|
+
raise InvalidStageError(unknown)
|
|
77
|
+
nodes = _map_pipeline_nodes(plan.nodes, lambda proc: _filter_process(proc, names))
|
|
38
78
|
return PipelinePlan(
|
|
39
79
|
pipeline_type=plan.pipeline_type,
|
|
40
80
|
params_type=plan.params_type,
|
|
@@ -105,3 +145,6 @@ def _map_process_nodes(
|
|
|
105
145
|
elif kept:
|
|
106
146
|
result.append(ParallelStepGroup(plans=kept))
|
|
107
147
|
return tuple(result)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
__all__ = ["InvalidStageError", "filter_plan"]
|
|
@@ -163,6 +163,12 @@ def iter_processes(plan: PipelinePlan) -> Iterator[ProcessPlan]:
|
|
|
163
163
|
|
|
164
164
|
Flattens top-level :class:`ParallelProcessGroup` nodes while preserving
|
|
165
165
|
the declared order within each group.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
plan: Compiled pipeline plan.
|
|
169
|
+
|
|
170
|
+
Yields:
|
|
171
|
+
Each :class:`ProcessPlan` of *plan*, once.
|
|
166
172
|
"""
|
|
167
173
|
for node in plan.nodes:
|
|
168
174
|
match node:
|
|
@@ -177,6 +183,12 @@ def iter_steps_in_process(plan: ProcessPlan) -> Iterator[StepPlan]:
|
|
|
177
183
|
|
|
178
184
|
Flattens :class:`ParallelStepGroup` nodes while preserving the declared
|
|
179
185
|
order within each group.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
plan: Compiled process plan, e.g. one yielded by :func:`iter_processes`.
|
|
189
|
+
|
|
190
|
+
Yields:
|
|
191
|
+
Each :class:`StepPlan` of *plan*, once.
|
|
180
192
|
"""
|
|
181
193
|
for node in plan.nodes:
|
|
182
194
|
match node:
|
|
@@ -187,7 +199,18 @@ def iter_steps_in_process(plan: ProcessPlan) -> Iterator[StepPlan]:
|
|
|
187
199
|
|
|
188
200
|
|
|
189
201
|
def iter_all_steps(plan: PipelinePlan) -> Iterator[StepPlan]:
|
|
190
|
-
"""Yield every concrete step plan in a pipeline.
|
|
202
|
+
"""Yield every concrete step plan in a pipeline, in execution order.
|
|
203
|
+
|
|
204
|
+
Equivalent to :func:`iter_steps_in_process` over each process yielded by
|
|
205
|
+
:func:`iter_processes`.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
plan: Compiled pipeline plan.
|
|
209
|
+
|
|
210
|
+
Yields:
|
|
211
|
+
Each :class:`StepPlan` of *plan*; a step class listed by two
|
|
212
|
+
processes is yielded once per process.
|
|
213
|
+
"""
|
|
191
214
|
for proc in iter_processes(plan):
|
|
192
215
|
yield from iter_steps_in_process(proc)
|
|
193
216
|
|
|
@@ -32,6 +32,7 @@ from .source import (
|
|
|
32
32
|
)
|
|
33
33
|
from .target import (
|
|
34
34
|
DeletePolicy,
|
|
35
|
+
EmptyReplaceError,
|
|
35
36
|
HistorifyDateCollisionError,
|
|
36
37
|
HistorifyInputMode,
|
|
37
38
|
HistorifyKeyConflictError,
|
|
@@ -91,4 +92,6 @@ __all__ = [
|
|
|
91
92
|
"HistorifyKeyConflictError",
|
|
92
93
|
"HistorifyDateCollisionError",
|
|
93
94
|
"HistorifyTemporalConflictError",
|
|
95
|
+
# write errors
|
|
96
|
+
"EmptyReplaceError",
|
|
94
97
|
]
|
|
@@ -99,6 +99,11 @@ class FromTable:
|
|
|
99
99
|
"""Declared filter predicates."""
|
|
100
100
|
return self._predicates
|
|
101
101
|
|
|
102
|
+
@property
|
|
103
|
+
def json_columns(self) -> tuple[JsonColumnSpec, ...]:
|
|
104
|
+
"""JSON columns declared with :meth:`parse_json`, in declaration order."""
|
|
105
|
+
return self._json_columns
|
|
106
|
+
|
|
102
107
|
def with_schema(self, schema: SchemaContract) -> FromTable:
|
|
103
108
|
"""Return a new ``FromTable`` with a user-declared source schema.
|
|
104
109
|
|
|
@@ -298,6 +303,11 @@ class FromFile:
|
|
|
298
303
|
"""File path template."""
|
|
299
304
|
return self._path
|
|
300
305
|
|
|
306
|
+
@property
|
|
307
|
+
def json_columns(self) -> tuple[JsonColumnSpec, ...]:
|
|
308
|
+
"""JSON columns declared with :meth:`parse_json`, in declaration order."""
|
|
309
|
+
return self._json_columns
|
|
310
|
+
|
|
301
311
|
@property
|
|
302
312
|
def format(self) -> Format:
|
|
303
313
|
"""I/O format."""
|
|
@@ -35,9 +35,14 @@ SCD2 support types:
|
|
|
35
35
|
* :class:`HistorifyKeyConflictError` — duplicate entity state vectors
|
|
36
36
|
* :class:`HistorifyDateCollisionError` — same-date LOG mode collisions
|
|
37
37
|
* :class:`HistorifyTemporalConflictError` — future-open records without re-weave
|
|
38
|
+
|
|
39
|
+
Write errors:
|
|
40
|
+
|
|
41
|
+
* :class:`EmptyReplaceError` — ``replace(allow_empty=False)`` received no rows
|
|
38
42
|
"""
|
|
39
43
|
|
|
40
44
|
from loom.etl.declarative.target._client import ClientSpec, IntoClient
|
|
45
|
+
from loom.etl.declarative.target._errors import EmptyReplaceError
|
|
41
46
|
from loom.etl.declarative.target._file import FileSpec
|
|
42
47
|
from loom.etl.declarative.target._history import (
|
|
43
48
|
DeletePolicy,
|
|
@@ -127,4 +132,6 @@ __all__ = [
|
|
|
127
132
|
"HistorifyKeyConflictError",
|
|
128
133
|
"HistorifyDateCollisionError",
|
|
129
134
|
"HistorifyTemporalConflictError",
|
|
135
|
+
# write errors
|
|
136
|
+
"EmptyReplaceError",
|
|
130
137
|
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Errors raised by backend writers for table targets.
|
|
2
|
+
|
|
3
|
+
Internal module — import from :mod:`loom.etl.declarative.target` or :mod:`loom.etl`.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class EmptyReplaceError(ValueError):
|
|
10
|
+
"""Raised when a ``replace(allow_empty=False)`` target receives no rows.
|
|
11
|
+
|
|
12
|
+
The table is left as it was: the check runs after the frame is
|
|
13
|
+
materialised and before anything is written or created.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
table_ref: Logical reference of the target table.
|
|
17
|
+
|
|
18
|
+
Attributes:
|
|
19
|
+
table_ref: Logical reference of the target table.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, table_ref: str) -> None:
|
|
23
|
+
self.table_ref = table_ref
|
|
24
|
+
super().__init__(
|
|
25
|
+
f"Refusing to replace {table_ref!r} with an empty frame: the target declares "
|
|
26
|
+
"replace(allow_empty=False). The table was not modified."
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
__all__ = ["EmptyReplaceError"]
|
|
@@ -108,6 +108,7 @@ class IntoTable:
|
|
|
108
108
|
*,
|
|
109
109
|
schema: SchemaMode = SchemaMode.STRICT,
|
|
110
110
|
streaming: bool = False,
|
|
111
|
+
allow_empty: bool = True,
|
|
111
112
|
) -> IntoTable:
|
|
112
113
|
"""Write mode: full replace of the target table.
|
|
113
114
|
|
|
@@ -115,16 +116,33 @@ class IntoTable:
|
|
|
115
116
|
partition-scoped overwrite or :meth:`replace_where` for predicate-scoped.
|
|
116
117
|
|
|
117
118
|
Args:
|
|
118
|
-
schema:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
streaming:
|
|
122
|
-
|
|
119
|
+
schema: Schema evolution strategy. Use
|
|
120
|
+
:attr:`~SchemaMode.OVERWRITE` to replace the table
|
|
121
|
+
schema entirely alongside the data.
|
|
122
|
+
streaming: When ``True`` the Polars backend writes via an Arrow
|
|
123
|
+
``RecordBatchReader`` instead of materialising.
|
|
124
|
+
allow_empty: When ``False``, a frame with no rows raises
|
|
125
|
+
:class:`~loom.etl.EmptyReplaceError` and the table
|
|
126
|
+
is neither replaced nor created. Use it for a
|
|
127
|
+
table, such as a dimension, that an empty read must
|
|
128
|
+
never wipe. Defaults to ``True``: an empty frame
|
|
129
|
+
replaces the table with an empty one.
|
|
123
130
|
|
|
124
131
|
Returns:
|
|
125
132
|
New ``IntoTable`` with REPLACE mode.
|
|
133
|
+
|
|
134
|
+
Example::
|
|
135
|
+
|
|
136
|
+
target = IntoTable("silver.dim_dealer").replace(allow_empty=False)
|
|
126
137
|
"""
|
|
127
|
-
return self._with(
|
|
138
|
+
return self._with(
|
|
139
|
+
ReplaceSpec(
|
|
140
|
+
table_ref=self._ref,
|
|
141
|
+
schema_mode=schema,
|
|
142
|
+
streaming=streaming,
|
|
143
|
+
allow_empty=allow_empty,
|
|
144
|
+
)
|
|
145
|
+
)
|
|
128
146
|
|
|
129
147
|
def replace_partitions(
|
|
130
148
|
self,
|