loom-kernel 8.0.0__tar.gz → 8.0.1__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-8.0.0 → loom_kernel-8.0.1}/CHANGELOG.md +52 -3
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/PKG-INFO +1 -1
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/backend/sqlalchemy.py +8 -4
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/introspection.py +10 -4
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/types.py +10 -2
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/compiler/_plan.py +0 -4
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/compiler/phases/build_plan.py +12 -10
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/compiler/phases/validate.py +85 -81
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_boundary.py +0 -7
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_mongo.py +0 -3
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_shape.py +3 -4
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_step.py +4 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/.gitignore +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/LICENSE +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/README.md +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/pyproject.toml +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/_concurrency.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/_filters.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/_paths.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/_roles.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/_startup.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/_transport.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/_usecase.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/a2a/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/a2a/_binding.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/a2a/_handlers.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/a2a/_rpc.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/a2a/card.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/a2a/events.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/a2a/server.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/abc.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/bootstrap.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/_compiler.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/_fingerprint.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/_plan.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/phases/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/phases/_capabilities.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/phases/_conversation.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/phases/_feedable.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/phases/_hook.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/phases/_instructions.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/phases/_limits.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/phases/_model_role.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/phases/_output.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/compiler/phases/_state.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/declarative/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/declarative/_envelope.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/declarative/_schema.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/declarative/_v1.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/declarative/schemas/agent-spec-v1.schema.json +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/describe.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_a2a.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_capabilities.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_engine.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_escape.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_events.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_guards.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_history.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_instructions.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_limits.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_mcp.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_models.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_native.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_output.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_returns.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_schemas.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/_spec.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/extras/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/extras/a2a.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/extras/handlebars.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/extras/mcp.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/extras/skills.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/provider.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/providers/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/providers/_shared.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/providers/anthropic.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/providers/bedrock.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/providers/gateway.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/providers/openai.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/engines/pydantic_ai/providers/typesafe.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/etl/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/etl/_batch.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/etl/_columns.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/etl/_frames.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/etl/_ledger.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/etl/_runner.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/etl/_validation.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/fastapi/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/fastapi/endpoints.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/fastapi/response.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/fastapi/streaming.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/inference.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/pricing.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/remote_auth.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/runtime/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/runtime/_bounded.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/runtime/_chain.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/runtime/_conversation.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/runtime/_grants.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/runtime/_handle.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/runtime/_health.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/runtime/_hooks.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/runtime/_lifecycle.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/runtime/_limits.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/runtime/_mcp.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/validate/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/ai/validate/__main__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/celery/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/celery/auto.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/celery/bootstrap.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/celery/config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/celery/constants.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/celery/runner.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/celery/service.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/cli/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/cli/app.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/cli/check.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/cli/schema.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/async_bridge.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/authz/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/authz/_decide.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/authz/_grants.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/authz/_roles.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/authz/_scope.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/authz/elevation.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/authz/product.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/backend/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/backend/core_model.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/backend/protocol.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/backend/scoped_ddl.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/bootstrap/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/bootstrap/bootstrap.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/bootstrap/kernel.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/_batching.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/_single_flight.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/abc/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/abc/backend.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/abc/config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/abc/dependency.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/calls.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/codec.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/decorators.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/dependency.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/gateway.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/keys.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/memory.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/repository.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/result_codec.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/serializer.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/cache/wiring.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/checks.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/command/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/command/adapter.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/command/base.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/command/field.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/command/introspection.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/compiler.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/_boto3.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/_includes.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/_resolver_utils.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/binder.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/configurable.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/context.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/keys.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/loader.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/model.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/observability.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/overrides.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/resolver.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/secrets.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/config/ssm.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/contracts/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/contracts/manifest.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/di/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/di/container.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/di/scope.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/discovery/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/discovery/_utils.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/discovery/base.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/discovery/interfaces.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/discovery/manifest.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/discovery/modules.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/engine/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/engine/compilable.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/engine/compiler.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/engine/events.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/engine/executor.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/engine/metrics.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/engine/plan.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/engine/post_commit.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/environment.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/errors/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/errors/codes.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/errors/errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/expr/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/expr/eval.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/expr/nodes.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/expr/refs.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/identity/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/identity/context.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/identity/identity.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/identity/issuer.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/identity/wire.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/introspection/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/introspection/base.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/introspection/describe.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/job/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/job/callback.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/job/context.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/job/handle.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/job/job.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/job/service.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/locator.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/logger/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/logger/abc.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/logger/checks.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/logger/config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/logger/registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/logger/structlogger.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/_json_schema.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/_loom_type.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/base.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/convert.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/enums.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/field.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/partition.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/privilege.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/projection.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/relation.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/scoped.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/struct.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/timestamped.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/model/types_postgres.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/event.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/observer/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/observer/noop.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/observer/otel.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/observer/structlog.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/otel_ids.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/protocol.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/runtime.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/span.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/observability/topology.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/persistence/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/persistence/abc.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/persistence/none.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/persistence/registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/plugins/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/plugins/entrypoints.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/plugins/optional.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/projection/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/projection/loaders.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/projection/runtime.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/abc/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/abc/cursor.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/abc/errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/abc/query.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/abc/query_compiler.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/abc/repo_for.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/abc/repository.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/abc/session_scope.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/dynamodb/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/dynamodb/backend.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/dynamodb/registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/dynamodb/repository.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/dynamodb/uow.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/mongo/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/mongo/backend.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/mongo/ids.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/mongo/query_compiler.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/mongo/registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/mongo/repository.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/mongo/uow.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/mongo/values.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/mutation.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/registration.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/backend.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/migrations/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/migrations/env_template.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/migrations/hook.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/migrations/operations.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/migrations/runners.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/model.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/bootstrap.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/elevate.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/guard/0001.sql +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/guard/0002.sql +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/guard/preflight.sql +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/integrity.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/partitions.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/provider.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/schema.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/sources.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/rls/verify.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/session_settings.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/repository/sqlalchemy/values.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/response/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/response/base.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/routing/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/routing/ref.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/routing/resolver.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/runner.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/schema/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/schema/schema_mode.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/schema_names.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/abc/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/abc/contracts.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/abc/errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/caller_bound.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/clickhouse/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/clickhouse/_client.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/clickhouse/executor.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/clickhouse/registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/roles.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/sql/service.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/symbols.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/tracing/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/tracing/context.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/transaction.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/transport/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/transport/adapter.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/uow/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/uow/abc.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/uow/context.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/_predicates.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/agent_markers.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/compute.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/constants.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/factory.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/field_ref.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/invoker.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/keys.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/markers.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/mcp_markers.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/outcome.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/rule.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/core/use_case/use_case.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/_uri.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_format_registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_historify/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_historify/_common.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_historify/_log.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_historify/_ops.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_historify/_transform.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_merge.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_path_template.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_predicate.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/_write_policy.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/_dtype.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/_file_writer.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/_frame.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/_historify.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/_predicate.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/_reader.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/_schema.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/_streaming.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/_writer.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/polars/provider.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/spark/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/spark/_dtype.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/spark/_historify.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/spark/_reader.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/spark/_schema.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/spark/_writer.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/backends/spark/provider.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/checkpoint/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/checkpoint/_cleaners.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/checkpoint/_options.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/checkpoint/_paths.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/checkpoint/_scope.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/checkpoint/_store.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/compiler/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/compiler/_binding.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/compiler/_compiler.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/compiler/_errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/compiler/_filter.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/compiler/_plan.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/compiler/_validators.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/compiler/_validators_agents.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/compiler/_validators_config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/compiler/_validators_plan.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/compiler/_validators_step.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/_format.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/_read_options.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/_utils.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/_with_agent.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/_write_options.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/expr/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/expr/_params.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/expr/_predicate.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/expr/_refs.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/source/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/source/_from.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/source/_from_config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/source/_specs.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_client.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_file.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_history/_report.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_into.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_table.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/declarative/target/_temp.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/executor/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/executor/_agents.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/executor/_dispatcher.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/executor/_executor.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/_registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/sources/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/sources/_clickhouse.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/sources/_dynamodb.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/sources/_mongo.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/sources/_serialization.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/targets/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/io/targets/_clickhouse.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/lineage/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/lineage/_config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/lineage/_observer.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/lineage/_records.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/lineage/sinks/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/lineage/sinks/_table.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/lineage/sinks/_writer.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/maintenance/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/maintenance/_builder.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/maintenance/_ops.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/maintenance/_protocol.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/maintenance/_runner.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/maintenance/_step.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/maintenance/backends/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/pipeline/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/pipeline/_generics.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/pipeline/_params.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/pipeline/_pipeline.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/pipeline/_process.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/pipeline/_sql.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/pipeline/_step.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/pipeline/_step_client.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/pipeline/_step_sql.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/runner/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/runner/_agents.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/runner/_providers.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/runner/_wiring.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/runner/config_loader.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/runner/core.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/runner/errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/runner/filtering.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/runtime/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/runtime/_config_values.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/runtime/contracts.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/schema/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/schema/_contract.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/schema/_schema.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/storage/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/storage/_config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/storage/_file_locator.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/storage/_locator.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/storage/routing.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/testing/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/testing/_result.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/testing/_runners.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/testing/_scenario.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/testing/_stubs.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/etl/testing/spark.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/_async.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/_config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/_ctx.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/_flow_yaml.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/_meta.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/_placeholders.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/_summary.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/deploy/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/deploy/_discovery.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/deploy/_schedule.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/deploy/_yaml_etls.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/deploy/entrypoint.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_assemble.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_backfill.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_backfill_body.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_body.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_common.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_factory.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_hooks.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_maintenance.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_params.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_run_name.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_runtime.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_signature.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/flow/_stages.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/manifest/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/manifest/_model.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/manifest/_s3.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/manifest/_store.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/notify/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/notify/_event.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/notify/_factory.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/notify/_format.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/notify/_port.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/notify/_slack.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/notify/_sns.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/observer/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/observer/_flow.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/observer/_logging_bridge.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/observer/_manifest.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prefect/observer/_task_run.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prometheus/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prometheus/_instruments.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prometheus/adapter.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prometheus/kafka.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prometheus/lifecycle.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/prometheus/middleware.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/py.typed +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/_body.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/adapter.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/auth/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/auth/abc.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/auth/config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/auth/jwt.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/auth/middleware.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/autocrud.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/checks.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/compiler.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/constants.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/cors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/fastapi/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/fastapi/_errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/fastapi/_exclusions.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/fastapi/app.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/fastapi/auto.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/fastapi/health.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/fastapi/openapi.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/fastapi/response.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/fastapi/router_runtime.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/fastapi/sql.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/middleware.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/model.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/rest/rest_adapter.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/_adapter.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/_batch_spans.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/_errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/_operators.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/bytewax/runner.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/compiler/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/compiler/_bindings.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/compiler/_compiler.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/compiler/_errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/core/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/core/_errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/core/_exceptions.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/core/_message.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/core/_tracing.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/core/_typing.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/graph/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/graph/_flow.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/_codec.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/_config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/_errors.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/_key_resolver.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/_message.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/_record.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/_wire.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/client/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/client/_consumer.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/client/_producer.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/client/_protocol.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/client/_retry.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/message/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/message/_consumer.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/message/_producer.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/kafka/message/_protocol.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/mongo/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/mongo/_config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/mongo/_event.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/mongo/_normalize.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_branches.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_broadcast.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_capabilities.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_decompose.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_expand_routes.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_expr_eval.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_fork.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_helpers.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_protocols.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_router.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_sink.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_table/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_table/common.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_table/config.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/_with.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/nodes/refs.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/streaming/testing.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/testing/__init__.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/testing/agents.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/testing/golden.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/testing/http_harness.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/testing/in_memory.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/testing/repository_harness.py +0 -0
- {loom_kernel-8.0.0 → loom_kernel-8.0.1}/src/loom/testing/runner.py +0 -0
|
@@ -459,6 +459,16 @@
|
|
|
459
459
|
|
|
460
460
|
### core
|
|
461
461
|
|
|
462
|
+
- **core:** a `Decimal` field, plain or optional, declares its column type: a
|
|
463
|
+
SQLAlchemy model with an undeclared one is refused when it is compiled,
|
|
464
|
+
naming the field. loom inferred `NUMERIC(10, 2)`, and Postgres silently
|
|
465
|
+
rounds a value to that scale (`1.2345` is stored as `1.23`) and refuses one
|
|
466
|
+
past that precision. Migration: declare it, e.g.
|
|
467
|
+
`Annotated[Decimal, Numeric(precision=20, scale=6)]` or
|
|
468
|
+
`ColumnField(Numeric(precision=20, scale=6))`; `Numeric()` with no
|
|
469
|
+
precision is now an unbounded `NUMERIC` instead of `NUMERIC(10, 2)`, and
|
|
470
|
+
`Numeric(scale=...)` without a precision raises `ValueError`, as SQLAlchemy
|
|
471
|
+
would drop the scale.
|
|
462
472
|
- **core:** `sql_endpoint.auth` admits only `identity` and `external`;
|
|
463
473
|
`auth: jwt` is refused when the config is loaded, and the alias and its
|
|
464
474
|
`DeprecationWarning` are gone. Migration: replace `auth: jwt` with
|
|
@@ -949,6 +959,22 @@
|
|
|
949
959
|
|
|
950
960
|
### streaming
|
|
951
961
|
|
|
962
|
+
- **streaming:** `FromTopic`, `FromMultiTypeTopic`, `FromMongoCDC` and
|
|
963
|
+
`IntoTopic` take no `shape`, `CompiledSingleSource`, `CompiledMultiSource`
|
|
964
|
+
and `CompiledMongoCDCSource` have no `shape` field, and `StreamShape.MANY`
|
|
965
|
+
is removed. The runtime never read a declared shape: every source emits one
|
|
966
|
+
record per message, so a source declared `BATCH` was shape-checked as
|
|
967
|
+
batches while its nodes received records, and an `IntoTopic` writes one
|
|
968
|
+
record per message whatever it declared. Every flow now starts as a record
|
|
969
|
+
stream, and an `IntoTopic` ends its path (shape `none`). Migration: drop
|
|
970
|
+
`shape=`; to work on batches, use `CollectBatch` and, back to records,
|
|
971
|
+
`ForEach`.
|
|
972
|
+
- **streaming:** a batch reaching a `Drain` or a `Broadcast` fails compilation
|
|
973
|
+
with `SHAPE_MISMATCH`, whatever the delivery. Under at-most-once delivery
|
|
974
|
+
`CollectBatch → Drain` compiled and dropped the batch; under at-least-once
|
|
975
|
+
the batch's offsets never completed. Under at-least-once a `Broadcast` with
|
|
976
|
+
more than one route raised `TypeError` (`Expected Message, got list`) on a
|
|
977
|
+
batch. Put a `ForEach` before the node.
|
|
952
978
|
- **streaming:** `BatchExpandStep.execute` returns one list of payloads per
|
|
953
979
|
message of its batch, in batch order, instead of one flat list. List `i`
|
|
954
980
|
holds what `messages[i]` expands into; each output takes that message's
|
|
@@ -975,9 +1001,11 @@
|
|
|
975
1001
|
`CompileIssue` instead), `loom_message_type()` is gone, and
|
|
976
1002
|
`CompilationIssue.prefixed()` is removed. Messages keep their text.
|
|
977
1003
|
- **streaming:** a `Broadcast` followed by another node reports
|
|
978
|
-
`BROADCAST_NOT_LAST` with component `broadcast`, at the top level
|
|
979
|
-
branch
|
|
980
|
-
|
|
1004
|
+
`BROADCAST_NOT_LAST` with component `broadcast`, at the top level and in a
|
|
1005
|
+
branch. It used to report `TERMINAL_NOT_LAST` with component `Broadcast`. In
|
|
1006
|
+
a Router branch a `Broadcast` reports `ROUTER_BRANCH_UNSAFE_NODE`, and one
|
|
1007
|
+
followed by another node also `TERMINAL_NOT_LAST` with component
|
|
1008
|
+
`router branch <label> > Broadcast`.
|
|
981
1009
|
- **streaming:** a Router branch that ends in `IntoTopic`, `IntoTable` (any
|
|
982
1010
|
`IntoSink`) or `Drain` hands the message to that terminal. The branch's
|
|
983
1011
|
terminal was skipped: with a flow `output` the message went to the output
|
|
@@ -1364,6 +1392,27 @@
|
|
|
1364
1392
|
|
|
1365
1393
|
### streaming
|
|
1366
1394
|
|
|
1395
|
+
- **streaming:** `ForEach` accepts the batch a `BatchStep` produces, so
|
|
1396
|
+
`CollectBatch → BatchStep → ForEach → IntoTopic` compiles; it failed with
|
|
1397
|
+
`shape mismatch: expected many but got batch before ForEach`. Under
|
|
1398
|
+
at-least-once delivery each offset completes once, after its write is
|
|
1399
|
+
flushed.
|
|
1400
|
+
- **streaming:** a batch reaching a node that takes records fails compilation
|
|
1401
|
+
with `SHAPE_MISMATCH`: `IntoTopic`, `IntoTable` (any `IntoSink`), `Fork`,
|
|
1402
|
+
`ExpandRoutes`, `CollectBatch` (it groups records), the flow `output`
|
|
1403
|
+
(component `flow.output`, field `output`)
|
|
1404
|
+
and a Broadcast route `output` (component `broadcast branch <n> > output`,
|
|
1405
|
+
field `output`). Such flows used to compile. `CollectBatch → BatchStep →
|
|
1406
|
+
IntoTopic` raised `'list' object has no attribute 'meta'` at runtime. Put a
|
|
1407
|
+
`ForEach` before the node. `Drain` and `Broadcast` are under Behaviour
|
|
1408
|
+
changes.
|
|
1409
|
+
- **streaming:** a `BatchExpandStep` subclass outputs records to the shape
|
|
1410
|
+
check. The compiler matched step output shapes by exact type, so every step
|
|
1411
|
+
subclass kept the incoming shape and a record step after a
|
|
1412
|
+
`BatchExpandStep` failed with `expected record but got batch`. The shape
|
|
1413
|
+
check reads a step's `input_shape` and `output_shape` from its class,
|
|
1414
|
+
except in a Router branch: there a `BatchStep` runs one record at a time,
|
|
1415
|
+
on a one-message batch, so it is record to record.
|
|
1367
1416
|
- **streaming:** a `Broadcast` is validated as a `Broadcast`. The compiler
|
|
1368
1417
|
treated it as a plain terminal, so the nodes of its branches were never
|
|
1369
1418
|
shape-checked. A branch with a shape mismatch, such as a record step after
|
|
@@ -292,15 +292,19 @@ def _compile_model(
|
|
|
292
292
|
def _refuse_undeclared_column_types(
|
|
293
293
|
struct_cls: type, column_fields: Mapping[str, ColumnFieldInfo]
|
|
294
294
|
) -> None:
|
|
295
|
-
"""Refuse a plain enum or ``Literal`` field whose column type is not declared.
|
|
295
|
+
"""Refuse a ``Decimal``, plain enum or ``Literal`` field whose column type is not declared.
|
|
296
296
|
|
|
297
|
-
loom does not infer a SQL type from the values of
|
|
297
|
+
loom does not infer a SQL type from the values of an enum or a ``Literal``,
|
|
298
|
+
nor a precision and scale for a ``Decimal``: Postgres rounds a value to the
|
|
299
|
+
declared scale and refuses one past the declared precision.
|
|
298
300
|
"""
|
|
299
301
|
for name, info in column_fields.items():
|
|
300
302
|
if info.needs_declared_type:
|
|
301
303
|
raise ValueError(
|
|
302
|
-
f"{struct_cls.__name__}.{name}: no column type
|
|
303
|
-
"Enum or Literal annotation; declare it, e.g.
|
|
304
|
+
f"{struct_cls.__name__}.{name}: no column type is inferred from a Decimal, "
|
|
305
|
+
"plain Enum or Literal annotation; declare it, e.g. "
|
|
306
|
+
"`Annotated[Decimal, Numeric(precision=12, scale=2)]` for a Decimal, "
|
|
307
|
+
"`ColumnField(String(20))` for an Enum or Literal"
|
|
304
308
|
)
|
|
305
309
|
|
|
306
310
|
|
|
@@ -11,6 +11,7 @@ from typing import (
|
|
|
11
11
|
Annotated,
|
|
12
12
|
Any,
|
|
13
13
|
ClassVar,
|
|
14
|
+
Final,
|
|
14
15
|
Literal,
|
|
15
16
|
Union,
|
|
16
17
|
cast,
|
|
@@ -56,8 +57,9 @@ class ColumnFieldInfo:
|
|
|
56
57
|
"""Resolved metadata for a single column field.
|
|
57
58
|
|
|
58
59
|
``needs_declared_type`` marks a field whose column type was not declared
|
|
59
|
-
and
|
|
60
|
-
|
|
60
|
+
and is not inferred: ``column_type`` is then a placeholder, an unbounded
|
|
61
|
+
``Numeric`` for a ``Decimal``, whose precision and scale must be declared,
|
|
62
|
+
and JSON for a plain enum or a ``Literal``.
|
|
61
63
|
"""
|
|
62
64
|
|
|
63
65
|
name: str
|
|
@@ -120,7 +122,7 @@ def _resolve_column_field(
|
|
|
120
122
|
python_type=_extract_origin_type(annotation),
|
|
121
123
|
column_type=column_type or JSON,
|
|
122
124
|
field=field,
|
|
123
|
-
needs_declared_type=column_type is None,
|
|
125
|
+
needs_declared_type=column_type is None or column_type is _UNDECLARED_DECIMAL,
|
|
124
126
|
)
|
|
125
127
|
|
|
126
128
|
|
|
@@ -401,6 +403,10 @@ def _is_classvar(annotation: Any) -> bool:
|
|
|
401
403
|
return get_origin(annotation) is ClassVar
|
|
402
404
|
|
|
403
405
|
|
|
406
|
+
# The placeholder of a Decimal with no declared column type; the SQLAlchemy
|
|
407
|
+
# compiler refuses such a field, so it is never compiled.
|
|
408
|
+
_UNDECLARED_DECIMAL: Final = Numeric()
|
|
409
|
+
|
|
404
410
|
_SCALAR_TYPE_MAP: dict[type, ColumnType] = {
|
|
405
411
|
int: Integer,
|
|
406
412
|
float: Float,
|
|
@@ -409,7 +415,7 @@ _SCALAR_TYPE_MAP: dict[type, ColumnType] = {
|
|
|
409
415
|
datetime: DateTime(tz=True),
|
|
410
416
|
date: Date,
|
|
411
417
|
time: Time,
|
|
412
|
-
Decimal:
|
|
418
|
+
Decimal: _UNDECLARED_DECIMAL,
|
|
413
419
|
}
|
|
414
420
|
|
|
415
421
|
|
|
@@ -28,8 +28,16 @@ def DateTime(*, tz: bool = True) -> ColumnType:
|
|
|
28
28
|
return ColumnType("DateTime", kwargs={"timezone": tz})
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def Numeric(*, precision: int =
|
|
32
|
-
|
|
31
|
+
def Numeric(*, precision: int | None = None, scale: int | None = None) -> ColumnType:
|
|
32
|
+
"""A ``NUMERIC`` column; with no precision it is unbounded.
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
ValueError: A scale is given without a precision; SQLAlchemy would
|
|
36
|
+
ignore it.
|
|
37
|
+
"""
|
|
38
|
+
if scale is not None and precision is None:
|
|
39
|
+
raise ValueError("Numeric: a scale needs a precision")
|
|
40
|
+
return ColumnType("Numeric", kwargs={"precision": precision, "scale": scale})
|
|
33
41
|
|
|
34
42
|
|
|
35
43
|
class _JsonMarker:
|
|
@@ -31,7 +31,6 @@ class CompiledSingleSource:
|
|
|
31
31
|
settings: ConsumerSettings
|
|
32
32
|
topics: tuple[str, ...]
|
|
33
33
|
payload_type: type[LoomStruct | LoomFrozenStruct]
|
|
34
|
-
shape: StreamShape
|
|
35
34
|
decode_strategy: Literal["record", "batch"]
|
|
36
35
|
|
|
37
36
|
|
|
@@ -45,7 +44,6 @@ class CompiledMultiSource:
|
|
|
45
44
|
dispatch: Pre-built table mapping ``message_type`` and error
|
|
46
45
|
``payload_type`` strings to their concrete Python types, plus
|
|
47
46
|
explicit wire-error payload types.
|
|
48
|
-
shape: Declared source shape.
|
|
49
47
|
decode_strategy: Whether to decode records individually or in batches.
|
|
50
48
|
"""
|
|
51
49
|
|
|
@@ -54,7 +52,6 @@ class CompiledMultiSource:
|
|
|
54
52
|
settings: ConsumerSettings
|
|
55
53
|
topics: tuple[str, ...]
|
|
56
54
|
dispatch: DispatchTable
|
|
57
|
-
shape: StreamShape
|
|
58
55
|
decode_strategy: Literal["record", "batch"]
|
|
59
56
|
|
|
60
57
|
|
|
@@ -67,7 +64,6 @@ class CompiledMongoCDCSource:
|
|
|
67
64
|
settings: MongoSourceConfig
|
|
68
65
|
collections: tuple[str, ...]
|
|
69
66
|
watch_options: Mapping[str, object]
|
|
70
|
-
shape: StreamShape
|
|
71
67
|
|
|
72
68
|
|
|
73
69
|
@dataclass(frozen=True)
|
|
@@ -21,9 +21,8 @@ from loom.streaming.compiler._plan import (
|
|
|
21
21
|
CompiledStorageSink,
|
|
22
22
|
)
|
|
23
23
|
from loom.streaming.compiler.phases.validate import (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
_walk_all_process_nodes,
|
|
24
|
+
node_output_shape,
|
|
25
|
+
walk_process_nodes,
|
|
27
26
|
)
|
|
28
27
|
from loom.streaming.core._errors import ErrorEnvelope
|
|
29
28
|
from loom.streaming.graph._flow import StreamFlow
|
|
@@ -33,7 +32,7 @@ from loom.streaming.mongo import MongoConfig
|
|
|
33
32
|
from loom.streaming.nodes._boundary import FromMultiTypeTopic, FromTopic, IntoTopic
|
|
34
33
|
from loom.streaming.nodes._branches import is_branching_node, iter_branches
|
|
35
34
|
from loom.streaming.nodes._mongo import FromMongoCDC
|
|
36
|
-
from loom.streaming.nodes._shape import CollectBatch
|
|
35
|
+
from loom.streaming.nodes._shape import CollectBatch, StreamShape
|
|
37
36
|
from loom.streaming.nodes._sink import IntoSink
|
|
38
37
|
from loom.streaming.nodes._table import Backend, IntoTable
|
|
39
38
|
from loom.streaming.nodes._table.config import (
|
|
@@ -60,7 +59,7 @@ def build_plan(flow: StreamFlow[Any, Any], ctx: ConfigContext) -> CompiledPlan:
|
|
|
60
59
|
terminal_sinks, terminal_storage_sinks = _build_terminal_sinks(flow.process.nodes, ctx)
|
|
61
60
|
error_routes = {kind: _build_sink(topic, ctx) for kind, topic in flow.errors.items()}
|
|
62
61
|
needs_async = any(
|
|
63
|
-
_node_needs_async_bridge(node) for node in
|
|
62
|
+
_node_needs_async_bridge(node) for node in walk_process_nodes(flow.process.nodes)
|
|
64
63
|
)
|
|
65
64
|
return CompiledPlan(
|
|
66
65
|
name=flow.name,
|
|
@@ -74,6 +73,12 @@ def build_plan(flow: StreamFlow[Any, Any], ctx: ConfigContext) -> CompiledPlan:
|
|
|
74
73
|
)
|
|
75
74
|
|
|
76
75
|
|
|
76
|
+
def _node_needs_async_bridge(node: object) -> bool:
|
|
77
|
+
return isinstance(node, WithAsync) or (
|
|
78
|
+
isinstance(node, IntoTable) and node.backend is Backend.SQLALCHEMY
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
77
82
|
def _build_mongo_source(flow: StreamFlow[Any, Any], ctx: ConfigContext) -> CompiledMongoCDCSource:
|
|
78
83
|
source = flow.source
|
|
79
84
|
if not isinstance(source, FromMongoCDC):
|
|
@@ -85,7 +90,6 @@ def _build_mongo_source(flow: StreamFlow[Any, Any], ctx: ConfigContext) -> Compi
|
|
|
85
90
|
settings=settings,
|
|
86
91
|
collections=source.collections,
|
|
87
92
|
watch_options=watch_options,
|
|
88
|
-
shape=source.shape,
|
|
89
93
|
)
|
|
90
94
|
|
|
91
95
|
|
|
@@ -100,7 +104,6 @@ def _build_single_source(flow: StreamFlow[Any, Any], ctx: ConfigContext) -> Comp
|
|
|
100
104
|
settings=consumer,
|
|
101
105
|
topics=consumer.topics,
|
|
102
106
|
payload_type=source.payload,
|
|
103
|
-
shape=source.shape,
|
|
104
107
|
decode_strategy=decode_strategy,
|
|
105
108
|
)
|
|
106
109
|
|
|
@@ -117,7 +120,6 @@ def _build_multi_source(flow: StreamFlow[Any, Any], ctx: ConfigContext) -> Compi
|
|
|
117
120
|
settings=consumer,
|
|
118
121
|
topics=consumer.topics,
|
|
119
122
|
dispatch=dispatch,
|
|
120
|
-
shape=source.shape,
|
|
121
123
|
decode_strategy=decode_strategy,
|
|
122
124
|
)
|
|
123
125
|
|
|
@@ -169,10 +171,10 @@ def _require_message_type(t: type[Any]) -> str:
|
|
|
169
171
|
|
|
170
172
|
def _build_nodes(flow: StreamFlow[Any, Any]) -> list[CompiledNode]:
|
|
171
173
|
nodes: list[CompiledNode] = []
|
|
172
|
-
current_shape =
|
|
174
|
+
current_shape = StreamShape.RECORD
|
|
173
175
|
for node in flow.process.nodes:
|
|
174
176
|
input_shape = current_shape
|
|
175
|
-
output_shape =
|
|
177
|
+
output_shape = node_output_shape(node, current_shape)
|
|
176
178
|
nodes.append(
|
|
177
179
|
CompiledNode(
|
|
178
180
|
node=node,
|
|
@@ -36,7 +36,7 @@ from loom.streaming.nodes._mongo import FromMongoCDC
|
|
|
36
36
|
from loom.streaming.nodes._router import Router
|
|
37
37
|
from loom.streaming.nodes._shape import CollectBatch, Drain, ForEach, StreamShape, WindowStrategy
|
|
38
38
|
from loom.streaming.nodes._sink import IntoSink
|
|
39
|
-
from loom.streaming.nodes._step import BatchExpandStep, BatchStep, ExpandStep, RecordStep
|
|
39
|
+
from loom.streaming.nodes._step import BatchExpandStep, BatchStep, ExpandStep, RecordStep, Step
|
|
40
40
|
from loom.streaming.nodes._table import Backend, IntoTable
|
|
41
41
|
from loom.streaming.nodes._table.config import (
|
|
42
42
|
resolve_clickhouse_table_config,
|
|
@@ -119,7 +119,9 @@ def validate_resources(flow: StreamFlow[Any, Any]) -> list[CompilationIssue]:
|
|
|
119
119
|
|
|
120
120
|
def validate_shapes(flow: StreamFlow[Any, Any]) -> list[CompilationIssue]:
|
|
121
121
|
"""Validate shape transitions through the process tree."""
|
|
122
|
-
errors,
|
|
122
|
+
errors, final_shape = _validate_shape_sequence(flow.process.nodes, StreamShape.RECORD)
|
|
123
|
+
if flow.output is not None:
|
|
124
|
+
errors.extend(_output_shape_issues(final_shape, "flow.output"))
|
|
123
125
|
errors.extend(_validate_window_strategies(flow.process.nodes))
|
|
124
126
|
errors.extend(_validate_scoped_process_nodes(_walk_all_process_nodes(flow.process.nodes)))
|
|
125
127
|
return errors
|
|
@@ -224,18 +226,12 @@ def walk_process_nodes(nodes: Iterable[object]) -> Iterable[object]:
|
|
|
224
226
|
yield from _walk_all_process_nodes(nodes)
|
|
225
227
|
|
|
226
228
|
|
|
227
|
-
def _node_needs_async_bridge(node: object) -> bool:
|
|
228
|
-
return isinstance(node, WithAsync) or (
|
|
229
|
-
isinstance(node, IntoTable) and node.backend is Backend.SQLALCHEMY
|
|
230
|
-
)
|
|
231
|
-
|
|
232
|
-
|
|
233
229
|
def _check_input_shape(
|
|
234
230
|
node: object,
|
|
235
231
|
current_shape: StreamShape,
|
|
236
232
|
errors: list[CompilationIssue],
|
|
237
233
|
) -> None:
|
|
238
|
-
expected =
|
|
234
|
+
expected = node_input_shape(node)
|
|
239
235
|
if expected is not None and current_shape != expected:
|
|
240
236
|
errors.append(
|
|
241
237
|
StreamingErrorCode.SHAPE_MISMATCH.issue(
|
|
@@ -244,6 +240,21 @@ def _check_input_shape(
|
|
|
244
240
|
)
|
|
245
241
|
|
|
246
242
|
|
|
243
|
+
def _output_shape_issues(shape: StreamShape, component: str) -> list[CompilationIssue]:
|
|
244
|
+
"""Return the mismatch of an output declared after a stream of *shape*.
|
|
245
|
+
|
|
246
|
+
An output writes records, so only a ``batch`` is a mismatch. ``none`` is the
|
|
247
|
+
shape after a node that ends the path, and after ``With`` and ``WithAsync``,
|
|
248
|
+
whose runtime hands their results on one message at a time.
|
|
249
|
+
"""
|
|
250
|
+
if shape in (StreamShape.RECORD, StreamShape.NONE):
|
|
251
|
+
return []
|
|
252
|
+
issue = StreamingErrorCode.SHAPE_MISMATCH.issue(
|
|
253
|
+
expected=StreamShape.RECORD.value, got=shape.value, component=component
|
|
254
|
+
)
|
|
255
|
+
return [msgspec.structs.replace(issue, field="output")]
|
|
256
|
+
|
|
257
|
+
|
|
247
258
|
def _must_be_last_errors(
|
|
248
259
|
idx: int,
|
|
249
260
|
node_list: tuple[object, ...],
|
|
@@ -351,13 +362,13 @@ def _validate_shape_node(
|
|
|
351
362
|
if isinstance(node, ExpandRoutes):
|
|
352
363
|
return _validate_expand_routes_node(node, idx, node_list)
|
|
353
364
|
if isinstance(node, Router):
|
|
354
|
-
router_errors, next_shape = _validate_router_shapes(node
|
|
365
|
+
router_errors, next_shape = _validate_router_shapes(node)
|
|
355
366
|
if router_ends_every_path(node):
|
|
356
367
|
not_last = StreamingErrorCode.TERMINAL_NOT_LAST.issue(component=type(node).__name__)
|
|
357
368
|
router_errors.extend(_must_be_last_errors(idx, node_list, not_last))
|
|
358
369
|
return router_errors, StreamShape.NONE, True
|
|
359
370
|
return router_errors, next_shape, False
|
|
360
|
-
return [],
|
|
371
|
+
return [], node_output_shape(node, current_shape), False
|
|
361
372
|
|
|
362
373
|
|
|
363
374
|
def _validate_leaf_terminal_node(
|
|
@@ -421,7 +432,7 @@ def _validate_explode_node(
|
|
|
421
432
|
if not isinstance(next_node, Router):
|
|
422
433
|
got = type(next_node).__name__ if next_node is not None else "nothing"
|
|
423
434
|
errors.append(StreamingErrorCode.EXPLODE_WITHOUT_ROUTER.issue(got=got))
|
|
424
|
-
return errors,
|
|
435
|
+
return errors, node_output_shape(node, current_shape), False
|
|
425
436
|
|
|
426
437
|
|
|
427
438
|
def _prefixed(issue: CompilationIssue, prefix: str) -> CompilationIssue:
|
|
@@ -471,7 +482,9 @@ def _validate_broadcast_shapes(
|
|
|
471
482
|
) -> tuple[list[CompilationIssue], StreamShape]:
|
|
472
483
|
errors: list[CompilationIssue] = []
|
|
473
484
|
for branch in iter_branches(broadcast):
|
|
474
|
-
branch_errors,
|
|
485
|
+
branch_errors, final_shape = _validate_shape_sequence(branch.nodes, initial_shape)
|
|
486
|
+
if branch.output is not None:
|
|
487
|
+
branch_errors.extend(_output_shape_issues(final_shape, "output"))
|
|
475
488
|
errors.extend(
|
|
476
489
|
_prefixed(issue, f"broadcast branch {branch.label}") for issue in branch_errors
|
|
477
490
|
)
|
|
@@ -487,50 +500,47 @@ def _validate_broadcast_shapes(
|
|
|
487
500
|
|
|
488
501
|
def _validate_router_branch_shape_sequence(
|
|
489
502
|
nodes: Iterable[object],
|
|
490
|
-
initial_shape: StreamShape,
|
|
491
503
|
) -> tuple[list[CompilationIssue], StreamShape]:
|
|
504
|
+
"""Shape-check the nodes of one Router branch and return the branch's output shape.
|
|
505
|
+
|
|
506
|
+
A ``BatchStep`` here is record to record: the runtime runs it on a
|
|
507
|
+
one-message batch of the routed message
|
|
508
|
+
(``loom.streaming.bytewax.handlers.routing._execute_router_node``).
|
|
509
|
+
"""
|
|
492
510
|
errors: list[CompilationIssue] = []
|
|
493
|
-
current_shape =
|
|
511
|
+
current_shape = StreamShape.RECORD
|
|
494
512
|
node_list = tuple(nodes)
|
|
495
513
|
|
|
496
514
|
for idx, node in enumerate(node_list):
|
|
497
515
|
if isinstance(node, BatchStep):
|
|
498
516
|
current_shape = StreamShape.RECORD
|
|
499
517
|
continue
|
|
500
|
-
|
|
501
|
-
if expected is not None and current_shape != expected:
|
|
502
|
-
errors.append(
|
|
503
|
-
StreamingErrorCode.SHAPE_MISMATCH.issue(
|
|
504
|
-
expected=expected.value, got=current_shape.value, component=type(node).__name__
|
|
505
|
-
)
|
|
506
|
-
)
|
|
518
|
+
_check_input_shape(node, current_shape, errors)
|
|
507
519
|
if _is_leaf_terminal(node) and idx != len(node_list) - 1:
|
|
508
|
-
errors.append(
|
|
509
|
-
StreamingErrorCode.BROADCAST_NOT_LAST.issue()
|
|
510
|
-
if isinstance(node, Broadcast)
|
|
511
|
-
else StreamingErrorCode.TERMINAL_NOT_LAST.issue(component=type(node).__name__)
|
|
512
|
-
)
|
|
520
|
+
errors.append(StreamingErrorCode.TERMINAL_NOT_LAST.issue(component=type(node).__name__))
|
|
513
521
|
break
|
|
514
|
-
current_shape =
|
|
522
|
+
current_shape = node_output_shape(node, current_shape)
|
|
515
523
|
|
|
516
524
|
return errors, current_shape
|
|
517
525
|
|
|
518
526
|
|
|
519
527
|
def _validate_router_shapes(
|
|
520
528
|
router: Router[StreamPayload, StreamPayload],
|
|
521
|
-
initial_shape: StreamShape,
|
|
522
529
|
) -> tuple[list[CompilationIssue], StreamShape]:
|
|
523
530
|
"""Validate *router*'s branches and return the shape of the messages that continue.
|
|
524
531
|
|
|
525
532
|
Those are the outputs of the branches that do not end their path and, without
|
|
526
533
|
a default branch, the unmatched input; only they must agree on one shape.
|
|
534
|
+
A Router takes records, so every branch starts as a record stream.
|
|
527
535
|
"""
|
|
528
536
|
errors: list[CompilationIssue] = []
|
|
529
|
-
outputs: dict[StreamShape, None] =
|
|
537
|
+
outputs: dict[StreamShape, None] = (
|
|
538
|
+
{} if router.default is not None else {StreamShape.RECORD: None}
|
|
539
|
+
)
|
|
530
540
|
|
|
531
541
|
for branch in iter_branches(router):
|
|
532
542
|
label, nodes = branch.label, branch.nodes
|
|
533
|
-
branch_errors, branch_output = _validate_router_branch_shape_sequence(nodes
|
|
543
|
+
branch_errors, branch_output = _validate_router_branch_shape_sequence(nodes)
|
|
534
544
|
errors.extend(_prefixed(issue, f"router branch {label}") for issue in branch_errors)
|
|
535
545
|
for node in nodes:
|
|
536
546
|
if not isinstance(node, RouterBranchSafe):
|
|
@@ -644,30 +654,6 @@ def _contains_broadcast(nodes: Iterable[object]) -> bool:
|
|
|
644
654
|
return any(isinstance(node, Broadcast) for node in nodes)
|
|
645
655
|
|
|
646
656
|
|
|
647
|
-
def _node_input_shape(node: object) -> StreamShape | None:
|
|
648
|
-
if isinstance(node, RecordStep):
|
|
649
|
-
return StreamShape.RECORD
|
|
650
|
-
if isinstance(node, BatchStep):
|
|
651
|
-
return StreamShape.BATCH
|
|
652
|
-
if isinstance(node, ExpandStep):
|
|
653
|
-
return StreamShape.RECORD
|
|
654
|
-
if isinstance(node, BatchExpandStep):
|
|
655
|
-
return StreamShape.BATCH
|
|
656
|
-
if isinstance(node, Explode):
|
|
657
|
-
return StreamShape.RECORD
|
|
658
|
-
if isinstance(node, (With, WithAsync)):
|
|
659
|
-
return None
|
|
660
|
-
if isinstance(node, ForEach):
|
|
661
|
-
return StreamShape.MANY
|
|
662
|
-
if isinstance(node, Drain):
|
|
663
|
-
return None
|
|
664
|
-
if isinstance(node, Fork):
|
|
665
|
-
return None
|
|
666
|
-
if isinstance(node, Router):
|
|
667
|
-
return StreamShape.RECORD
|
|
668
|
-
return None
|
|
669
|
-
|
|
670
|
-
|
|
671
657
|
def _validate_window_strategies(nodes: Iterable[object]) -> list[CompilationIssue]:
|
|
672
658
|
errors: list[CompilationIssue] = []
|
|
673
659
|
for node in nodes:
|
|
@@ -702,29 +688,47 @@ def _validate_scoped_process_nodes(nodes: Iterable[object]) -> list[CompilationI
|
|
|
702
688
|
return errors
|
|
703
689
|
|
|
704
690
|
|
|
705
|
-
|
|
706
|
-
CollectBatch
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
691
|
+
_NODE_SHAPES: tuple[tuple[type, StreamShape | None, StreamShape | None], ...] = (
|
|
692
|
+
(CollectBatch, StreamShape.RECORD, StreamShape.BATCH),
|
|
693
|
+
(ForEach, StreamShape.BATCH, StreamShape.RECORD),
|
|
694
|
+
(Explode, StreamShape.RECORD, None),
|
|
695
|
+
(Router, StreamShape.RECORD, None),
|
|
696
|
+
(ExpandRoutes, StreamShape.RECORD, None),
|
|
697
|
+
(Fork, StreamShape.RECORD, StreamShape.NONE),
|
|
698
|
+
(Broadcast, StreamShape.RECORD, StreamShape.NONE),
|
|
699
|
+
(Drain, StreamShape.RECORD, StreamShape.NONE),
|
|
700
|
+
(IntoTopic, StreamShape.RECORD, StreamShape.NONE),
|
|
701
|
+
(IntoSink, StreamShape.RECORD, StreamShape.NONE),
|
|
702
|
+
(With, None, StreamShape.NONE),
|
|
703
|
+
(WithAsync, None, StreamShape.NONE),
|
|
704
|
+
)
|
|
705
|
+
"""``(node type, input shape, output shape)`` of every non-step node.
|
|
706
|
+
|
|
707
|
+
``None`` input accepts any shape; ``None`` output keeps the incoming shape.
|
|
708
|
+
A ``Step`` declares both on its class instead.
|
|
709
|
+
"""
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
def _non_step_shapes(node: object) -> tuple[StreamShape | None, StreamShape | None]:
|
|
713
|
+
return next(
|
|
714
|
+
((inp, out) for kind, inp, out in _NODE_SHAPES if isinstance(node, kind)), (None, None)
|
|
715
|
+
)
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
def node_input_shape(node: object) -> StreamShape | None:
|
|
719
|
+
"""Return the shape *node* requires on its input, or ``None`` when it takes any."""
|
|
720
|
+
if isinstance(node, Step):
|
|
721
|
+
return node.input_shape
|
|
722
|
+
return _non_step_shapes(node)[0]
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
def node_output_shape(node: object, current: StreamShape) -> StreamShape:
|
|
726
|
+
"""Return the shape after *node* when it receives *current*.
|
|
727
|
+
|
|
728
|
+
In a Router branch a ``BatchStep`` is record to record; the branch walk
|
|
729
|
+
handles it before calling this.
|
|
730
|
+
"""
|
|
731
|
+
if isinstance(node, Step):
|
|
732
|
+
return node.output_shape
|
|
733
|
+
output = _non_step_shapes(node)[1]
|
|
734
|
+
return current if output is None else output
|
|
@@ -8,7 +8,6 @@ from typing import ClassVar, Generic, Protocol, TypeVar
|
|
|
8
8
|
from loom.core.model import LoomFrozenStruct, LoomStruct
|
|
9
9
|
from loom.core.routing import LogicalRef, as_logical_ref
|
|
10
10
|
from loom.streaming.core._message import Message
|
|
11
|
-
from loom.streaming.nodes._shape import StreamShape
|
|
12
11
|
|
|
13
12
|
PayloadT = TypeVar("PayloadT", bound=LoomStruct | LoomFrozenStruct, contravariant=True)
|
|
14
13
|
MultiPayloadT = TypeVar("MultiPayloadT", bound=LoomStruct | LoomFrozenStruct, covariant=True)
|
|
@@ -24,12 +23,10 @@ class FromTopic(LoomFrozenStruct, Generic[PayloadT], frozen=True):
|
|
|
24
23
|
name: Logical input reference. By default this is also used as the
|
|
25
24
|
Kafka config reference.
|
|
26
25
|
payload: Logical payload type descriptor.
|
|
27
|
-
shape: Declared source shape.
|
|
28
26
|
"""
|
|
29
27
|
|
|
30
28
|
name: str
|
|
31
29
|
payload: type[PayloadT]
|
|
32
|
-
shape: StreamShape = StreamShape.RECORD
|
|
33
30
|
|
|
34
31
|
@property
|
|
35
32
|
def logical_ref(self) -> LogicalRef:
|
|
@@ -56,7 +53,6 @@ class FromMultiTypeTopic(LoomFrozenStruct, Generic[MultiPayloadT], frozen=True):
|
|
|
56
53
|
Args:
|
|
57
54
|
name: Logical input reference.
|
|
58
55
|
payloads: Tuple of two or more expected payload types.
|
|
59
|
-
shape: Declared source shape.
|
|
60
56
|
|
|
61
57
|
Raises:
|
|
62
58
|
ValueError: When fewer than two payload types are declared.
|
|
@@ -72,7 +68,6 @@ class FromMultiTypeTopic(LoomFrozenStruct, Generic[MultiPayloadT], frozen=True):
|
|
|
72
68
|
|
|
73
69
|
name: str
|
|
74
70
|
payloads: tuple[type[LoomStruct | LoomFrozenStruct], ...]
|
|
75
|
-
shape: StreamShape = StreamShape.RECORD
|
|
76
71
|
|
|
77
72
|
def __post_init__(self) -> None:
|
|
78
73
|
if len(self.payloads) < 2:
|
|
@@ -97,7 +92,6 @@ class IntoTopic(LoomFrozenStruct, Generic[PayloadT], frozen=True):
|
|
|
97
92
|
name: Logical output reference. By default this is also used as the
|
|
98
93
|
Kafka config reference.
|
|
99
94
|
payload: Optional logical payload type descriptor.
|
|
100
|
-
shape: Declared output shape.
|
|
101
95
|
partitioning: Optional partitioning policy.
|
|
102
96
|
dlq: Optional dead-letter topic name. When set, messages that fail
|
|
103
97
|
delivery are routed to this topic instead of crashing the worker.
|
|
@@ -107,7 +101,6 @@ class IntoTopic(LoomFrozenStruct, Generic[PayloadT], frozen=True):
|
|
|
107
101
|
|
|
108
102
|
name: str
|
|
109
103
|
payload: type[PayloadT] | None = None
|
|
110
|
-
shape: StreamShape = StreamShape.RECORD
|
|
111
104
|
partitioning: PartitionPolicy[PayloadT] | None = None
|
|
112
105
|
dlq: str | None = None
|
|
113
106
|
router_branch_safe: ClassVar[bool] = True
|
|
@@ -11,7 +11,6 @@ from typing_extensions import TypeVar
|
|
|
11
11
|
from loom.core.model import LoomFrozenStruct, LoomStruct
|
|
12
12
|
from loom.core.routing import LogicalRef, as_logical_ref
|
|
13
13
|
from loom.streaming.mongo._event import MongoCDCEvent
|
|
14
|
-
from loom.streaming.nodes._shape import StreamShape
|
|
15
14
|
|
|
16
15
|
MongoCDCPayloadT = TypeVar(
|
|
17
16
|
"MongoCDCPayloadT",
|
|
@@ -33,13 +32,11 @@ class FromMongoCDC(LoomFrozenStruct, Generic[MongoCDCPayloadT], frozen=True):
|
|
|
33
32
|
collections: Collection names to watch. An empty tuple means a
|
|
34
33
|
database-level watch.
|
|
35
34
|
watch_options: Driver watch kwargs resolved later by compiler/runtime.
|
|
36
|
-
shape: Declared source shape.
|
|
37
35
|
"""
|
|
38
36
|
|
|
39
37
|
name: str
|
|
40
38
|
collections: tuple[str, ...] = ()
|
|
41
39
|
watch_options: Mapping[str, object] = msgspec.field(default_factory=dict)
|
|
42
|
-
shape: StreamShape = StreamShape.RECORD
|
|
43
40
|
|
|
44
41
|
@property
|
|
45
42
|
def logical_ref(self) -> LogicalRef:
|
|
@@ -12,7 +12,6 @@ class StreamShape(StrEnum):
|
|
|
12
12
|
"""Logical data shape at a streaming graph edge."""
|
|
13
13
|
|
|
14
14
|
RECORD = "record"
|
|
15
|
-
MANY = "many"
|
|
16
15
|
BATCH = "batch"
|
|
17
16
|
NONE = "none"
|
|
18
17
|
|
|
@@ -64,8 +63,8 @@ class CollectBatch(LoomFrozenStruct, frozen=True):
|
|
|
64
63
|
|
|
65
64
|
Groups individual records into batches before handing them to downstream
|
|
66
65
|
batch-aware nodes. Batch is an **optimization grouping**, not a
|
|
67
|
-
first-class semantic unit
|
|
68
|
-
|
|
66
|
+
first-class semantic unit: a ``ForEach`` after the batch nodes turns the
|
|
67
|
+
batch back into individual records.
|
|
69
68
|
|
|
70
69
|
Args:
|
|
71
70
|
max_records: Maximum records collected into one batch.
|
|
@@ -102,7 +101,7 @@ class CollectBatch(LoomFrozenStruct, frozen=True):
|
|
|
102
101
|
|
|
103
102
|
|
|
104
103
|
class Drain(LoomFrozenStruct, frozen=True):
|
|
105
|
-
"""Explicit terminal adapter from
|
|
104
|
+
"""Explicit terminal adapter from ``record`` to ``none``.
|
|
106
105
|
|
|
107
106
|
Pattern:
|
|
108
107
|
Shape adapter.
|