loom-kernel 2.22.3__tar.gz → 3.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-3.0.0}/CHANGELOG.md +60 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/PKG-INFO +1 -1
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/introspection.py +26 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/mixins.py +4 -11
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +17 -3
- loom_kernel-3.0.0/src/loom/core/repository/sqlalchemy/values.py +51 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/__init__.py +2 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/compiler.py +141 -6
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/config.py +21 -2
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/fastapi/router_runtime.py +117 -32
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/model.py +44 -1
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/.gitignore +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/LICENSE +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/README.md +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/pyproject.toml +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/_concurrency.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/_filters.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/_paths.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/_roles.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/_startup.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/_transport.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/_usecase.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/a2a/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/a2a/_binding.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/a2a/_handlers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/a2a/_rpc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/a2a/card.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/a2a/events.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/a2a/server.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/abc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/bootstrap.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/_compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/_fingerprint.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/_plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/phases/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/phases/_capabilities.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/phases/_conversation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/phases/_feedable.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/phases/_hook.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/phases/_instructions.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/phases/_limits.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/phases/_model_role.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/phases/_output.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/compiler/phases/_state.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/declarative/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/declarative/_envelope.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/declarative/_schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/declarative/_v1.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/declarative/schemas/agent-spec-v1.schema.json +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/describe.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_a2a.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_capabilities.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_engine.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_escape.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_events.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_guards.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_history.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_instructions.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_limits.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_mcp.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_models.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_native.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_output.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_returns.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_schemas.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/_spec.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/extras/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/extras/a2a.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/extras/handlebars.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/extras/mcp.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/extras/skills.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/provider.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/providers/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/providers/_shared.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/providers/anthropic.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/providers/bedrock.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/providers/gateway.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/providers/openai.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/engines/pydantic_ai/providers/typesafe.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/etl/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/etl/_batch.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/etl/_columns.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/etl/_frames.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/etl/_ledger.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/etl/_runner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/etl/_validation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/fastapi/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/fastapi/endpoints.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/fastapi/response.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/fastapi/streaming.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/inference.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/pricing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/remote_auth.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/runtime/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/runtime/_bounded.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/runtime/_chain.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/runtime/_conversation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/runtime/_grants.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/runtime/_handle.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/runtime/_health.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/runtime/_hooks.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/runtime/_lifecycle.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/runtime/_limits.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/runtime/_mcp.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/validate/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/ai/validate/__main__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/celery/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/celery/auto.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/celery/bootstrap.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/celery/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/celery/constants.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/celery/runner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/celery/service.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/cli/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/cli/app.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/cli/schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/async_bridge.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/authz/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/authz/_decide.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/authz/_grants.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/authz/_roles.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/authz/_scope.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/authz/elevation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/authz/product.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/backend/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/backend/core_model.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/backend/protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/backend/scoped_ddl.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/backend/sqlalchemy.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/bootstrap/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/bootstrap/kernel.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/_batching.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/_single_flight.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/abc/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/abc/backend.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/abc/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/abc/dependency.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/calls.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/codec.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/decorators.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/dependency.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/gateway.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/keys.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/memory.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/repository.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/result_codec.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/serializer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/cache/wiring.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/command/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/command/adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/command/base.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/command/field.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/command/introspection.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/_boto3.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/_includes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/_resolver_utils.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/binder.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/configurable.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/context.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/keys.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/loader.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/model.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/observability.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/resolver.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/secrets.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/config/ssm.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/contracts/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/contracts/manifest.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/di/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/di/container.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/di/scope.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/discovery/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/discovery/_utils.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/discovery/base.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/discovery/interfaces.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/discovery/manifest.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/discovery/modules.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/engine/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/engine/compilable.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/engine/compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/engine/events.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/engine/executor.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/engine/metrics.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/engine/plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/engine/post_commit.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/errors/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/errors/codes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/errors/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/expr/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/expr/eval.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/expr/nodes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/expr/refs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/identity/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/identity/context.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/identity/identity.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/identity/issuer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/identity/wire.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/introspection/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/introspection/base.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/introspection/describe.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/job/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/job/callback.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/job/context.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/job/handle.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/job/job.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/job/service.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/locator.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/logger/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/logger/abc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/logger/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/logger/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/logger/structlogger.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/_json_schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/_loom_type.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/base.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/convert.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/enums.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/field.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/partition.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/privilege.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/projection.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/relation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/scoped.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/struct.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/timestamped.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/types.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/model/types_postgres.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/event.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/observer/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/observer/noop.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/observer/otel.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/observer/structlog.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/otel_ids.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/runtime.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/span.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/observability/topology.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/persistence/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/persistence/abc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/persistence/none.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/persistence/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/plugins/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/plugins/entrypoints.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/plugins/optional.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/projection/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/projection/loaders.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/projection/runtime.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/abc/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/abc/cursor.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/abc/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/abc/query.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/abc/query_compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/abc/repo_for.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/abc/repository.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/abc/session_scope.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/dynamodb/backend.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/dynamodb/repository.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/mongo/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/mongo/backend.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/mongo/ids.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/mongo/query_compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/mongo/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/mongo/repository.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/mongo/uow.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/mongo/values.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/mutation.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/registration.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/backend.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/migrations/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/migrations/env_template.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/migrations/hook.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/migrations/operations.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/migrations/runners.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/bootstrap.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/elevate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/guard/0001.sql +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/guard/0002.sql +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/guard/preflight.sql +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/integrity.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/partitions.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/provider.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/sources.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/rls/verify.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/session_settings.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/response/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/response/base.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/routing/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/routing/ref.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/routing/resolver.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/runner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/schema/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/schema/schema_mode.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/schema_names.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/abc/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/abc/contracts.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/abc/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/caller_bound.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/roles.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/sql/service.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/symbols.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/tracing/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/tracing/context.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/transaction.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/transport/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/transport/adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/uow/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/uow/abc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/uow/context.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/_predicates.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/agent_markers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/compute.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/constants.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/factory.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/field_ref.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/invoker.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/keys.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/markers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/mcp_markers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/outcome.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/rule.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/core/use_case/use_case.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/_uri.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_format_registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_historify/_common.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_historify/_log.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_merge.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_path_template.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_predicate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/_write_policy.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/_frame.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/_historify.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/_reader.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/_schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/_streaming.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/_writer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/polars/provider.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/spark/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/spark/_historify.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/spark/_reader.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/spark/_schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/spark/_writer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/backends/spark/provider.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/checkpoint/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/checkpoint/_options.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/checkpoint/_paths.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/checkpoint/_scope.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/checkpoint/_store.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/compiler/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/compiler/_binding.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/compiler/_compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/compiler/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/compiler/_filter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/compiler/_plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/compiler/_validators.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/compiler/_validators_agents.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/compiler/_validators_config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/compiler/_validators_step.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/_format.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/_read_options.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/_utils.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/_with_agent.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/_write_options.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/expr/_params.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/source/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/source/_from.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/source/_from_config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/source/_specs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_client.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_file.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_into.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_table.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/declarative/target/_temp.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/executor/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/executor/_agents.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/executor/_dispatcher.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/executor/_executor.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/_registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/sources/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/sources/_mongo.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/sources/_serialization.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/targets/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/lineage/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/lineage/_config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/lineage/_observer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/lineage/_records.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/maintenance/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/maintenance/_builder.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/maintenance/_ops.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/maintenance/_protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/maintenance/_runner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/maintenance/_step.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/pipeline/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/pipeline/_generics.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/pipeline/_params.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/pipeline/_process.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/pipeline/_sql.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/pipeline/_step.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/pipeline/_step_client.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/runner/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/runner/_agents.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/runner/_providers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/runner/_wiring.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/runner/config_loader.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/runner/core.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/runner/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/runner/filtering.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/runtime/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/runtime/_config_values.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/runtime/contracts.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/schema/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/schema/_contract.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/schema/_schema.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/storage/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/storage/_config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/storage/_file_locator.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/storage/_locator.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/storage/routing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/testing/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/testing/_result.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/testing/_runners.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/testing/_scenario.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/testing/_stubs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/etl/testing/spark.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/_async.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/_config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/_ctx.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/_flow_yaml.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/_meta.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/_placeholders.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/_summary.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/deploy/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/deploy/_discovery.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/deploy/_schedule.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/deploy/_yaml_etls.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/deploy/entrypoint.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_assemble.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_backfill.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_backfill_body.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_body.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_common.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_factory.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_hooks.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_maintenance.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_params.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_run_name.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_runtime.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_signature.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/flow/_stages.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/manifest/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/manifest/_model.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/manifest/_s3.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/manifest/_store.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/notify/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/notify/_event.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/notify/_factory.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/notify/_format.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/notify/_port.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/notify/_slack.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/notify/_sns.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/observer/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/observer/_flow.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/observer/_logging_bridge.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/observer/_manifest.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prefect/observer/_task_run.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prometheus/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prometheus/_instruments.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prometheus/adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prometheus/kafka.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prometheus/lifecycle.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/prometheus/middleware.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/py.typed +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/_body.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/auth/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/auth/abc.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/auth/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/auth/jwt.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/auth/middleware.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/autocrud.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/constants.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/cors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/fastapi/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/fastapi/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/fastapi/app.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/fastapi/auto.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/fastapi/health.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/fastapi/openapi.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/fastapi/response.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/fastapi/sql.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/middleware.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/rest/rest_adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/_batch_spans.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/_operators.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/bytewax/runner.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/compiler/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/compiler/_bindings.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/compiler/_compiler.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/compiler/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/compiler/_plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/compiler/phases/build_plan.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/compiler/phases/validate.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/core/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/core/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/core/_exceptions.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/core/_message.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/core/_tracing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/core/_typing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/graph/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/graph/_flow.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/_codec.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/_config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/_errors.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/_message.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/_record.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/_wire.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/client/_retry.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/mongo/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/mongo/_config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/mongo/_event.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/mongo/_normalize.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_boundary.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_branches.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_decompose.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_fork.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_helpers.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_mongo.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_protocols.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_router.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_shape.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_sink.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_step.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_table/common.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_table/config.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/_with.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/nodes/refs.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/streaming/testing.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/testing/__init__.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/testing/agents.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/testing/golden.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/testing/http_harness.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/testing/in_memory.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/testing/repository_harness.py +0 -0
- {loom_kernel-2.22.3 → loom_kernel-3.0.0}/src/loom/testing/runner.py +0 -0
|
@@ -602,6 +602,37 @@
|
|
|
602
602
|
|
|
603
603
|
### rest
|
|
604
604
|
|
|
605
|
+
- **rest:** a `QuerySpec` route filters and sorts only on the columns it
|
|
606
|
+
declares. Before, a client could filter or sort on any field the repository
|
|
607
|
+
could resolve. Now a filter on an undeclared column answers
|
|
608
|
+
`400 unsupported_query` naming the field, and so does a sort on one, with the
|
|
609
|
+
same answer whether or not the column exists. The primary key, which the
|
|
610
|
+
route orders by when the client names no sort, needs no declaration.
|
|
611
|
+
Declare `filterable` and `sortable` on the interface (its auto-CRUD `list`
|
|
612
|
+
route included) or on a route, which overrides it, as field references or
|
|
613
|
+
column names:
|
|
614
|
+
|
|
615
|
+
```python
|
|
616
|
+
class OrderRestInterface(RestInterface[Order]):
|
|
617
|
+
prefix = "/orders"
|
|
618
|
+
auto = True
|
|
619
|
+
filterable = (F(Order).status, F(Order).total)
|
|
620
|
+
sortable = (F(Order).created_at,)
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
In `app.rest.interfaces` both take column names (`[status, total]`).
|
|
624
|
+
`ALL` (`all` in YAML) keeps every scalar column and logs a warning naming
|
|
625
|
+
the route at startup. Only scalar columns of the use case's own model
|
|
626
|
+
(`UseCase[Model, ...]`) qualify. A related model's column (`warehouse.code`)
|
|
627
|
+
is refused, and so are JSON, array and text-search columns; lists, dicts
|
|
628
|
+
and structs, and an `Enum` or `Literal` declared without a column type, are
|
|
629
|
+
JSON. `InterfaceCompilationError` names the route and the field. It is also
|
|
630
|
+
raised for a declaration on a use case with no model, and for a route-level
|
|
631
|
+
declaration on a route without a `QuerySpec`; an inherited one is ignored.
|
|
632
|
+
`exists` and `not_exists` answer `400 unsupported_query`, and so do `like`
|
|
633
|
+
and `ilike` on a column that is not `str`. The repository's
|
|
634
|
+
`allowed_filter_fields` is unchanged: programmatic callers are not
|
|
635
|
+
restricted.
|
|
605
636
|
- **rest:** every route now resolves its request parameters and decodes its
|
|
606
637
|
body before the use case is built, so a request refused at that point
|
|
607
638
|
never runs the use case's constructor.
|
|
@@ -767,6 +798,12 @@
|
|
|
767
798
|
|
|
768
799
|
### core
|
|
769
800
|
|
|
801
|
+
- **core:** the SQLAlchemy query compiler converts a filter value, and each
|
|
802
|
+
`in` item, as the repository converts a value it writes
|
|
803
|
+
(`loom.core.repository.sqlalchemy.values.to_column_value`, now shared by
|
|
804
|
+
both): an `Enum` member is bound as its value, a JSON column's value is
|
|
805
|
+
reduced to builtins. A plain `Enum` member as the value of a filter on a
|
|
806
|
+
string column failed to bind.
|
|
770
807
|
- **core:** a `BoundaryValidationError` no longer echoes the rejected value
|
|
771
808
|
(#347). msgspec's `Invalid enum value 'x'` (an `Enum`, `IntEnum` or `Literal`
|
|
772
809
|
field or dict key) and `Invalid value 'x'` (a tagged-union tag) become
|
|
@@ -953,6 +990,29 @@
|
|
|
953
990
|
|
|
954
991
|
### rest
|
|
955
992
|
|
|
993
|
+
- **rest:** `?sort=` accepted any column. A cursor page put the sort
|
|
994
|
+
column's raw value of its last row in `nextCursor` (base64 JSON), so any
|
|
995
|
+
column, a secret one included, could be read through it, and a forged
|
|
996
|
+
cursor could range-probe it. Offset pages leaked its order, and an unknown
|
|
997
|
+
column answered `400 unsupported_query` (`Unknown filter field path`) while
|
|
998
|
+
a known one answered `200`, so the model's columns could be enumerated. A
|
|
999
|
+
route now sorts only by its declared `sortable` columns and its primary
|
|
1000
|
+
key, so a cursor carries only those values.
|
|
1001
|
+
- **rest:** a `page` whose offset, `(page - 1) * limit`, exceeds the largest
|
|
1002
|
+
signed 64-bit integer answers `400 query_validation` on `page` before any
|
|
1003
|
+
query runs.
|
|
1004
|
+
- **rest:** a `QuerySpec` filter value was typed by its spelling: `true` and
|
|
1005
|
+
`false` became booleans, text with a `.` a float and digits an integer,
|
|
1006
|
+
whatever the filtered field declared. `?code=0123` on a `str` field compared
|
|
1007
|
+
against `123`, and on Postgres a number bound to a text column answered
|
|
1008
|
+
`500`. Values of `eq`, `ne`, `gt`, `gte`, `lt`, `lte` and each item of `in`
|
|
1009
|
+
are now converted by the type of the declared filterable field, with the
|
|
1010
|
+
strict grammar of `Query()`: a `str` field keeps the text as sent, a
|
|
1011
|
+
boolean accepts only `true` or `false`, an `Enum` or `Literal` only its
|
|
1012
|
+
values, and a value its field's type refuses answers `400 query_validation`
|
|
1013
|
+
with `violations` naming the field. The field's constraints
|
|
1014
|
+
(`msgspec.Meta`) do not apply to a filter value, so `rank__gt=0` is valid
|
|
1015
|
+
on a column declared `ge=1`. `like` and `ilike` keep their pattern as text.
|
|
956
1016
|
- **rest:** the OpenAPI `limit` parameter of a `QuerySpec` route published
|
|
957
1017
|
`maximum: 1000` and `default: 50` whatever `RestApiDefaults.max_limit` said,
|
|
958
1018
|
while the router clamped `?limit=` to `max_limit`. The schema now publishes
|
|
@@ -316,6 +316,32 @@ def generic_type_arg(annotation: Any, origin: Any) -> type | None:
|
|
|
316
316
|
return args[0]
|
|
317
317
|
|
|
318
318
|
|
|
319
|
+
_NON_SCALAR_COLUMN_TYPES = frozenset(
|
|
320
|
+
{"JSON", "Postgres.JSONB", "Postgres.ARRAY", "Postgres.TSVECTOR"}
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def scalar_column_annotations(model: type) -> dict[str, Any]:
|
|
325
|
+
"""Return the annotation of each scalar column of *model*, ``Annotated`` metadata removed.
|
|
326
|
+
|
|
327
|
+
A JSON, array or text-search column is not scalar; lists, dicts and
|
|
328
|
+
structs, and an ``Enum`` or ``Literal`` declared without a column type,
|
|
329
|
+
are inferred as JSON.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
model: Model whose columns are read.
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
Mapping of column name to its annotation, in declaration order.
|
|
336
|
+
"""
|
|
337
|
+
hints = get_type_hints(model)
|
|
338
|
+
return {
|
|
339
|
+
name: hints[name]
|
|
340
|
+
for name, info in get_column_fields(model).items()
|
|
341
|
+
if info.column_type.type_name not in _NON_SCALAR_COLUMN_TYPES
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
|
|
319
345
|
def _extract_origin_type(annotation: Any) -> type[Any]:
|
|
320
346
|
"""Return the base type from ``Annotated[T, ...]``."""
|
|
321
347
|
origin = getattr(annotation, "__origin__", None)
|
|
@@ -3,10 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from abc import abstractmethod
|
|
4
4
|
from collections.abc import Sequence
|
|
5
5
|
from contextlib import AbstractAsyncContextManager
|
|
6
|
-
from datetime import date, datetime, time
|
|
7
|
-
from decimal import Decimal
|
|
8
6
|
from typing import Any, ClassVar, Generic, cast
|
|
9
|
-
from uuid import UUID
|
|
10
7
|
|
|
11
8
|
import msgspec
|
|
12
9
|
from sqlalchemy import and_, exists, func, insert, inspect, select, tuple_
|
|
@@ -36,11 +33,9 @@ from loom.core.repository.mutation import MutationEvent
|
|
|
36
33
|
from loom.core.repository.sqlalchemy.integrity import handle_integrity_errors
|
|
37
34
|
from loom.core.repository.sqlalchemy.query_compiler.compiler import QuerySpecCompiler
|
|
38
35
|
from loom.core.repository.sqlalchemy.transactional import record_mutation
|
|
36
|
+
from loom.core.repository.sqlalchemy.values import is_json_column, to_column_value
|
|
39
37
|
|
|
40
38
|
_SENTINEL = object()
|
|
41
|
-
# Values SQLAlchemy binds natively; encoding them to strings breaks typed columns.
|
|
42
|
-
_NATIVE_COLUMN_TYPES = (bytes, datetime, date, time, Decimal, UUID)
|
|
43
|
-
_JSON_TYPE_NAMES = frozenset({"JSON", "Postgres.JSONB"})
|
|
44
39
|
_TOTAL_COUNT_ALIAS = "__loom_total_count"
|
|
45
40
|
|
|
46
41
|
|
|
@@ -77,9 +72,7 @@ class SQLAlchemyContextMixin(Generic[OutputT, IdT]):
|
|
|
77
72
|
column_field_names = frozenset(column_fields.keys())
|
|
78
73
|
self._column_field_names = column_field_names
|
|
79
74
|
self._json_column_names = frozenset(
|
|
80
|
-
name
|
|
81
|
-
for name, info in column_fields.items()
|
|
82
|
-
if info.column_type.type_name in _JSON_TYPE_NAMES
|
|
75
|
+
name for name in column_fields if is_json_column(getattr(sa, name, None))
|
|
83
76
|
)
|
|
84
77
|
self._relations_cache = get_relations(self.model)
|
|
85
78
|
self._core_model = get_compiled_core(self.model)
|
|
@@ -165,7 +158,7 @@ class SQLAlchemyContextMixin(Generic[OutputT, IdT]):
|
|
|
165
158
|
|
|
166
159
|
def _serialize_input(self, data: msgspec.Struct | dict[str, Any]) -> dict[str, Any]:
|
|
167
160
|
if isinstance(data, msgspec.Struct):
|
|
168
|
-
builtins =
|
|
161
|
+
builtins = to_column_value(data)
|
|
169
162
|
if not isinstance(builtins, dict):
|
|
170
163
|
raise TypeError("Struct payload must serialize to dict")
|
|
171
164
|
return self._encode_json_columns(_to_internal_field_names(type(data), builtins))
|
|
@@ -174,7 +167,7 @@ class SQLAlchemyContextMixin(Generic[OutputT, IdT]):
|
|
|
174
167
|
def _encode_json_columns(self, values: dict[str, Any]) -> dict[str, Any]:
|
|
175
168
|
"""Reduce JSON-column payloads to JSON-serialisable builtins."""
|
|
176
169
|
for key in self._json_column_names.intersection(values):
|
|
177
|
-
values[key] =
|
|
170
|
+
values[key] = to_column_value(values[key], json=True)
|
|
178
171
|
return values
|
|
179
172
|
|
|
180
173
|
def _column_for_field(self, field: str) -> Any:
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from collections.abc import Callable
|
|
5
|
+
from collections.abc import Callable, Iterable
|
|
6
6
|
from typing import Any
|
|
7
7
|
|
|
8
8
|
from sqlalchemy import and_, or_
|
|
9
|
+
from sqlalchemy.sql.expression import ClauseElement
|
|
9
10
|
|
|
10
11
|
from loom.core.repository.abc.query import FilterGroup, FilterOp, FilterSpec
|
|
11
12
|
from loom.core.repository.sqlalchemy.query_compiler.errors import UnsafeFilterError
|
|
@@ -14,6 +15,7 @@ from loom.core.repository.sqlalchemy.query_compiler.subquery import (
|
|
|
14
15
|
compile_exists,
|
|
15
16
|
compile_not_exists,
|
|
16
17
|
)
|
|
18
|
+
from loom.core.repository.sqlalchemy.values import is_json_column, to_column_value
|
|
17
19
|
|
|
18
20
|
_RELATION_OPS = frozenset([FilterOp.EXISTS, FilterOp.NOT_EXISTS])
|
|
19
21
|
_SIMPLE_OPS: dict[FilterOp, Callable[[Any, Any], Any]] = {
|
|
@@ -74,7 +76,19 @@ def _compile_spec(
|
|
|
74
76
|
|
|
75
77
|
|
|
76
78
|
def _apply_op(col: Any, op: FilterOp, value: Any) -> Any:
|
|
79
|
+
"""Apply *op*, converting *value* as the repository converts a value it writes.
|
|
80
|
+
|
|
81
|
+
A SQLAlchemy expression, and an ``IN`` value that is a string or not
|
|
82
|
+
iterable, reach SQLAlchemy as they are.
|
|
83
|
+
"""
|
|
77
84
|
handler = _SIMPLE_OPS.get(op)
|
|
78
|
-
if handler is
|
|
85
|
+
if handler is None:
|
|
86
|
+
raise ValueError(f"Unsupported FilterOp: {op!r}")
|
|
87
|
+
if isinstance(value, ClauseElement):
|
|
88
|
+
return handler(col, value)
|
|
89
|
+
json = is_json_column(col)
|
|
90
|
+
if op is not FilterOp.IN:
|
|
91
|
+
return handler(col, to_column_value(value, json=json))
|
|
92
|
+
if isinstance(value, str | bytes) or not isinstance(value, Iterable):
|
|
79
93
|
return handler(col, value)
|
|
80
|
-
|
|
94
|
+
return handler(col, [to_column_value(item, json=json) for item in value])
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Column form of model values in SQLAlchemy rows.
|
|
2
|
+
|
|
3
|
+
SQLAlchemy binds ``bytes``, ``datetime``, ``date``, ``time``, ``Decimal`` and
|
|
4
|
+
``UUID`` natively; every other value is reduced to msgspec builtins (an
|
|
5
|
+
``Enum`` to its value, a struct to a dict). A JSON column holds builtins only,
|
|
6
|
+
so its values are reduced completely.
|
|
7
|
+
|
|
8
|
+
:func:`to_column_value` is the conversion the repository applies to a value it
|
|
9
|
+
writes and the query compiler to a filter value, so a filter compares against
|
|
10
|
+
exactly what the row holds.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from datetime import date, datetime, time
|
|
16
|
+
from decimal import Decimal
|
|
17
|
+
from typing import Any
|
|
18
|
+
from uuid import UUID
|
|
19
|
+
|
|
20
|
+
import msgspec
|
|
21
|
+
from sqlalchemy import JSON
|
|
22
|
+
|
|
23
|
+
# Values SQLAlchemy binds natively; encoding them to strings breaks typed columns.
|
|
24
|
+
_NATIVE_COLUMN_TYPES = (bytes, datetime, date, time, Decimal, UUID)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def to_column_value(value: object, *, json: bool = False) -> Any:
|
|
28
|
+
"""Return the form ``value`` takes in a column.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
value: A model value or a filter value.
|
|
32
|
+
json: ``True`` when the column is a JSON column.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
``value`` reduced to msgspec builtins, keeping the natively bound
|
|
36
|
+
types unless the column is a JSON column.
|
|
37
|
+
"""
|
|
38
|
+
if json:
|
|
39
|
+
return msgspec.to_builtins(value)
|
|
40
|
+
return msgspec.to_builtins(value, builtin_types=_NATIVE_COLUMN_TYPES)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def is_json_column(column: object) -> bool:
|
|
44
|
+
"""Whether *column*, a SQLAlchemy column or mapped attribute, holds JSON.
|
|
45
|
+
|
|
46
|
+
``JSON`` and the dialect types derived from it (Postgres ``JSONB``) count.
|
|
47
|
+
"""
|
|
48
|
+
return isinstance(getattr(column, "type", None), JSON)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
__all__ = ["is_json_column", "to_column_value"]
|
|
@@ -19,6 +19,7 @@ from loom.rest.config import RestInterfaceConfigError
|
|
|
19
19
|
from loom.rest.errors import HttpErrorMapper
|
|
20
20
|
from loom.rest.middleware import TraceIdMiddleware
|
|
21
21
|
from loom.rest.model import (
|
|
22
|
+
ALL,
|
|
22
23
|
PaginationMode,
|
|
23
24
|
RestApiDefaults,
|
|
24
25
|
RestInterface,
|
|
@@ -27,6 +28,7 @@ from loom.rest.model import (
|
|
|
27
28
|
from loom.rest.rest_adapter import LoomRestAdapter
|
|
28
29
|
|
|
29
30
|
__all__ = [
|
|
31
|
+
"ALL",
|
|
30
32
|
"CompiledRoute",
|
|
31
33
|
"HttpErrorMapper",
|
|
32
34
|
"InterfaceCompilationError",
|
|
@@ -21,6 +21,10 @@ Compilation steps per interface:
|
|
|
21
21
|
- Read the fields of a ``Query()`` parameter, refusing a non-scalar field,
|
|
22
22
|
a name shared with a path parameter or ``profile``, or a ``QuerySpec``
|
|
23
23
|
parameter next to it.
|
|
24
|
+
- Resolve the filterable and sortable columns of a ``QuerySpec`` route
|
|
25
|
+
(route → interface) against its use case's model, refusing a field
|
|
26
|
+
reference rooted elsewhere, a name that is not a scalar column of that
|
|
27
|
+
model, and a route-level declaration on a route without a ``QuerySpec``.
|
|
24
28
|
- Refuse ``expose_profile`` without ``allowed_profiles``.
|
|
25
29
|
"""
|
|
26
30
|
|
|
@@ -28,6 +32,7 @@ from __future__ import annotations
|
|
|
28
32
|
|
|
29
33
|
import functools
|
|
30
34
|
import inspect
|
|
35
|
+
import logging
|
|
31
36
|
import operator
|
|
32
37
|
import types
|
|
33
38
|
import typing
|
|
@@ -40,12 +45,23 @@ from typing import Any, NamedTuple
|
|
|
40
45
|
from loom.core.engine.compiler import UseCaseCompiler
|
|
41
46
|
from loom.core.engine.metrics import MetricsAdapter
|
|
42
47
|
from loom.core.engine.plan import ExecutionPlan
|
|
43
|
-
from loom.core.model import loom_type
|
|
48
|
+
from loom.core.model import UnsupportedBoundaryType, get_column_fields, loom_type, msgspec_type
|
|
44
49
|
from loom.core.model._json_schema import DEFS, DEFS_PREFIX, REF, definition, without_null
|
|
50
|
+
from loom.core.model.introspection import scalar_column_annotations
|
|
45
51
|
from loom.core.repository.abc.query import QuerySpec
|
|
52
|
+
from loom.core.use_case.field_ref import FieldRef
|
|
46
53
|
from loom.core.use_case.outcome import Created
|
|
47
54
|
from loom.rest.constants import QueryParam
|
|
48
|
-
from loom.rest.model import
|
|
55
|
+
from loom.rest.model import (
|
|
56
|
+
ALL,
|
|
57
|
+
DeclaredFields,
|
|
58
|
+
PaginationMode,
|
|
59
|
+
RestApiDefaults,
|
|
60
|
+
RestInterface,
|
|
61
|
+
RestRoute,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
_logger = logging.getLogger(__name__)
|
|
49
65
|
|
|
50
66
|
|
|
51
67
|
class _RouteOrigin(Enum):
|
|
@@ -333,6 +349,11 @@ class CompiledRoute:
|
|
|
333
349
|
parameter of this route.
|
|
334
350
|
query_fields: Parameters the route's ``Query()`` declares; empty
|
|
335
351
|
when the use case declares none.
|
|
352
|
+
filter_fields: ``(column, annotation)`` of each column a client may
|
|
353
|
+
filter the route's ``QuerySpec`` on, the annotation without its
|
|
354
|
+
``Annotated`` metadata; empty when the route filters nothing.
|
|
355
|
+
sort_fields: Columns a client may sort the route's ``QuerySpec`` by:
|
|
356
|
+
the declared ``sortable`` ones and the primary key.
|
|
336
357
|
result_type: Result type of ``execute`` without its ``Created``
|
|
337
358
|
member, answered with the route's ``status_code``.
|
|
338
359
|
created_type: Type a ``Created`` result wraps, answered with ``201``;
|
|
@@ -356,10 +377,109 @@ class CompiledRoute:
|
|
|
356
377
|
effective_requires_roles: tuple[str, ...] = ()
|
|
357
378
|
effective_max_limit: int = 1000
|
|
358
379
|
query_fields: tuple[QueryField, ...] = ()
|
|
380
|
+
filter_fields: tuple[tuple[str, Any], ...] = ()
|
|
381
|
+
sort_fields: tuple[str, ...] = ()
|
|
359
382
|
result_type: Any = Any
|
|
360
383
|
created_type: Any = None
|
|
361
384
|
|
|
362
385
|
|
|
386
|
+
@dataclass(frozen=True)
|
|
387
|
+
class _ColumnPolicy:
|
|
388
|
+
"""Resolves the columns a route lets a client filter or sort on (route → interface).
|
|
389
|
+
|
|
390
|
+
Args:
|
|
391
|
+
where: Route label used in compilation errors and warnings.
|
|
392
|
+
model: The use case's model, ``None`` when it declares none.
|
|
393
|
+
takes_query_spec: Whether the use case takes a ``QuerySpec``.
|
|
394
|
+
"""
|
|
395
|
+
|
|
396
|
+
where: str
|
|
397
|
+
model: type[Any] | None
|
|
398
|
+
takes_query_spec: bool
|
|
399
|
+
|
|
400
|
+
def resolve(
|
|
401
|
+
self, kind: str, on_route: DeclaredFields | None, on_interface: DeclaredFields | None
|
|
402
|
+
) -> dict[str, Any]:
|
|
403
|
+
"""Return ``{column: annotation}`` for the declared *kind* (``filterable``/``sortable``).
|
|
404
|
+
|
|
405
|
+
A declaration inherited by a route without a ``QuerySpec`` is ignored.
|
|
406
|
+
|
|
407
|
+
Raises:
|
|
408
|
+
InterfaceCompilationError: The route itself declares *kind* but
|
|
409
|
+
takes no ``QuerySpec``, the use case declares no model, or an
|
|
410
|
+
entry is not a scalar column of the route's model.
|
|
411
|
+
"""
|
|
412
|
+
if on_route is not None and not self.takes_query_spec:
|
|
413
|
+
raise InterfaceCompilationError(
|
|
414
|
+
f"{self.where} declares {kind} fields, but its use case takes no QuerySpec."
|
|
415
|
+
)
|
|
416
|
+
declared = on_route if on_route is not None else on_interface
|
|
417
|
+
if not declared or not self.takes_query_spec:
|
|
418
|
+
return {}
|
|
419
|
+
if self.model is None:
|
|
420
|
+
source = "declares" if on_route is not None else "inherits"
|
|
421
|
+
raise InterfaceCompilationError(
|
|
422
|
+
f"{self.where} {source} {kind} fields, but its use case declares no model; "
|
|
423
|
+
"declare it as UseCase[Model, ...]."
|
|
424
|
+
)
|
|
425
|
+
columns = scalar_column_annotations(self.model)
|
|
426
|
+
if declared is ALL:
|
|
427
|
+
_logger.warning(
|
|
428
|
+
"%s makes every scalar column of %s %s (ALL); declare the columns instead.",
|
|
429
|
+
self.where,
|
|
430
|
+
self.model.__name__,
|
|
431
|
+
kind,
|
|
432
|
+
)
|
|
433
|
+
return columns
|
|
434
|
+
resolved: dict[str, Any] = {}
|
|
435
|
+
for entry in declared:
|
|
436
|
+
name = self._column_name(kind, entry)
|
|
437
|
+
if name not in columns:
|
|
438
|
+
raise InterfaceCompilationError(
|
|
439
|
+
f"{self.where}: {kind} field {name!r} is not a scalar column of "
|
|
440
|
+
f"{self.model.__name__}."
|
|
441
|
+
)
|
|
442
|
+
resolved[name] = columns[name]
|
|
443
|
+
return resolved
|
|
444
|
+
|
|
445
|
+
def filter_fields(
|
|
446
|
+
self, on_route: DeclaredFields | None, on_interface: DeclaredFields | None
|
|
447
|
+
) -> tuple[tuple[str, Any], ...]:
|
|
448
|
+
"""Resolve ``filterable``, refusing a column whose type a query value cannot decode.
|
|
449
|
+
|
|
450
|
+
Raises:
|
|
451
|
+
InterfaceCompilationError: As :meth:`resolve`, or msgspec cannot
|
|
452
|
+
describe a declared column's type.
|
|
453
|
+
"""
|
|
454
|
+
columns = self.resolve("filterable", on_route, on_interface)
|
|
455
|
+
for name, annotation in columns.items():
|
|
456
|
+
try:
|
|
457
|
+
msgspec_type(annotation).schema()
|
|
458
|
+
except (TypeError, UnsupportedBoundaryType) as exc:
|
|
459
|
+
raise InterfaceCompilationError(
|
|
460
|
+
f"{self.where}: filterable field {name!r} has a type a query value "
|
|
461
|
+
f"cannot be decoded into: {exc}"
|
|
462
|
+
) from exc
|
|
463
|
+
return tuple(columns.items())
|
|
464
|
+
|
|
465
|
+
def default_order(self) -> tuple[str, ...]:
|
|
466
|
+
"""Primary-key columns, the order the route applies when the client names none."""
|
|
467
|
+
if self.model is None or not self.takes_query_spec:
|
|
468
|
+
return ()
|
|
469
|
+
fields = get_column_fields(self.model)
|
|
470
|
+
return tuple(name for name, info in fields.items() if info.field.primary_key)
|
|
471
|
+
|
|
472
|
+
def _column_name(self, kind: str, entry: FieldRef | str) -> str:
|
|
473
|
+
if not isinstance(entry, FieldRef):
|
|
474
|
+
return entry
|
|
475
|
+
if entry.root is not self.model:
|
|
476
|
+
raise InterfaceCompilationError(
|
|
477
|
+
f"{self.where}: {kind} field {'.'.join(entry.path)!r} is rooted at "
|
|
478
|
+
f"{entry.root!r}, not at the route's model."
|
|
479
|
+
)
|
|
480
|
+
return ".".join(entry.path)
|
|
481
|
+
|
|
482
|
+
|
|
363
483
|
class RestInterfaceCompiler:
|
|
364
484
|
"""Compiles RestInterface declarations into CompiledRoute records.
|
|
365
485
|
|
|
@@ -509,6 +629,13 @@ class RestInterfaceCompiler:
|
|
|
509
629
|
seen[key] = route
|
|
510
630
|
|
|
511
631
|
full_path = f"{prefix}{route.path}" if route.path else prefix or "/"
|
|
632
|
+
where = f"{iface_name}: route ({route.method.upper()}, {route.path!r})"
|
|
633
|
+
takes_query_spec = any(names_query_spec(pb.annotation) for pb in plan.param_bindings)
|
|
634
|
+
columns = _ColumnPolicy(
|
|
635
|
+
where=where,
|
|
636
|
+
model=route.use_case.describe_main_repo()[0],
|
|
637
|
+
takes_query_spec=takes_query_spec,
|
|
638
|
+
)
|
|
512
639
|
|
|
513
640
|
compiled.append(
|
|
514
641
|
CompiledRoute(
|
|
@@ -527,7 +654,16 @@ class RestInterfaceCompiler:
|
|
|
527
654
|
execute_param_types=self._resolve_execute_param_types(route.use_case),
|
|
528
655
|
effective_requires_roles=self._resolve_requires_roles(route, interface),
|
|
529
656
|
effective_max_limit=self._defaults.max_limit,
|
|
530
|
-
query_fields=self._resolve_query_fields(
|
|
657
|
+
query_fields=self._resolve_query_fields(where, takes_query_spec, route, plan),
|
|
658
|
+
filter_fields=columns.filter_fields(route.filterable, interface.filterable),
|
|
659
|
+
sort_fields=tuple(
|
|
660
|
+
dict.fromkeys(
|
|
661
|
+
(
|
|
662
|
+
*columns.resolve("sortable", route.sortable, interface.sortable),
|
|
663
|
+
*columns.default_order(),
|
|
664
|
+
)
|
|
665
|
+
)
|
|
666
|
+
),
|
|
531
667
|
result_type=result_type,
|
|
532
668
|
created_type=created_type,
|
|
533
669
|
)
|
|
@@ -583,13 +719,12 @@ class RestInterfaceCompiler:
|
|
|
583
719
|
|
|
584
720
|
@staticmethod
|
|
585
721
|
def _resolve_query_fields(
|
|
586
|
-
|
|
722
|
+
where: str, takes_query_spec: bool, route: RestRoute, plan: ExecutionPlan
|
|
587
723
|
) -> tuple[QueryField, ...]:
|
|
588
724
|
binding = plan.query_binding
|
|
589
725
|
if binding is None:
|
|
590
726
|
return ()
|
|
591
|
-
|
|
592
|
-
if any(names_query_spec(pb.annotation) for pb in plan.param_bindings):
|
|
727
|
+
if takes_query_spec:
|
|
593
728
|
raise InterfaceCompilationError(
|
|
594
729
|
f"{where}: Query() cannot be combined with a QuerySpec parameter."
|
|
595
730
|
)
|
|
@@ -29,7 +29,7 @@ from __future__ import annotations
|
|
|
29
29
|
|
|
30
30
|
import types
|
|
31
31
|
from collections.abc import Mapping, Sequence
|
|
32
|
-
from typing import Any
|
|
32
|
+
from typing import Any, Literal
|
|
33
33
|
|
|
34
34
|
import msgspec
|
|
35
35
|
|
|
@@ -38,7 +38,7 @@ from loom.core.repository.abc.query import PaginationMode
|
|
|
38
38
|
from loom.core.symbols import import_symbol
|
|
39
39
|
from loom.core.use_case.constants import CrudOp
|
|
40
40
|
from loom.core.use_case.use_case import UseCase
|
|
41
|
-
from loom.rest.model import RestInterface, RestRoute
|
|
41
|
+
from loom.rest.model import ALL, DeclaredFields, RestInterface, RestRoute
|
|
42
42
|
|
|
43
43
|
__all__ = [
|
|
44
44
|
"DisableRouteConfig",
|
|
@@ -89,6 +89,9 @@ class RestRouteConfig(msgspec.Struct, kw_only=True, forbid_unknown_fields=True):
|
|
|
89
89
|
allowed_profiles: Profiles callers may request.
|
|
90
90
|
expose_profile: Whether ``?profile=`` is publicly accepted.
|
|
91
91
|
requires_roles: Roles that grant access to this route.
|
|
92
|
+
filterable: Columns callers may filter on, or ``all`` for
|
|
93
|
+
:data:`~loom.rest.model.ALL`.
|
|
94
|
+
sortable: Columns callers may sort by, or ``all``.
|
|
92
95
|
"""
|
|
93
96
|
|
|
94
97
|
use_case: str
|
|
@@ -103,6 +106,8 @@ class RestRouteConfig(msgspec.Struct, kw_only=True, forbid_unknown_fields=True):
|
|
|
103
106
|
allowed_profiles: tuple[str, ...] = ()
|
|
104
107
|
expose_profile: bool = False
|
|
105
108
|
requires_roles: tuple[str, ...] = ()
|
|
109
|
+
filterable: tuple[str, ...] | Literal["all"] | None = None
|
|
110
|
+
sortable: tuple[str, ...] | Literal["all"] | None = None
|
|
106
111
|
|
|
107
112
|
|
|
108
113
|
class RestInterfaceConfig(msgspec.Struct, kw_only=True, forbid_unknown_fields=True):
|
|
@@ -134,6 +139,9 @@ class RestInterfaceConfig(msgspec.Struct, kw_only=True, forbid_unknown_fields=Tr
|
|
|
134
139
|
allowed_profiles: Profiles available to callers of this interface.
|
|
135
140
|
expose_profile: Whether ``?profile=`` is publicly accepted by default.
|
|
136
141
|
requires_roles: Roles granting access to every route of this interface.
|
|
142
|
+
filterable: Columns callers may filter the interface's routes on, or
|
|
143
|
+
``all`` for :data:`~loom.rest.model.ALL`.
|
|
144
|
+
sortable: Columns callers may sort the interface's routes by, or ``all``.
|
|
137
145
|
"""
|
|
138
146
|
|
|
139
147
|
prefix: str = ""
|
|
@@ -148,6 +156,8 @@ class RestInterfaceConfig(msgspec.Struct, kw_only=True, forbid_unknown_fields=Tr
|
|
|
148
156
|
allowed_profiles: tuple[str, ...] = ()
|
|
149
157
|
expose_profile: bool = False
|
|
150
158
|
requires_roles: tuple[str, ...] = ()
|
|
159
|
+
filterable: tuple[str, ...] | Literal["all"] | None = None
|
|
160
|
+
sortable: tuple[str, ...] | Literal["all"] | None = None
|
|
151
161
|
|
|
152
162
|
|
|
153
163
|
class DisableRouteConfig(msgspec.Struct, kw_only=True, forbid_unknown_fields=True):
|
|
@@ -214,9 +224,16 @@ def _build_route(interface_name: str, route_cfg: RestRouteConfig) -> RestRoute:
|
|
|
214
224
|
allowed_profiles=route_cfg.allowed_profiles,
|
|
215
225
|
expose_profile=route_cfg.expose_profile,
|
|
216
226
|
requires_roles=route_cfg.requires_roles,
|
|
227
|
+
filterable=_declared_fields(route_cfg.filterable),
|
|
228
|
+
sortable=_declared_fields(route_cfg.sortable),
|
|
217
229
|
)
|
|
218
230
|
|
|
219
231
|
|
|
232
|
+
def _declared_fields(value: tuple[str, ...] | Literal["all"] | None) -> DeclaredFields | None:
|
|
233
|
+
"""Map the YAML ``all`` spelling to :data:`~loom.rest.model.ALL`."""
|
|
234
|
+
return ALL if isinstance(value, str) else value
|
|
235
|
+
|
|
236
|
+
|
|
220
237
|
def _class_name(interface_name: str) -> str:
|
|
221
238
|
"""Build a readable class name from *interface_name*, always distinct."""
|
|
222
239
|
# Embeds the config key verbatim instead of sanitising it into an
|
|
@@ -308,6 +325,8 @@ def _build_interface_class(
|
|
|
308
325
|
"allowed_profiles": cfg.allowed_profiles,
|
|
309
326
|
"expose_profile": cfg.expose_profile,
|
|
310
327
|
"requires_roles": cfg.requires_roles,
|
|
328
|
+
"filterable": _declared_fields(cfg.filterable),
|
|
329
|
+
"sortable": _declared_fields(cfg.sortable),
|
|
311
330
|
# types.new_class defaults __module__ to this function's caller frame
|
|
312
331
|
# (typically "types" itself, via __set_name__ machinery), which would
|
|
313
332
|
# make every traceback, repr, and log line naming this class point at
|