loom-kernel 2.22.3__tar.gz → 4.0.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.22.3 → loom_kernel-4.0.0}/CHANGELOG.md +201 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/PKG-INFO +5 -1
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/README.md +4 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/auto.py +11 -1
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/bootstrap.py +47 -16
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/config.py +7 -5
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/cli/app.py +3 -1
- loom_kernel-4.0.0/src/loom/cli/check.py +105 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/bootstrap/bootstrap.py +9 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/bootstrap/kernel.py +8 -0
- loom_kernel-4.0.0/src/loom/core/checks.py +343 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/context.py +25 -1
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/keys.py +0 -2
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/observability.py +1 -1
- loom_kernel-4.0.0/src/loom/core/config/overrides.py +317 -0
- loom_kernel-4.0.0/src/loom/core/environment.py +293 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/locator.py +40 -12
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/logger/__init__.py +2 -2
- loom_kernel-4.0.0/src/loom/core/logger/checks.py +46 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/logger/config.py +70 -76
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/introspection.py +26 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/types.py +5 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/config.py +10 -4
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/runtime.py +17 -6
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/dynamodb/backend.py +1 -1
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/mixins.py +4 -11
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +17 -3
- loom_kernel-4.0.0/src/loom/core/repository/sqlalchemy/values.py +51 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/config.py +17 -13
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_streaming.py +2 -2
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/_config.py +1 -1
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/config_loader.py +24 -8
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/core.py +89 -9
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/storage/_config.py +15 -15
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/spark.py +3 -3
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/__init__.py +1 -1
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_config.py +1 -1
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_ctx.py +0 -2
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_flow_yaml.py +12 -4
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_meta.py +3 -6
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/deploy/_discovery.py +45 -39
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/deploy/_yaml_etls.py +4 -3
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/deploy/entrypoint.py +4 -5
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_assemble.py +2 -1
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_backfill.py +3 -3
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_backfill_body.py +17 -7
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_body.py +13 -5
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_hooks.py +14 -4
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_maintenance.py +12 -9
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_signature.py +12 -4
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_event.py +2 -3
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/__init__.py +5 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/auth/config.py +3 -3
- loom_kernel-4.0.0/src/loom/rest/checks.py +64 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/compiler.py +141 -6
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/config.py +21 -2
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/cors.py +1 -1
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/auto.py +130 -67
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/router_runtime.py +117 -32
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/model.py +44 -1
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/runner.py +72 -35
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_config.py +14 -8
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/mongo/_config.py +2 -2
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/.gitignore +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/LICENSE +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/pyproject.toml +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_concurrency.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_filters.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_paths.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_roles.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_startup.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_transport.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/_usecase.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/_binding.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/_handlers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/_rpc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/card.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/events.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/a2a/server.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/abc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/bootstrap.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/_compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/_fingerprint.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/_plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_capabilities.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_conversation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_feedable.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_hook.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_instructions.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_limits.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_model_role.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_output.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/compiler/phases/_state.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/declarative/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/declarative/_envelope.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/declarative/_schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/declarative/_v1.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/declarative/schemas/agent-spec-v1.schema.json +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/describe.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_a2a.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_capabilities.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_engine.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_escape.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_events.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_guards.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_history.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_instructions.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_limits.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_mcp.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_models.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_native.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_output.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_returns.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_schemas.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/_spec.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/extras/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/extras/a2a.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/extras/handlebars.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/extras/mcp.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/extras/skills.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/provider.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/_shared.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/anthropic.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/bedrock.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/gateway.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/openai.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/engines/pydantic_ai/providers/typesafe.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_batch.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_columns.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_frames.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_ledger.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_runner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/etl/_validation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/fastapi/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/fastapi/endpoints.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/fastapi/response.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/fastapi/streaming.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/inference.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/pricing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/remote_auth.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_bounded.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_chain.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_conversation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_grants.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_handle.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_health.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_hooks.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_lifecycle.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_limits.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/runtime/_mcp.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/validate/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/ai/validate/__main__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/constants.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/runner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/celery/service.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/cli/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/cli/schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/async_bridge.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/_decide.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/_grants.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/_roles.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/_scope.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/elevation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/authz/product.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/backend/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/backend/core_model.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/backend/protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/backend/scoped_ddl.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/backend/sqlalchemy.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/bootstrap/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/_batching.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/_single_flight.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/abc/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/abc/backend.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/abc/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/abc/dependency.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/calls.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/codec.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/decorators.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/dependency.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/gateway.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/keys.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/memory.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/repository.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/result_codec.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/serializer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/cache/wiring.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/command/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/command/adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/command/base.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/command/field.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/command/introspection.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/_boto3.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/_includes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/_resolver_utils.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/binder.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/configurable.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/loader.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/model.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/resolver.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/secrets.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/config/ssm.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/contracts/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/contracts/manifest.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/di/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/di/container.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/di/scope.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/_utils.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/base.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/interfaces.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/manifest.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/discovery/modules.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/compilable.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/events.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/executor.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/metrics.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/engine/post_commit.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/errors/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/errors/codes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/errors/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/expr/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/expr/eval.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/expr/nodes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/expr/refs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/identity/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/identity/context.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/identity/identity.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/identity/issuer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/identity/wire.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/introspection/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/introspection/base.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/introspection/describe.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/callback.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/context.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/handle.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/job.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/job/service.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/logger/abc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/logger/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/logger/structlogger.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/_json_schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/_loom_type.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/base.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/convert.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/enums.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/field.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/partition.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/privilege.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/projection.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/relation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/scoped.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/struct.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/timestamped.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/model/types_postgres.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/event.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/observer/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/observer/noop.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/observer/otel.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/observer/structlog.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/otel_ids.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/span.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/observability/topology.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/persistence/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/persistence/abc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/persistence/none.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/persistence/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/plugins/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/plugins/entrypoints.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/plugins/optional.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/projection/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/projection/loaders.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/projection/runtime.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/cursor.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/query.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/query_compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/repo_for.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/repository.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/abc/session_scope.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/dynamodb/repository.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/backend.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/ids.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/query_compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/repository.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/uow.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mongo/values.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/mutation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/registration.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/backend.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/migrations/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/migrations/env_template.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/migrations/hook.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/migrations/operations.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/migrations/runners.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/bootstrap.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/elevate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/guard/0001.sql +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/guard/0002.sql +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/guard/preflight.sql +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/integrity.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/partitions.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/provider.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/sources.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/rls/verify.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/session_settings.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/response/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/response/base.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/routing/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/routing/ref.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/routing/resolver.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/runner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/schema/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/schema/schema_mode.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/schema_names.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/abc/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/abc/contracts.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/abc/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/caller_bound.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/roles.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/sql/service.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/symbols.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/tracing/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/tracing/context.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/transaction.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/transport/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/transport/adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/uow/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/uow/abc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/uow/context.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/_predicates.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/agent_markers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/compute.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/constants.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/factory.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/field_ref.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/invoker.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/keys.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/markers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/mcp_markers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/outcome.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/rule.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/core/use_case/use_case.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/_uri.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_format_registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/_common.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/_log.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_merge.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_path_template.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_predicate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/_write_policy.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_frame.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_historify.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_reader.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/_writer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/polars/provider.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_historify.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_reader.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/_writer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/backends/spark/provider.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_options.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_paths.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_scope.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/checkpoint/_store.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_binding.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_filter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_validators.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_validators_agents.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_validators_config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/compiler/_validators_step.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/_format.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/_read_options.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/_utils.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/_with_agent.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/_write_options.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/expr/_params.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_from.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_from_config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/source/_specs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_client.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_file.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_into.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_table.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/declarative/target/_temp.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/executor/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/executor/_agents.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/executor/_dispatcher.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/executor/_executor.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/_registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_mongo.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/sources/_serialization.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/targets/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/_observer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/_records.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/_builder.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/_ops.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/_protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/_runner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/_step.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_generics.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_params.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_process.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_sql.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_step.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_step_client.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/_agents.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/_providers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/_wiring.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runner/filtering.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runtime/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runtime/_config_values.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/runtime/contracts.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/schema/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/schema/_contract.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/schema/_schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/storage/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/storage/_file_locator.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/storage/_locator.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/storage/routing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/_result.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/_runners.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/_scenario.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/etl/testing/_stubs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_async.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_placeholders.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/_summary.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/deploy/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/deploy/_schedule.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_common.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_factory.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_params.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_run_name.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_runtime.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/flow/_stages.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/manifest/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/manifest/_model.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/manifest/_s3.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/manifest/_store.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_factory.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_format.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_port.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_slack.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/notify/_sns.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/observer/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/observer/_flow.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/observer/_logging_bridge.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/observer/_manifest.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prefect/observer/_task_run.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/_instruments.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/kafka.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/lifecycle.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/prometheus/middleware.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/py.typed +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/_body.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/auth/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/auth/abc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/auth/jwt.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/auth/middleware.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/autocrud.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/constants.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/app.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/health.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/openapi.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/response.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/fastapi/sql.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/middleware.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/rest/rest_adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_batch_spans.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_operators.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/_bindings.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/_compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/_plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/phases/build_plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/compiler/phases/validate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/_exceptions.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/_message.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/_tracing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/core/_typing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/graph/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/graph/_flow.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_codec.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_message.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_record.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/_wire.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/client/_retry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/mongo/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/mongo/_event.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/mongo/_normalize.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_boundary.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_branches.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_decompose.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_fork.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_helpers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_mongo.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_protocols.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_router.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_shape.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_sink.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_step.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_table/common.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_table/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/_with.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/nodes/refs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/streaming/testing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/agents.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/golden.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/http_harness.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/in_memory.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/repository_harness.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-4.0.0}/src/loom/testing/runner.py +0 -0
|
@@ -459,6 +459,85 @@
|
|
|
459
459
|
|
|
460
460
|
### core
|
|
461
461
|
|
|
462
|
+
- **core:** with no `LOOM_ENV` and no `environment=`, a process starts as
|
|
463
|
+
`production` and runs the deploy checks; an API without authentication now
|
|
464
|
+
fails at startup with `loom.rest.E001` until it configures
|
|
465
|
+
`app.rest.auth.jwt`, sets `app.rest.auth.custom: true` and passes an
|
|
466
|
+
`authenticator`, sets `LOOM_ENV=development`, or lists the id under
|
|
467
|
+
`checks.silenced`. An unknown or empty `LOOM_ENV` is a startup error.
|
|
468
|
+
- **core:** the logger's default changed from development to production: with
|
|
469
|
+
no explicit `renderer`/`colors`, logs render as JSON without colours unless
|
|
470
|
+
the process resolved `development` or `test`. `create_kernel`,
|
|
471
|
+
`bootstrap_app`, `ObservabilityRuntime.from_config`, `configure_logging`
|
|
472
|
+
and `configure_logging_from_values` take `environment=None` and resolve it
|
|
473
|
+
(`LOOM_ENV`, else production) when none is passed.
|
|
474
|
+
- **core:** the logger's own environment is removed:
|
|
475
|
+
`loom.core.logger.Environment`, `LoggerConfig.environment` and
|
|
476
|
+
`LogConfig.environment` are gone, and the logging functions take
|
|
477
|
+
`loom.core.environment.Environment`.
|
|
478
|
+
- **core:** configuration sections refuse keys they do not declare: the
|
|
479
|
+
logger and its handlers, `checks`, `app.rest` (with `auth`, `jwt`, `cors`
|
|
480
|
+
and `discovery`), the `observability` log, otel and prometheus structs and
|
|
481
|
+
`OtelConfig`, `sql`, `celery` and `jobs`, every ETL `storage` struct and
|
|
482
|
+
lineage, `kafka`, the bytewax runtime, streaming `mongo`, `dynamodb` and the
|
|
483
|
+
flow config. A leftover `observability.log.config.environment`, or any
|
|
484
|
+
typo there, is a `ConfigError`. `app`, `database`, `persistence` and the
|
|
485
|
+
top of `observability`, which several readers decode in part, still accept
|
|
486
|
+
keys another reader owns. `create_app` and `bootstrap_worker` no longer fall
|
|
487
|
+
back to the default `observability` section when it fails validation, and
|
|
488
|
+
`create_app` registers the in-process job service when the `celery`
|
|
489
|
+
section is absent (with a warning) or the Celery extra is not installed; a
|
|
490
|
+
`celery` section that fails validation now stops startup instead.
|
|
491
|
+
- **core:** a `LOOM__*` override sets one leaf value. A variable naming no
|
|
492
|
+
known section, with a malformed level, whose value is or holds a mapping,
|
|
493
|
+
whose target the files declare as a mapping or a list of mappings, naming
|
|
494
|
+
`config`, holding `${` however it is written, reaching inside an
|
|
495
|
+
interpolated key, failing to parse, or colliding with another variable
|
|
496
|
+
stops startup naming the variable, never the value. In production and
|
|
497
|
+
staging an override may set only an allowlisted key: loom's operational
|
|
498
|
+
keys (`loom.core.config.overrides.OVERRIDABLE`: log levels, Celery and
|
|
499
|
+
streaming worker counts and timeouts, SQL pool sizes and driver timeouts)
|
|
500
|
+
and the keys the reviewed files list under `config.overridable`. A
|
|
501
|
+
`config.overridable` entry starting with `*`, or inside `checks` or
|
|
502
|
+
`config`, stops every load. A placeholder in the `checks` section is a
|
|
503
|
+
`ConfigError`. A per-flow Prefect YAML is read without overrides.
|
|
504
|
+
`ConfigKey.LOGGER` and `ConfigKey.METRICS`, read by nothing, are removed.
|
|
505
|
+
- **core:** the SQL `max_execution_time`, `connect_timeout`,
|
|
506
|
+
`send_receive_timeout`, `pool_size` and `executor_threads`, the Celery
|
|
507
|
+
`runtime.shutdown_timeout_ms` and the streaming runtime's
|
|
508
|
+
`epoch_interval_ms` and `force_shutdown_timeout_ms` must be above zero; a
|
|
509
|
+
`0` fails when the section decodes.
|
|
510
|
+
- **core:** the `loom.core.checks` logger sets its own WARNING level, so a
|
|
511
|
+
parent level (`CRITICAL`, top-level or `named_levels.loom`) cannot hide a
|
|
512
|
+
deploy check's warning or the silenced ids; name `loom.core.checks` under
|
|
513
|
+
`named_levels` to quiet it. The handlers `configure_logging` attaches no
|
|
514
|
+
longer filter by level, so a named level below the top-level level takes
|
|
515
|
+
effect for stdlib loggers; structlog loggers, loom's own included, still
|
|
516
|
+
drop events below the top-level level.
|
|
517
|
+
- **core:** a consumer's test suite must set `LOOM_ENV=test` (loom's own
|
|
518
|
+
sets it in `tests/conftest.py`), or every application it builds starts as
|
|
519
|
+
production and runs the deploy checks.
|
|
520
|
+
- **core:** the migration locator now resolves `LOOM_ENV` (picking the
|
|
521
|
+
overlay of a config directory), applies the `LOOM__*` variables and puts
|
|
522
|
+
`app.code_path` on `sys.path` when the directory exists, as the
|
|
523
|
+
application does. `loom check --deploy` refuses an `app.code_path` that is
|
|
524
|
+
not a literal path.
|
|
525
|
+
- **core:** `ETLRunner` and `StreamingRunner` resolve the environment
|
|
526
|
+
(`LOOM_ENV`, else production): without one they log JSON and, built from a
|
|
527
|
+
whole configuration (a file, a directory, or a mapping for
|
|
528
|
+
`StreamingRunner.from_dict`), run the deploy checks; `ETLRunner.from_dict`
|
|
529
|
+
and `from_spark` receive no whole configuration and run none.
|
|
530
|
+
- **core:** `loom.core.locator.CONFIG_ENV_VAR` is replaced by
|
|
531
|
+
`loom.core.environment.CONFIG_VARIABLE`; `LOOM_CONFIG` may name a config
|
|
532
|
+
directory. `loom.prefect`'s `LOOM_ETL_CONFIG` alias is removed; use
|
|
533
|
+
`loom.core.environment.ETL_CONFIG_VARIABLE`. `app.code_path` is added to
|
|
534
|
+
`sys.path` only when the directory exists.
|
|
535
|
+
- **core:** a non-deployed environment logs one WARNING that the deploy
|
|
536
|
+
checks were skipped.
|
|
537
|
+
- **rest:** `create_app(authenticator=...)` requires
|
|
538
|
+
`app.rest.auth.custom: true`, `custom: true` requires an `authenticator`,
|
|
539
|
+
and `custom: true` beside `app.rest.auth.jwt` is refused; `loom.rest.E001`
|
|
540
|
+
passes on `custom: true`.
|
|
462
541
|
- **core:** `Rule.check(..., via=fn)` takes the violation from `fn`: a `str`
|
|
463
542
|
(the message) or a `RuleViolation` fails the rule, `None` passes it. A `bool`
|
|
464
543
|
or any other result raises `TypeError` naming the field, instead of `True`
|
|
@@ -602,6 +681,37 @@
|
|
|
602
681
|
|
|
603
682
|
### rest
|
|
604
683
|
|
|
684
|
+
- **rest:** a `QuerySpec` route filters and sorts only on the columns it
|
|
685
|
+
declares. Before, a client could filter or sort on any field the repository
|
|
686
|
+
could resolve. Now a filter on an undeclared column answers
|
|
687
|
+
`400 unsupported_query` naming the field, and so does a sort on one, with the
|
|
688
|
+
same answer whether or not the column exists. The primary key, which the
|
|
689
|
+
route orders by when the client names no sort, needs no declaration.
|
|
690
|
+
Declare `filterable` and `sortable` on the interface (its auto-CRUD `list`
|
|
691
|
+
route included) or on a route, which overrides it, as field references or
|
|
692
|
+
column names:
|
|
693
|
+
|
|
694
|
+
```python
|
|
695
|
+
class OrderRestInterface(RestInterface[Order]):
|
|
696
|
+
prefix = "/orders"
|
|
697
|
+
auto = True
|
|
698
|
+
filterable = (F(Order).status, F(Order).total)
|
|
699
|
+
sortable = (F(Order).created_at,)
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
In `app.rest.interfaces` both take column names (`[status, total]`).
|
|
703
|
+
`ALL` (`all` in YAML) keeps every scalar column and logs a warning naming
|
|
704
|
+
the route at startup. Only scalar columns of the use case's own model
|
|
705
|
+
(`UseCase[Model, ...]`) qualify. A related model's column (`warehouse.code`)
|
|
706
|
+
is refused, and so are JSON, array and text-search columns; lists, dicts
|
|
707
|
+
and structs, and an `Enum` or `Literal` declared without a column type, are
|
|
708
|
+
JSON. `InterfaceCompilationError` names the route and the field. It is also
|
|
709
|
+
raised for a declaration on a use case with no model, and for a route-level
|
|
710
|
+
declaration on a route without a `QuerySpec`; an inherited one is ignored.
|
|
711
|
+
`exists` and `not_exists` answer `400 unsupported_query`, and so do `like`
|
|
712
|
+
and `ilike` on a column that is not `str`. The repository's
|
|
713
|
+
`allowed_filter_fields` is unchanged: programmatic callers are not
|
|
714
|
+
restricted.
|
|
605
715
|
- **rest:** every route now resolves its request parameters and decodes its
|
|
606
716
|
body before the use case is built, so a request refused at that point
|
|
607
717
|
never runs the use case's constructor.
|
|
@@ -633,6 +743,20 @@
|
|
|
633
743
|
|
|
634
744
|
### prefect
|
|
635
745
|
|
|
746
|
+
- **prefect:** `FlowCtx.environment` is removed; nothing read it.
|
|
747
|
+
- **prefect:** the flow parameter `env` and the keys of a flow YAML's
|
|
748
|
+
`environments` block are loom environments (`production`, `staging`,
|
|
749
|
+
`development`, `test`); `prod`, `dev`, `local` or any other key or value is
|
|
750
|
+
a `ConfigError`. A run resolves the worker's environment (`LOOM_ENV`, else
|
|
751
|
+
production); `env` defaults to `None` and only confirms it, so a run whose
|
|
752
|
+
`env` differs fails before anything runs. The run hands the environment to
|
|
753
|
+
the runner, which takes its logger defaults from it and runs the deploy
|
|
754
|
+
checks when deployed; notifications report it. `deploy_flow` and
|
|
755
|
+
`discover_and_deploy_etls` take an optional `env` resolved the same way and
|
|
756
|
+
record it as the deployment's `env` parameter, so a deployment run on a
|
|
757
|
+
worker in another environment fails.
|
|
758
|
+
- **prefect:** the storage configuration of a flow run may be a config
|
|
759
|
+
directory.
|
|
636
760
|
- **prefect:** a placeholder counts from the run's scheduled start instead of
|
|
637
761
|
the wall clock. `${today-1d}`, `${yesterday}` and `${now±N}` counted from
|
|
638
762
|
`datetime.now()` inside the flow, so a queued run that started after
|
|
@@ -767,6 +891,60 @@
|
|
|
767
891
|
|
|
768
892
|
### core
|
|
769
893
|
|
|
894
|
+
- **core:** one environment selector and deploy checks (ADR 0005). loom had
|
|
895
|
+
two unconnected notions of environment (the logger's `dev`/`prod`, where an
|
|
896
|
+
unknown value meant `dev`, and `FlowCtx.environment`) and nothing checked a
|
|
897
|
+
deployed configuration. `loom.core.environment` now holds
|
|
898
|
+
`Environment` (`production`, `staging`, `development`, `test`) and
|
|
899
|
+
`resolve_environment`: the explicit argument, else `LOOM_ENV`, else
|
|
900
|
+
`production`; an unknown or empty value raises `ConfigError`. REST
|
|
901
|
+
`create_app`, Celery `create_app` and `bootstrap_worker` take
|
|
902
|
+
`environment=` and `config_dir=`, which loads `base.yaml` then
|
|
903
|
+
`<environment>.yaml` when present; explicit file lists keep working, one
|
|
904
|
+
form or the other. `create_kernel(environment=...)` registers the
|
|
905
|
+
environment in the container, so a use case can inject `Environment`.
|
|
906
|
+
`loom.core.checks` adds deploy checks with stable ids
|
|
907
|
+
(`@deploy_check("<area>.<E|W><nnn>")`), run at startup in production and
|
|
908
|
+
staging: `E` fails startup with `DeployCheckError`, `W` logs a warning, and
|
|
909
|
+
`checks.silenced: [ids]` silences by id with a startup warning naming them.
|
|
910
|
+
Initial checks: `loom.rest.E001` (neither a literal `app.rest.auth.jwt`
|
|
911
|
+
mapping nor the literal `app.rest.auth.custom: true`), `loom.rest.W001` (docs, redoc or OpenAPI
|
|
912
|
+
URL not `null`), `loom.logger.W001` (`console` renderer); they read keys as
|
|
913
|
+
written (`ConfigContext.raw`) and resolve no placeholder. Processes serving
|
|
914
|
+
no HTTP skip the `loom.rest` checks. `loom check --deploy [--env X]
|
|
915
|
+
[--skip AREA] <config>` runs them in CI without starting the application
|
|
916
|
+
and prints the areas it skipped.
|
|
917
|
+
- **core:** one place tells every loom process its environment and
|
|
918
|
+
configuration (ADR 0005). `LOOM__SECTION__KEY` variables override any
|
|
919
|
+
configuration key as the last layer (code defaults < `base.yaml` <
|
|
920
|
+
`<LOOM_ENV>.yaml` < `LOOM__*`, allowlisted keys only in production and
|
|
921
|
+
staging), merged as an OmegaConf dotlist; levels
|
|
922
|
+
match declared keys case-insensitively, a first level naming no known
|
|
923
|
+
section is a `ConfigError` naming the variable, values are parsed literals
|
|
924
|
+
(no `${` anywhere in them), an override sets one leaf, and one WARNING
|
|
925
|
+
line names the overridden keys without their values.
|
|
926
|
+
`loom.core.config.overrides.load_application_config` is the one loader
|
|
927
|
+
behind REST and Celery `create_app`, `bootstrap_worker`,
|
|
928
|
+
`loom check --deploy`, `ETLRunner.from_yaml`, `StreamingRunner.from_yaml`,
|
|
929
|
+
the migration locator and `load_kafka_settings`; a per-flow Prefect YAML is
|
|
930
|
+
a flow definition and is read without them. Deploy checks see the final configuration. `ETLRunner`,
|
|
931
|
+
`StreamingRunner` and the migration locator accept a config directory as
|
|
932
|
+
the factories do. They take `environment=`, take their logger defaults from
|
|
933
|
+
it and run the deploy checks when deployed, like the Prefect flows through
|
|
934
|
+
them; a Prefect run's `env` only confirms the worker's environment.
|
|
935
|
+
Only `loom.core.environment` names, reads or sets `LOOM_*` variables.
|
|
936
|
+
`checks.modules` lists the modules registering an
|
|
937
|
+
application's own checks, imported before every run, at startup and in
|
|
938
|
+
`loom check --deploy` (which puts `app.code_path` on the import path as
|
|
939
|
+
`create_app` does). `app.rest.auth.custom: true` declares an authenticator
|
|
940
|
+
passed in code, so `loom.rest.E001` reads the same answer in CI and at
|
|
941
|
+
startup. `parse_environment` validates a value naming an environment.
|
|
942
|
+
- **core:** the SQLAlchemy query compiler converts a filter value, and each
|
|
943
|
+
`in` item, as the repository converts a value it writes
|
|
944
|
+
(`loom.core.repository.sqlalchemy.values.to_column_value`, now shared by
|
|
945
|
+
both): an `Enum` member is bound as its value, a JSON column's value is
|
|
946
|
+
reduced to builtins. A plain `Enum` member as the value of a filter on a
|
|
947
|
+
string column failed to bind.
|
|
770
948
|
- **core:** a `BoundaryValidationError` no longer echoes the rejected value
|
|
771
949
|
(#347). msgspec's `Invalid enum value 'x'` (an `Enum`, `IntEnum` or `Literal`
|
|
772
950
|
field or dict key) and `Invalid value 'x'` (a tagged-union tag) become
|
|
@@ -953,6 +1131,29 @@
|
|
|
953
1131
|
|
|
954
1132
|
### rest
|
|
955
1133
|
|
|
1134
|
+
- **rest:** `?sort=` accepted any column. A cursor page put the sort
|
|
1135
|
+
column's raw value of its last row in `nextCursor` (base64 JSON), so any
|
|
1136
|
+
column, a secret one included, could be read through it, and a forged
|
|
1137
|
+
cursor could range-probe it. Offset pages leaked its order, and an unknown
|
|
1138
|
+
column answered `400 unsupported_query` (`Unknown filter field path`) while
|
|
1139
|
+
a known one answered `200`, so the model's columns could be enumerated. A
|
|
1140
|
+
route now sorts only by its declared `sortable` columns and its primary
|
|
1141
|
+
key, so a cursor carries only those values.
|
|
1142
|
+
- **rest:** a `page` whose offset, `(page - 1) * limit`, exceeds the largest
|
|
1143
|
+
signed 64-bit integer answers `400 query_validation` on `page` before any
|
|
1144
|
+
query runs.
|
|
1145
|
+
- **rest:** a `QuerySpec` filter value was typed by its spelling: `true` and
|
|
1146
|
+
`false` became booleans, text with a `.` a float and digits an integer,
|
|
1147
|
+
whatever the filtered field declared. `?code=0123` on a `str` field compared
|
|
1148
|
+
against `123`, and on Postgres a number bound to a text column answered
|
|
1149
|
+
`500`. Values of `eq`, `ne`, `gt`, `gte`, `lt`, `lte` and each item of `in`
|
|
1150
|
+
are now converted by the type of the declared filterable field, with the
|
|
1151
|
+
strict grammar of `Query()`: a `str` field keeps the text as sent, a
|
|
1152
|
+
boolean accepts only `true` or `false`, an `Enum` or `Literal` only its
|
|
1153
|
+
values, and a value its field's type refuses answers `400 query_validation`
|
|
1154
|
+
with `violations` naming the field. The field's constraints
|
|
1155
|
+
(`msgspec.Meta`) do not apply to a filter value, so `rank__gt=0` is valid
|
|
1156
|
+
on a column declared `ge=1`. `like` and `ilike` keep their pattern as text.
|
|
956
1157
|
- **rest:** the OpenAPI `limit` parameter of a `QuerySpec` route published
|
|
957
1158
|
`maximum: 1000` and `default: 50` whatever `RestApiDefaults.max_limit` said,
|
|
958
1159
|
while the router clamped `?limit=` to `max_limit`. The schema now publishes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: loom-kernel
|
|
3
|
-
Version:
|
|
3
|
+
Version: 4.0.0
|
|
4
4
|
Summary: Loom Python project
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -484,6 +484,10 @@ from loom.rest.fastapi.auto import create_app
|
|
|
484
484
|
app = create_app("config/api.yaml")
|
|
485
485
|
```
|
|
486
486
|
|
|
487
|
+
Run it with `LOOM_ENV=development`: an unset `LOOM_ENV` means production, where
|
|
488
|
+
the deploy checks refuse an API that authenticates nobody (`loom.rest.E001`).
|
|
489
|
+
See [Environments and deploy checks](docs/getting-started/environments.md).
|
|
490
|
+
|
|
487
491
|
For larger projects, use `mode: manifest` and a manifest module:
|
|
488
492
|
|
|
489
493
|
```python
|
|
@@ -360,6 +360,10 @@ from loom.rest.fastapi.auto import create_app
|
|
|
360
360
|
app = create_app("config/api.yaml")
|
|
361
361
|
```
|
|
362
362
|
|
|
363
|
+
Run it with `LOOM_ENV=development`: an unset `LOOM_ENV` means production, where
|
|
364
|
+
the deploy checks refuse an API that authenticates nobody (`loom.rest.E001`).
|
|
365
|
+
See [Environments and deploy checks](docs/getting-started/environments.md).
|
|
366
|
+
|
|
363
367
|
For larger projects, use `mode: manifest` and a manifest module:
|
|
364
368
|
|
|
365
369
|
```python
|
|
@@ -13,11 +13,14 @@ from loom.core.di.container import LoomContainer
|
|
|
13
13
|
if TYPE_CHECKING:
|
|
14
14
|
from loom.core.config import ConfigResolver
|
|
15
15
|
from loom.core.engine.metrics import MetricsAdapter
|
|
16
|
+
from loom.core.environment import Environment
|
|
16
17
|
from loom.core.job.job import Job
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
def create_app(
|
|
20
21
|
*config_paths: str,
|
|
22
|
+
config_dir: str | None = None,
|
|
23
|
+
environment: Environment | str | None = None,
|
|
21
24
|
jobs: Sequence[type[Job[Any]]] = (),
|
|
22
25
|
callbacks: Sequence[type[Any]] = (),
|
|
23
26
|
modules: Sequence[Callable[[LoomContainer], None]] = (),
|
|
@@ -27,7 +30,12 @@ def create_app(
|
|
|
27
30
|
"""Create a Celery app with all Loom job tasks registered.
|
|
28
31
|
|
|
29
32
|
Args:
|
|
30
|
-
*config_paths:
|
|
33
|
+
*config_paths: YAML config files merged left-to-right. Mutually
|
|
34
|
+
exclusive with *config_dir*.
|
|
35
|
+
config_dir: Directory holding ``base.yaml`` and the per-environment
|
|
36
|
+
overlays; ``<environment>.yaml`` loads after the base when present.
|
|
37
|
+
environment: Environment of the worker; overrides ``LOOM_ENV``, which
|
|
38
|
+
defaults to production when unset.
|
|
31
39
|
jobs: Concrete ``Job`` subclasses to register as Celery tasks.
|
|
32
40
|
Optional when ``app.discovery`` (modules/manifest) is configured.
|
|
33
41
|
callbacks: Optional callback classes for success/failure hooks.
|
|
@@ -42,6 +50,8 @@ def create_app(
|
|
|
42
50
|
"""
|
|
43
51
|
result = bootstrap_worker(
|
|
44
52
|
*config_paths,
|
|
53
|
+
config_dir=config_dir,
|
|
54
|
+
environment=environment,
|
|
45
55
|
jobs=jobs,
|
|
46
56
|
callbacks=callbacks,
|
|
47
57
|
modules=modules,
|
|
@@ -83,6 +83,7 @@ from loom.celery.runner import (
|
|
|
83
83
|
from loom.core.async_bridge import build_backend_options
|
|
84
84
|
from loom.core.bootstrap import KernelRuntime, create_kernel
|
|
85
85
|
from loom.core.cache.wiring import cache_module_for
|
|
86
|
+
from loom.core.checks import REST_CHECKS, enforce_deploy_checks
|
|
86
87
|
from loom.core.config import (
|
|
87
88
|
ConfigContext,
|
|
88
89
|
ConfigKey,
|
|
@@ -90,10 +91,12 @@ from loom.core.config import (
|
|
|
90
91
|
with_default_resolvers,
|
|
91
92
|
)
|
|
92
93
|
from loom.core.config.errors import ConfigError
|
|
94
|
+
from loom.core.config.overrides import load_application_config
|
|
93
95
|
from loom.core.di.container import LoomContainer
|
|
94
96
|
from loom.core.discovery._utils import collect_from_modules, import_modules
|
|
95
97
|
from loom.core.engine.compilable import Compilable
|
|
96
98
|
from loom.core.engine.metrics import MetricsAdapter
|
|
99
|
+
from loom.core.environment import Environment, resolve_environment, select_config_paths
|
|
97
100
|
from loom.core.job.job import Job
|
|
98
101
|
from loom.core.model import BaseModel
|
|
99
102
|
from loom.core.observability.config import ObservabilityConfig
|
|
@@ -666,14 +669,18 @@ def _compile_models(
|
|
|
666
669
|
|
|
667
670
|
def _build_observability_runtime(
|
|
668
671
|
ctx: ConfigContext | Mapping[str, Any],
|
|
672
|
+
environment: Environment = Environment.PRODUCTION,
|
|
669
673
|
) -> ObservabilityRuntime:
|
|
670
|
-
"""Build the shared observability runtime from top-level config.
|
|
674
|
+
"""Build the shared observability runtime from top-level config.
|
|
675
|
+
|
|
676
|
+
Defaults apply only when the section is absent; one that fails validation
|
|
677
|
+
stops the worker instead of silently dropping its settings.
|
|
678
|
+
"""
|
|
671
679
|
config = _ensure_config_context(ctx)
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
return ObservabilityRuntime.from_config(observability_cfg)
|
|
680
|
+
observability_cfg = config.section_or_default(
|
|
681
|
+
ConfigKey.OBSERVABILITY, ObservabilityConfig, ObservabilityConfig()
|
|
682
|
+
)
|
|
683
|
+
return ObservabilityRuntime.from_config(observability_cfg, environment=environment)
|
|
677
684
|
|
|
678
685
|
|
|
679
686
|
def _compile_db_layer(
|
|
@@ -835,6 +842,8 @@ def _reject_mcp_markers(
|
|
|
835
842
|
|
|
836
843
|
def bootstrap_worker(
|
|
837
844
|
*config_paths: str,
|
|
845
|
+
config_dir: str | None = None,
|
|
846
|
+
environment: Environment | str | None = None,
|
|
838
847
|
jobs: Sequence[type[Job[Any]]] = (),
|
|
839
848
|
use_cases: Sequence[type[Compilable]] = (),
|
|
840
849
|
interfaces: Sequence[type[Any]] = (),
|
|
@@ -845,9 +854,15 @@ def bootstrap_worker(
|
|
|
845
854
|
) -> WorkerBootstrapResult:
|
|
846
855
|
"""Bootstrap a Celery worker process and register all Job tasks.
|
|
847
856
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
857
|
+
Resolves the environment once (*environment*, else ``LOOM_ENV``, else
|
|
858
|
+
production; see :mod:`loom.core.environment`), loads configuration from
|
|
859
|
+
``config_dir`` or ``config_paths``, compiles all ``Job`` subclasses,
|
|
860
|
+
registers Celery tasks, and connects worker lifecycle signals for
|
|
861
|
+
per-process async bridge management.
|
|
862
|
+
|
|
863
|
+
In production and staging the deploy checks run (see
|
|
864
|
+
:mod:`loom.core.checks`), except the ``loom.rest`` ones: a worker serves
|
|
865
|
+
no HTTP. The environment is registered in the container.
|
|
851
866
|
|
|
852
867
|
This function is **independent** of
|
|
853
868
|
:func:`~loom.core.bootstrap.bootstrap.bootstrap_app` — it targets the
|
|
@@ -865,9 +880,14 @@ def bootstrap_worker(
|
|
|
865
880
|
persistence.
|
|
866
881
|
|
|
867
882
|
Args:
|
|
868
|
-
*config_paths:
|
|
869
|
-
|
|
870
|
-
|
|
883
|
+
*config_paths: Paths to YAML configuration files, merged
|
|
884
|
+
left-to-right; later files override earlier ones. Mutually
|
|
885
|
+
exclusive with *config_dir*.
|
|
886
|
+
config_dir: Local directory holding ``base.yaml`` and the
|
|
887
|
+
per-environment overlays: ``base.yaml`` loads first, then
|
|
888
|
+
``<environment>.yaml`` when present. Either way the
|
|
889
|
+
``LOOM__SECTION__KEY`` variables merge last.
|
|
890
|
+
environment: Environment of the worker; overrides ``LOOM_ENV``.
|
|
871
891
|
jobs: Concrete ``Job`` subclasses to compile/register. When
|
|
872
892
|
omitted, jobs are discovered from ``app.discovery`` using
|
|
873
893
|
mode ``modules`` or ``manifest``.
|
|
@@ -899,8 +919,11 @@ def bootstrap_worker(
|
|
|
899
919
|
configured Celery application.
|
|
900
920
|
|
|
901
921
|
Raises:
|
|
902
|
-
ConfigError: If
|
|
903
|
-
|
|
922
|
+
ConfigError: If neither or both of *config_paths* and *config_dir*
|
|
923
|
+
are given, the environment is unknown, or a required
|
|
924
|
+
configuration section is missing or fails validation.
|
|
925
|
+
DeployCheckError: When a deploy check of level error fails in
|
|
926
|
+
production or staging.
|
|
904
927
|
RuntimeError: If no ``app.discovery`` config is provided and no
|
|
905
928
|
``jobs`` are declared, or if discovery finds no ``Job`` classes.
|
|
906
929
|
|
|
@@ -915,10 +938,17 @@ def bootstrap_worker(
|
|
|
915
938
|
)
|
|
916
939
|
result.celery_app.start()
|
|
917
940
|
"""
|
|
918
|
-
|
|
941
|
+
resolved_environment = resolve_environment(environment)
|
|
942
|
+
paths = select_config_paths(
|
|
943
|
+
config_paths, config_dir, resolved_environment, caller="bootstrap_worker"
|
|
944
|
+
)
|
|
945
|
+
ctx = load_application_config(
|
|
946
|
+
*paths, resolvers=with_default_resolvers(resolvers), environment=resolved_environment
|
|
947
|
+
)
|
|
919
948
|
app_cfg = ctx.section_optional(ConfigKey.APP, _WorkerAppConfig) or _WorkerAppConfig()
|
|
920
949
|
celery_cfg = ctx.section(ConfigKey.CELERY, CeleryConfig)
|
|
921
|
-
observability_runtime = _build_observability_runtime(ctx)
|
|
950
|
+
observability_runtime = _build_observability_runtime(ctx, resolved_environment)
|
|
951
|
+
enforce_deploy_checks(ctx, resolved_environment, skip=(REST_CHECKS,))
|
|
922
952
|
async_runtime = _build_async_runtime(celery_cfg.runtime)
|
|
923
953
|
|
|
924
954
|
resolved = _resolve_compilables_and_jobs(ctx, jobs, use_cases)
|
|
@@ -951,6 +981,7 @@ def bootstrap_worker(
|
|
|
951
981
|
modules=runtime_modules,
|
|
952
982
|
metrics=metrics,
|
|
953
983
|
uow_factory=uow_factory,
|
|
984
|
+
environment=resolved_environment,
|
|
954
985
|
)
|
|
955
986
|
_reject_agent_markers(resolved.compilables, kernel)
|
|
956
987
|
_reject_mcp_markers(resolved.compilables, kernel)
|
|
@@ -37,12 +37,13 @@ from celery import Celery # type: ignore[import-untyped]
|
|
|
37
37
|
from kombu import Queue # type: ignore[import-untyped]
|
|
38
38
|
|
|
39
39
|
from loom.core.model import LoomFrozenStruct
|
|
40
|
+
from loom.core.model.types import PositiveInt
|
|
40
41
|
|
|
41
42
|
if TYPE_CHECKING:
|
|
42
43
|
from loom.core.job.job import Job
|
|
43
44
|
|
|
44
45
|
|
|
45
|
-
class CeleryRuntimeConfig(LoomFrozenStruct, frozen=True, kw_only=True):
|
|
46
|
+
class CeleryRuntimeConfig(LoomFrozenStruct, frozen=True, kw_only=True, forbid_unknown_fields=True):
|
|
46
47
|
"""Async bridge settings for a Celery worker process.
|
|
47
48
|
|
|
48
49
|
Attributes:
|
|
@@ -51,15 +52,16 @@ class CeleryRuntimeConfig(LoomFrozenStruct, frozen=True, kw_only=True):
|
|
|
51
52
|
use_uvloop: When ``True`` and the backend is ``"asyncio"``, the worker
|
|
52
53
|
uses uvloop on supported platforms.
|
|
53
54
|
shutdown_timeout_ms: Maximum milliseconds to wait for in-flight async
|
|
54
|
-
work during worker shutdown. ``None`` waits
|
|
55
|
+
work during worker shutdown, above zero. ``None`` waits
|
|
56
|
+
indefinitely.
|
|
55
57
|
"""
|
|
56
58
|
|
|
57
59
|
backend: Literal["asyncio", "trio"] = "asyncio"
|
|
58
60
|
use_uvloop: bool = False
|
|
59
|
-
shutdown_timeout_ms:
|
|
61
|
+
shutdown_timeout_ms: PositiveInt | None = None
|
|
60
62
|
|
|
61
63
|
|
|
62
|
-
class CeleryConfig(LoomFrozenStruct, frozen=True, kw_only=True):
|
|
64
|
+
class CeleryConfig(LoomFrozenStruct, frozen=True, kw_only=True, forbid_unknown_fields=True):
|
|
63
65
|
"""Broker and worker settings for the Celery application.
|
|
64
66
|
|
|
65
67
|
Attributes:
|
|
@@ -109,7 +111,7 @@ class CeleryConfig(LoomFrozenStruct, frozen=True, kw_only=True):
|
|
|
109
111
|
runtime: CeleryRuntimeConfig = msgspec.field(default_factory=CeleryRuntimeConfig)
|
|
110
112
|
|
|
111
113
|
|
|
112
|
-
class JobConfig(LoomFrozenStruct, frozen=True, kw_only=True):
|
|
114
|
+
class JobConfig(LoomFrozenStruct, frozen=True, kw_only=True, forbid_unknown_fields=True):
|
|
113
115
|
"""Per-job routing and execution overrides applied at bootstrap.
|
|
114
116
|
|
|
115
117
|
Fields set to ``None`` leave the corresponding ClassVar on the
|
|
@@ -4,7 +4,9 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import typer
|
|
6
6
|
|
|
7
|
+
from loom.cli.check import check
|
|
7
8
|
from loom.cli.schema import schema_app
|
|
8
9
|
|
|
9
|
-
app = typer.Typer(no_args_is_help=True, help="Operate
|
|
10
|
+
app = typer.Typer(no_args_is_help=True, help="Operate a loom application.")
|
|
10
11
|
app.add_typer(schema_app, name="schema")
|
|
12
|
+
app.command("check")(check)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""``loom check --deploy``: run the deploy checks without starting the application.
|
|
2
|
+
|
|
3
|
+
Meant for CI: it loads the configuration the application would load, runs
|
|
4
|
+
every deploy check whatever the environment, prints each finding with its id
|
|
5
|
+
and hint, and exits ``1`` when an error remains. loom's checks read keys as
|
|
6
|
+
written and resolve no placeholder; the configuration loads with loom's
|
|
7
|
+
default resolvers, so a ``${secrets:...}`` value no check reads is left alone.
|
|
8
|
+
|
|
9
|
+
The command cannot tell which kind of process a configuration is for: a REST
|
|
10
|
+
application may declare ``celery`` for its job service and a worker may share
|
|
11
|
+
``app.rest``. ``--skip loom.rest`` (repeatable, any id or area) leaves out
|
|
12
|
+
what the process does not run, as the worker and the runners do at startup.
|
|
13
|
+
|
|
14
|
+
``app.code_path`` (``src`` by default, relative to the first file) joins the
|
|
15
|
+
import path as ``create_app`` adds it, so the modules of ``checks.modules``
|
|
16
|
+
import here as they do at startup.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import importlib
|
|
22
|
+
import importlib.util
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
from typing import Annotated
|
|
25
|
+
|
|
26
|
+
import typer
|
|
27
|
+
|
|
28
|
+
from loom.core.checks import DeployReport, run_deploy_checks
|
|
29
|
+
from loom.core.config import ConfigContext, with_default_resolvers
|
|
30
|
+
from loom.core.config.errors import ConfigError
|
|
31
|
+
from loom.core.config.overrides import load_application_config
|
|
32
|
+
from loom.core.environment import Environment, resolve_environment, select_config_paths
|
|
33
|
+
from loom.core.locator import DEFAULT_CODE_PATH, add_code_path
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def check(
|
|
37
|
+
config: Annotated[
|
|
38
|
+
list[Path],
|
|
39
|
+
typer.Argument(help="A config directory (base.yaml plus overlays) or YAML files."),
|
|
40
|
+
],
|
|
41
|
+
deploy: Annotated[bool, typer.Option("--deploy", help="Run the deploy checks.")] = False,
|
|
42
|
+
env: Annotated[
|
|
43
|
+
str | None,
|
|
44
|
+
typer.Option("--env", help="Environment picking the overlay; defaults to LOOM_ENV."),
|
|
45
|
+
] = None,
|
|
46
|
+
skip: Annotated[
|
|
47
|
+
list[str] | None,
|
|
48
|
+
typer.Option("--skip", help="A check id or area to leave out, e.g. loom.rest; repeatable."),
|
|
49
|
+
] = None,
|
|
50
|
+
) -> None:
|
|
51
|
+
"""Run the deploy checks against the configuration, for CI."""
|
|
52
|
+
if not deploy:
|
|
53
|
+
typer.echo("only deploy checks exist: run 'loom check --deploy <config>'.", err=True)
|
|
54
|
+
raise typer.Exit(2)
|
|
55
|
+
_load_check_packages()
|
|
56
|
+
try:
|
|
57
|
+
environment = resolve_environment(env)
|
|
58
|
+
paths = _config_paths(config, environment)
|
|
59
|
+
context = load_application_config(
|
|
60
|
+
*paths, resolvers=with_default_resolvers(()), environment=environment
|
|
61
|
+
)
|
|
62
|
+
_add_code_path(context, Path(paths[0]).resolve().parent)
|
|
63
|
+
report = run_deploy_checks(context, skip=tuple(skip or ()))
|
|
64
|
+
except ConfigError as exc:
|
|
65
|
+
typer.echo(str(exc), err=True)
|
|
66
|
+
raise typer.Exit(1) from exc
|
|
67
|
+
_print(report, environment, tuple(skip or ()))
|
|
68
|
+
if report.errors:
|
|
69
|
+
raise typer.Exit(1)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _load_check_packages() -> None:
|
|
73
|
+
"""Import the packages registering loom's checks; the REST ones need the rest extra."""
|
|
74
|
+
importlib.import_module("loom.core.logger")
|
|
75
|
+
if importlib.util.find_spec("fastapi") is not None:
|
|
76
|
+
importlib.import_module("loom.rest")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _add_code_path(context: ConfigContext, config_dir: Path) -> None:
|
|
80
|
+
raw = context.raw("app.code_path", DEFAULT_CODE_PATH)
|
|
81
|
+
if not isinstance(raw, str) or "${" in raw:
|
|
82
|
+
raise ConfigError(
|
|
83
|
+
"app.code_path must be a literal path for loom check: a placeholder or a "
|
|
84
|
+
"non-string value cannot name the directory its check modules import from"
|
|
85
|
+
)
|
|
86
|
+
add_code_path(raw, config_dir)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _config_paths(config: list[Path], environment: Environment) -> tuple[str, ...]:
|
|
90
|
+
directory = config[0] if len(config) == 1 and config[0].is_dir() else None
|
|
91
|
+
if directory is None and any(path.is_dir() for path in config):
|
|
92
|
+
raise ConfigError("pass one config directory or YAML files, not both")
|
|
93
|
+
files = () if directory is not None else tuple(str(path) for path in config)
|
|
94
|
+
return select_config_paths(files, directory, environment, caller="loom check")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _print(report: DeployReport, environment: Environment, skipped: tuple[str, ...]) -> None:
|
|
98
|
+
typer.echo(f"environment: {environment}")
|
|
99
|
+
if skipped:
|
|
100
|
+
typer.echo(f"skipped: {', '.join(skipped)}")
|
|
101
|
+
if report.silenced:
|
|
102
|
+
typer.echo(f"silenced: {', '.join(report.silenced)}")
|
|
103
|
+
for result in report.results:
|
|
104
|
+
typer.echo(f"{result.level.upper()} {result.describe()}")
|
|
105
|
+
typer.echo(f"{len(report.errors)} error(s), {len(report.warnings)} warning(s)")
|
|
@@ -33,6 +33,7 @@ from loom.core.engine.compilable import Compilable
|
|
|
33
33
|
from loom.core.engine.compiler import UseCaseCompiler
|
|
34
34
|
from loom.core.engine.executor import RuntimeExecutor
|
|
35
35
|
from loom.core.engine.metrics import MetricsAdapter
|
|
36
|
+
from loom.core.environment import Environment, resolve_environment
|
|
36
37
|
from loom.core.logger import LoggerPort, get_logger
|
|
37
38
|
from loom.core.use_case.factory import UseCaseFactory
|
|
38
39
|
|
|
@@ -77,6 +78,7 @@ def bootstrap_app(
|
|
|
77
78
|
modules: Sequence[Callable[[LoomContainer], None]] = (),
|
|
78
79
|
logger: LoggerPort | None = None,
|
|
79
80
|
metrics: MetricsAdapter | None = None,
|
|
81
|
+
environment: Environment | str | None = None,
|
|
80
82
|
) -> BootstrapResult:
|
|
81
83
|
"""Run the deterministic Loom bootstrap pipeline.
|
|
82
84
|
|
|
@@ -97,6 +99,11 @@ def bootstrap_app(
|
|
|
97
99
|
Executed in declaration order before compilation.
|
|
98
100
|
logger: Optional logger. Falls back to the framework default.
|
|
99
101
|
metrics: Optional metrics adapter passed to the compiler.
|
|
102
|
+
environment: Environment of the application, resolved like
|
|
103
|
+
:func:`~loom.core.environment.resolve_environment` (``LOOM_ENV``,
|
|
104
|
+
else production) when ``None``. Registered at ``APPLICATION``
|
|
105
|
+
scope with the configuration, before the modules run, so a
|
|
106
|
+
module's service can resolve it.
|
|
100
107
|
|
|
101
108
|
Returns:
|
|
102
109
|
:class:`BootstrapResult` with container, compiler, and factory.
|
|
@@ -117,12 +124,14 @@ def bootstrap_app(
|
|
|
117
124
|
app = create_fastapi_app(result, RouteSources(python=[OrderRestInterface]))
|
|
118
125
|
"""
|
|
119
126
|
_logger = logger or get_logger("loom.bootstrap")
|
|
127
|
+
resolved_environment = resolve_environment(environment)
|
|
120
128
|
|
|
121
129
|
try:
|
|
122
130
|
# Step 1 — Container + config binding
|
|
123
131
|
_logger.info("[BOOT] Initialising DI container")
|
|
124
132
|
container = LoomContainer()
|
|
125
133
|
container.register(type(config), lambda: config, scope=Scope.APPLICATION)
|
|
134
|
+
container.register(Environment, lambda: resolved_environment, scope=Scope.APPLICATION)
|
|
126
135
|
|
|
127
136
|
# Step 2 — User module bindings
|
|
128
137
|
for module in modules:
|