loom-kernel 2.12.0__tar.gz → 2.14.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.12.0 → loom_kernel-2.14.0}/CHANGELOG.md +90 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/PKG-INFO +1 -1
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/bootstrap.py +35 -5
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/backend/scoped_ddl.py +57 -1
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/backend/sqlalchemy.py +191 -24
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/bootstrap/bootstrap.py +3 -1
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/gateway.py +51 -24
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/errors/codes.py +1 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/locator.py +15 -3
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/__init__.py +14 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/convert.py +12 -1
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/introspection.py +159 -4
- loom_kernel-2.14.0/src/loom/core/model/partition.py +114 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/scoped.py +21 -1
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/types.py +1 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/types_postgres.py +1 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/backend.py +17 -6
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/migrations/hook.py +19 -5
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/migrations/operations.py +182 -4
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/migrations/runners.py +22 -5
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/mixins.py +1 -1
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/__init__.py +6 -0
- loom_kernel-2.14.0/src/loom/core/repository/sqlalchemy/rls/guard/0002.sql +68 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/guard_manifest.py +16 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/integrity.py +25 -7
- loom_kernel-2.14.0/src/loom/core/repository/sqlalchemy/rls/partitions.py +196 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/verify.py +24 -5
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/schema_names.py +23 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/auth/__init__.py +2 -1
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/auth/abc.py +39 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/auth/middleware.py +46 -7
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/errors.py +22 -16
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/_errors.py +1 -1
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/auto.py +26 -1
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/.gitignore +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/LICENSE +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/README.md +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/pyproject.toml +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_concurrency.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_filters.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_roles.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_startup.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_transport.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/_usecase.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/_binding.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/_handlers.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/_rpc.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/card.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/events.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/a2a/server.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/abc.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/_compiler.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/_plan.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_capabilities.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_conversation.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_feedable.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_hook.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_instructions.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_limits.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_model_role.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_output.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/compiler/phases/_state.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/declarative/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/declarative/_envelope.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/declarative/_schema.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/declarative/_v1.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/declarative/schemas/agent-spec-v1.schema.json +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/describe.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_a2a.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_capabilities.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_engine.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_escape.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_events.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_guards.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_history.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_instructions.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_limits.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_mcp.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_models.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_native.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_output.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_returns.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_schemas.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/_spec.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/extras/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/extras/a2a.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/extras/handlebars.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/extras/mcp.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/extras/skills.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/provider.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/_shared.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/anthropic.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/bedrock.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/gateway.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/openai.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/engines/pydantic_ai/providers/typesafe.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/fastapi/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/fastapi/endpoints.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/fastapi/response.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/fastapi/streaming.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/inference.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/remote_auth.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_bounded.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_chain.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_conversation.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_grants.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_handle.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_health.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_hooks.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_lifecycle.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_limits.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/runtime/_mcp.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/validate/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/ai/validate/__main__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/auto.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/constants.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/runner.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/celery/service.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/cli/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/cli/app.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/cli/schema.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/async_bridge.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/_decide.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/_grants.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/_roles.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/_scope.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/elevation.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/authz/product.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/backend/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/backend/core_model.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/backend/protocol.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/bootstrap/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/bootstrap/kernel.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/_batching.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/_single_flight.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/abc/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/abc/backend.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/abc/config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/abc/dependency.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/calls.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/codec.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/decorators.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/dependency.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/keys.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/memory.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/repository.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/result_codec.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/serializer.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/cache/wiring.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/command/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/command/adapter.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/command/base.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/command/field.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/command/introspection.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/compiler.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/_boto3.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/_includes.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/_resolver_utils.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/binder.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/configurable.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/context.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/keys.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/loader.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/model.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/observability.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/resolver.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/secrets.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/config/ssm.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/contracts/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/contracts/manifest.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/di/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/di/container.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/di/scope.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/_utils.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/base.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/interfaces.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/manifest.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/discovery/modules.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/compilable.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/compiler.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/events.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/executor.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/metrics.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/plan.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/engine/post_commit.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/errors/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/errors/errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/expr/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/expr/eval.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/expr/nodes.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/expr/refs.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/identity/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/identity/context.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/identity/identity.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/identity/issuer.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/identity/wire.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/introspection/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/introspection/base.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/introspection/describe.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/callback.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/context.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/handle.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/job.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/job/service.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/logger/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/logger/abc.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/logger/config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/logger/registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/logger/structlogger.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/_loom_type.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/base.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/enums.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/field.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/privilege.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/projection.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/relation.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/struct.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/model/timestamped.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/event.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/observer/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/observer/noop.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/observer/otel.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/observer/structlog.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/otel_ids.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/protocol.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/runtime.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/span.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/observability/topology.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/persistence/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/persistence/abc.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/persistence/none.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/persistence/registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/plugins/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/plugins/entrypoints.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/plugins/optional.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/projection/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/projection/loaders.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/projection/runtime.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/cursor.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/query.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/query_compiler.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/repo_for.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/repository.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/abc/session_scope.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/dynamodb/backend.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/dynamodb/repository.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/backend.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/ids.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/query_compiler.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/repository.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/uow.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mongo/values.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/mutation.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/registration.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/migrations/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/migrations/env_template.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/bootstrap.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/elevate.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/guard/0001.sql +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/guard/preflight.sql +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/provider.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/schema.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/rls/sources.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/session_settings.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/response/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/response/base.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/routing/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/routing/ref.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/routing/resolver.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/runner.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/schema/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/schema/schema_mode.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/abc/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/abc/contracts.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/abc/errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/caller_bound.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/roles.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/sql/service.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/symbols.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/tracing/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/tracing/context.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/transaction.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/transport/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/transport/adapter.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/uow/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/uow/abc.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/uow/context.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/_predicates.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/agent_markers.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/compute.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/constants.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/factory.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/field_ref.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/invoker.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/keys.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/markers.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/mcp_markers.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/rule.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/core/use_case/use_case.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_format_registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/_common.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/_log.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_merge.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_path_template.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_predicate.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/_write_policy.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_historify.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_reader.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_schema.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_streaming.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/_writer.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/polars/provider.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_historify.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_reader.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_schema.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/_writer.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/backends/spark/provider.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_options.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_paths.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_scope.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/checkpoint/_store.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_binding.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_compiler.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_plan.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_validators.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_validators_config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/compiler/_validators_step.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/_format.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/_read_options.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/_utils.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/_write_options.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/expr/_params.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_from.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_from_config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/source/_specs.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_client.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_file.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_into.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_table.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/declarative/target/_temp.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/executor/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/executor/_dispatcher.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/executor/_executor.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/_registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_mongo.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/sources/_serialization.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/targets/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/_config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/_observer.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/_records.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/_builder.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/_ops.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/_protocol.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/_runner.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/_step.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_generics.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_params.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_process.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_sql.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_step.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_step_client.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/_providers.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/_wiring.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/config_loader.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/core.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runner/filtering.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runtime/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runtime/_config_values.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/runtime/contracts.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/schema/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/schema/_contract.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/schema/_schema.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/storage/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/storage/_config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/storage/_file_locator.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/storage/_locator.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/storage/routing.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/_result.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/_runners.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/_scenario.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/_stubs.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/etl/testing/spark.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_async.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_ctx.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_flow_yaml.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_meta.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_placeholders.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/_summary.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/deploy/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/deploy/_discovery.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/deploy/_schedule.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/deploy/_yaml_etls.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/deploy/entrypoint.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_assemble.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_backfill.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_backfill_body.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_body.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_common.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_factory.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_hooks.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_maintenance.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_params.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_run_name.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_runtime.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_signature.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/flow/_stages.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/manifest/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/manifest/_model.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/manifest/_s3.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/manifest/_store.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/notify/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/notify/_event.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/notify/_factory.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/notify/_port.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/notify/_slack.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/observer/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/observer/_flow.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/observer/_logging_bridge.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/observer/_manifest.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prefect/observer/_task_run.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/_instruments.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/adapter.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/kafka.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/lifecycle.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/prometheus/middleware.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/py.typed +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/_body.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/adapter.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/auth/config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/auth/jwt.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/autocrud.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/compiler.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/constants.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/cors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/app.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/health.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/openapi.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/response.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/fastapi/sql.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/middleware.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/model.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/rest/rest_adapter.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_batch_spans.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_operators.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/bytewax/runner.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/_bindings.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/_compiler.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/_errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/_plan.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/phases/build_plan.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/compiler/phases/validate.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/_errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/_exceptions.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/_message.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/_tracing.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/core/_typing.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/graph/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/graph/_flow.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_codec.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_errors.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_message.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_record.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/_wire.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/client/_retry.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/mongo/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/mongo/_config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/mongo/_event.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/mongo/_normalize.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_boundary.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_branches.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_decompose.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_fork.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_helpers.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_mongo.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_protocols.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_router.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_shape.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_sink.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_step.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_table/common.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_table/config.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/_with.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/nodes/refs.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/streaming/testing.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/__init__.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/agents.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/golden.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/http_harness.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/in_memory.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/repository_harness.py +0 -0
- {loom_kernel-2.12.0 → loom_kernel-2.14.0}/src/loom/testing/runner.py +0 -0
|
@@ -4,6 +4,61 @@
|
|
|
4
4
|
|
|
5
5
|
### core
|
|
6
6
|
|
|
7
|
+
- **core:** range-partitioned row-scoped tables.
|
|
8
|
+
`__partition_by__ = ("RANGE", "<column>")` on a `RowScoped` model compiles to
|
|
9
|
+
`postgresql_partition_by`; the column must be a `DateTime` column of the
|
|
10
|
+
primary key and every unique key must contain it, LIST and HASH are refused,
|
|
11
|
+
all at compile time. Partitions are created ahead of time by the migrator
|
|
12
|
+
through guard revision 2 (`0002.sql`, new functions `create_range_partition`
|
|
13
|
+
and `detach_partition`, `EXECUTE` for the owner only), which creates,
|
|
14
|
+
registers and protects each partition with its parent's scopes in the
|
|
15
|
+
caller's transaction: `op.ensure_range_partitions(table, start, end,
|
|
16
|
+
interval=...)` in a revision, or
|
|
17
|
+
`loom.core.repository.sqlalchemy.rls.ensure_range_partitions(url_or_connection,
|
|
18
|
+
application, model, start, end, interval=...)` at runtime. Partitions are
|
|
19
|
+
named `<table>_p<YYYYMM>` (`_p<YYYY>`, `_p<YYYYMMDD>` for year and day) with
|
|
20
|
+
midnight-UTC bounds. Retention uses `op.detach_range_partitions(...,
|
|
21
|
+
drop=...)` or `detach_range_partitions(...)`, which unprotects, detaches and
|
|
22
|
+
optionally drops. Dropping a partitioned table in an autogenerated revision
|
|
23
|
+
drops its partitions first (`op.drop_partitions`). `check` and `verify` count
|
|
24
|
+
registered partitions with their parent; `verify` reports
|
|
25
|
+
`partition.registration` for a partition registered unlike its parent.
|
|
26
|
+
Re-apply the bootstrap to install revision 2; partition calls on an older
|
|
27
|
+
guard raise `guard revision pending`. `ScopedTable` gains `partition_by`, and
|
|
28
|
+
`require_guard_revision(_sync)` take an optional `minimum`.
|
|
29
|
+
- **core:** a model declares named checks and partial unique indexes.
|
|
30
|
+
`__checks__ = {rule: sql_expression}` compiles one `CHECK` constraint per
|
|
31
|
+
rule, named by the rule; `__partial_unique__ = {rule: (columns, where)}`
|
|
32
|
+
compiles a unique index `uq_<table>_<rule>` restricted to the rows matching
|
|
33
|
+
`where`, and on a row-scoped table its columns must contain the boundary
|
|
34
|
+
(C5, refused at compile time as the guard refuses it with `LG002`). The
|
|
35
|
+
expression and the predicate are product code with the trust of a
|
|
36
|
+
hand-written Alembic revision and must be static literals with no runtime
|
|
37
|
+
input; loom checks only that each is a non-empty string. The static-SQL lint
|
|
38
|
+
exempts exactly the two calls that compile them and now also watches
|
|
39
|
+
`CheckConstraint`. Alembic's autogenerate does not compare checks or index
|
|
40
|
+
predicates, so adding, changing or removing a check on an existing table,
|
|
41
|
+
or changing a predicate, is a hand-written revision.
|
|
42
|
+
- **core:** `database.schema.naming_convention` hands a SQLAlchemy
|
|
43
|
+
`naming_convention` (`pk`, `fk`, `uq`, `ck`, `ix`) to the application
|
|
44
|
+
metadata of the migration path and to the metadata the REST runtime and the
|
|
45
|
+
Celery worker compile, so all of them name constraints alike; absent,
|
|
46
|
+
nothing changes. Use
|
|
47
|
+
`fk_%(table_name)s_%(column_0_N_name)s`: every composite FK of a scoped
|
|
48
|
+
table starts with the boundary column. Compilation now refuses two
|
|
49
|
+
constraints or indexes of one table resolving to the same name, and a
|
|
50
|
+
check, `__indexes__` or `__partial_unique__` name over Postgres's 63 bytes,
|
|
51
|
+
instead of failing or truncating at DDL time. `reset_registry` takes the
|
|
52
|
+
convention as `naming_convention=`; called without it, it leaves the
|
|
53
|
+
convention as it is, and `None` restores SQLAlchemy's default.
|
|
54
|
+
|
|
55
|
+
- **core:** two column types. `Bytes` (`loom.core.model.Bytes`, also inferred
|
|
56
|
+
from a `bytes` annotation, which used to fall back to `JSON`) compiles to
|
|
57
|
+
`LargeBinary`, `bytea` on Postgres; `Postgres.INET` compiles to Postgres
|
|
58
|
+
`inet`. The SQLAlchemy repository binds `bytes` as they are instead of
|
|
59
|
+
base64 text, and a network address the driver returns for `inet` reaches a
|
|
60
|
+
`str` field as its text form (`10.0.0.1`, `2001:db8::1/64`).
|
|
61
|
+
|
|
7
62
|
- **core:** a memory cache alias can be bounded. `cache: max_size` (entries) and
|
|
8
63
|
the new `cache: max_bytes` (stored payload bytes) serve every
|
|
9
64
|
`aiocache.SimpleMemoryCache` alias through `loom.core.cache.memory.BoundedMemoryCache`,
|
|
@@ -85,12 +140,25 @@
|
|
|
85
140
|
|
|
86
141
|
### rest
|
|
87
142
|
|
|
143
|
+
- **rest:** a single `RuleViolation(field, message)` now answers its `field`.
|
|
144
|
+
`HttpErrorMapper` dropped it, so two `rule_violation` 422s could only be
|
|
145
|
+
told apart by their message text. The body adds `field` (`ErrorField.FIELD`,
|
|
146
|
+
the key each `violations` item of `RuleViolations` already carries) next to
|
|
147
|
+
the unchanged `code`, `message` and `trace_id`; the status stays `422`. This
|
|
148
|
+
includes the SQL endpoint's 422s, whose `field` is `sql` or `body`. Every
|
|
149
|
+
other error body is unchanged.
|
|
88
150
|
- **rest:** a strict `pydantic.BaseModel` result, a `list` of them or an
|
|
89
151
|
envelope holding one now renders directly on a REST route, through
|
|
90
152
|
`MsgspecJSONResponse`'s `enc_hook`, and documents in OpenAPI
|
|
91
153
|
(`_safe_pydantic_schema`) through the same `LoomType` the cache and MCP
|
|
92
154
|
boundaries already use; `LoomRestAdapter`'s Struct projection goes
|
|
93
155
|
through it too.
|
|
156
|
+
- **rest:** `create_app` accepts `modules: Sequence[Callable[[LoomContainer], None]]`,
|
|
157
|
+
mirroring the Celery `create_app`. Each module is called with the container,
|
|
158
|
+
in order, before repositories are registered and before use cases are
|
|
159
|
+
verified, so a use case can inject a port no repository provides (a clock,
|
|
160
|
+
an identity verifier, a bridge to another bounded context). Without the
|
|
161
|
+
module, startup still fails with the same `ResolutionError`.
|
|
94
162
|
|
|
95
163
|
### prefect
|
|
96
164
|
|
|
@@ -231,6 +299,15 @@
|
|
|
231
299
|
|
|
232
300
|
### core
|
|
233
301
|
|
|
302
|
+
- **core:** the RLS guard refuses, in the same statement, a drop outside the
|
|
303
|
+
hatch that breaks its invariants. `DROP POLICY` or `DROP TRIGGER
|
|
304
|
+
loom_deny_owner_dml` on a scoped table used to commit, because drops are not
|
|
305
|
+
reported to `ddl_command_end`; the schema then failed the assertion (`LG002`)
|
|
306
|
+
only at the next DDL. The `sql_drop` trigger now runs the assertion when the
|
|
307
|
+
drop removes an object of the application schema and the hatch is closed;
|
|
308
|
+
dropping a plain index still succeeds. Shipped in guard revision 2
|
|
309
|
+
(`0002.sql`, `CREATE OR REPLACE FUNCTION on_sql_drop`); re-apply the
|
|
310
|
+
bootstrap to install it.
|
|
234
311
|
- **core:** a model with a relation or projection field imports again on
|
|
235
312
|
Python 3.12.4 and later when its module uses
|
|
236
313
|
`from __future__ import annotations`. It failed with
|
|
@@ -293,6 +370,19 @@
|
|
|
293
370
|
capability does not recover yet; see "A session that died after it opened is
|
|
294
371
|
replaced by the next call" in `docs/ai/mcp.md`.
|
|
295
372
|
|
|
373
|
+
### rest
|
|
374
|
+
|
|
375
|
+
- **rest:** an authenticator can report an outage instead of answering `500`.
|
|
376
|
+
An exception raised inside `AuthenticationMiddleware` never reached
|
|
377
|
+
Starlette's exception handlers, so a custom authenticator whose identity
|
|
378
|
+
provider was unreachable answered a bare `500`. An authenticator now raises
|
|
379
|
+
`loom.rest.auth.AuthenticationUnavailable` and the request answers `503`
|
|
380
|
+
with the standard error body (`code: service_unavailable`, a fixed message,
|
|
381
|
+
`trace_id`) and no `WWW-Authenticate` challenge; the exception's message
|
|
382
|
+
and cause are logged at `WARNING`, never sent. `ErrorCode` gains
|
|
383
|
+
`SERVICE_UNAVAILABLE`, which `HttpErrorMapper` maps to `503`. Any other
|
|
384
|
+
exception from the authenticator, and the `401` refusal, are unchanged.
|
|
385
|
+
|
|
296
386
|
## ♻️ Refactor
|
|
297
387
|
|
|
298
388
|
### etl
|
|
@@ -118,6 +118,16 @@ _T = TypeVar("_T")
|
|
|
118
118
|
# ---------------------------------------------------------------------------
|
|
119
119
|
|
|
120
120
|
|
|
121
|
+
class _WorkerSchemaConfig(msgspec.Struct, kw_only=True):
|
|
122
|
+
"""The part of ``database.schema`` the worker compiles models with.
|
|
123
|
+
|
|
124
|
+
Attributes:
|
|
125
|
+
naming_convention: SQLAlchemy naming convention keyed by constraint kind.
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
naming_convention: dict[str, str] | None = None
|
|
129
|
+
|
|
130
|
+
|
|
121
131
|
class _WorkerDbConfig(msgspec.Struct, kw_only=True):
|
|
122
132
|
"""Database settings for the worker process.
|
|
123
133
|
|
|
@@ -125,11 +135,13 @@ class _WorkerDbConfig(msgspec.Struct, kw_only=True):
|
|
|
125
135
|
url: Async SQLAlchemy connection URL.
|
|
126
136
|
echo: Log all SQL statements when ``True``.
|
|
127
137
|
pool_pre_ping: Test connections before checkout.
|
|
138
|
+
schema: Schema settings the models are compiled with.
|
|
128
139
|
"""
|
|
129
140
|
|
|
130
141
|
url: str
|
|
131
142
|
echo: bool = False
|
|
132
143
|
pool_pre_ping: bool = True
|
|
144
|
+
schema: _WorkerSchemaConfig = msgspec.field(default_factory=_WorkerSchemaConfig)
|
|
133
145
|
|
|
134
146
|
|
|
135
147
|
class _DiscoveryModules(msgspec.Struct, kw_only=True):
|
|
@@ -621,16 +633,28 @@ def _register_repositories(
|
|
|
621
633
|
return build_sqlalchemy_repository_registration_module(session_manager, models)
|
|
622
634
|
|
|
623
635
|
|
|
624
|
-
def
|
|
636
|
+
def _worker_naming_convention(ctx: ConfigContext) -> Mapping[str, str] | None:
|
|
637
|
+
"""The ``database.schema.naming_convention`` the REST runtime and migrations also read."""
|
|
638
|
+
db_cfg = ctx.section(ConfigKey.DATABASE, _WorkerDbConfig)
|
|
639
|
+
return db_cfg.schema.naming_convention
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
def _compile_models(
|
|
643
|
+
models: Sequence[type[BaseModel]], *, naming_convention: Mapping[str, str] | None
|
|
644
|
+
) -> tuple[type[BaseModel], ...]:
|
|
625
645
|
"""Compile and normalize discovered models for SQLAlchemy repositories."""
|
|
626
646
|
if not models:
|
|
627
647
|
return ()
|
|
628
648
|
try:
|
|
629
|
-
from loom.core.backend.sqlalchemy import
|
|
649
|
+
from loom.core.backend.sqlalchemy import (
|
|
650
|
+
compile_all,
|
|
651
|
+
configured_naming_convention,
|
|
652
|
+
reset_registry,
|
|
653
|
+
)
|
|
630
654
|
except ImportError as exc:
|
|
631
655
|
raise _sqlalchemy_extra_error() from exc
|
|
632
656
|
ordered = tuple(dict.fromkeys(models))
|
|
633
|
-
reset_registry()
|
|
657
|
+
reset_registry(naming_convention=configured_naming_convention(naming_convention))
|
|
634
658
|
compile_all(*ordered)
|
|
635
659
|
return ordered
|
|
636
660
|
|
|
@@ -656,6 +680,8 @@ def _compile_db_layer(
|
|
|
656
680
|
session_manager: SessionManager | None,
|
|
657
681
|
models: Sequence[type[BaseModel]],
|
|
658
682
|
user_modules: Sequence[Callable[[LoomContainer], None]],
|
|
683
|
+
*,
|
|
684
|
+
naming_convention: Mapping[str, str] | None,
|
|
659
685
|
) -> tuple[tuple[type[BaseModel], ...], tuple[Callable[[LoomContainer], None], ...]]:
|
|
660
686
|
"""Compile models and register repositories; no-op when DB is not configured.
|
|
661
687
|
|
|
@@ -663,6 +689,7 @@ def _compile_db_layer(
|
|
|
663
689
|
session_manager: Active session manager, or ``None`` for pure jobs.
|
|
664
690
|
models: Model classes discovered or declared for this worker.
|
|
665
691
|
user_modules: Container modules provided by the caller.
|
|
692
|
+
naming_convention: The configured ``database.schema.naming_convention``.
|
|
666
693
|
|
|
667
694
|
Returns:
|
|
668
695
|
Tuple of (normalized_models, runtime_modules). When no DB is
|
|
@@ -671,7 +698,7 @@ def _compile_db_layer(
|
|
|
671
698
|
base = tuple(user_modules)
|
|
672
699
|
if session_manager is None:
|
|
673
700
|
return tuple(models), base
|
|
674
|
-
normalized = _compile_models(models)
|
|
701
|
+
normalized = _compile_models(models, naming_convention=naming_convention)
|
|
675
702
|
if not normalized:
|
|
676
703
|
return tuple(models), base
|
|
677
704
|
return normalized, (*base, _register_repositories(session_manager, normalized))
|
|
@@ -904,7 +931,10 @@ def bootstrap_worker(
|
|
|
904
931
|
_apply_job_config_if_present(ctx, job_type)
|
|
905
932
|
|
|
906
933
|
uow_factory, session_manager = _resolve_uow_factory(ctx)
|
|
907
|
-
|
|
934
|
+
convention = _worker_naming_convention(ctx) if session_manager is not None else None
|
|
935
|
+
final_models, runtime_modules = _compile_db_layer(
|
|
936
|
+
session_manager, resolved.models, modules, naming_convention=convention
|
|
937
|
+
)
|
|
908
938
|
runtime_modules = (*runtime_modules, cache_module_for(ctx))
|
|
909
939
|
|
|
910
940
|
resolved = _WorkerResolved(
|
|
@@ -11,13 +11,14 @@ from __future__ import annotations
|
|
|
11
11
|
|
|
12
12
|
import json
|
|
13
13
|
import re
|
|
14
|
-
from collections.abc import Callable, Mapping
|
|
14
|
+
from collections.abc import Callable, Iterable, Iterator, Mapping
|
|
15
15
|
from typing import Any, Final, get_args
|
|
16
16
|
|
|
17
17
|
from sqlalchemy import Connection, Table, event, text
|
|
18
18
|
|
|
19
19
|
from loom.core.config import ConfigError
|
|
20
20
|
from loom.core.model.field import Reach
|
|
21
|
+
from loom.core.model.partition import PartitionRange
|
|
21
22
|
from loom.core.model.privilege import Privilege
|
|
22
23
|
from loom.core.model.scoped import ScopedTable
|
|
23
24
|
from loom.core.schema_names import schema_identifier, sql_identifier
|
|
@@ -42,6 +43,21 @@ GRANT_TABLE: Final = (
|
|
|
42
43
|
"CAST(:readers AS text[]), CAST(:writers AS text[]))"
|
|
43
44
|
)
|
|
44
45
|
ASSERT_SCHEMA: Final = "SELECT assert_scoped_schema()"
|
|
46
|
+
CREATE_RANGE_PARTITION: Final = (
|
|
47
|
+
"SELECT create_range_partition("
|
|
48
|
+
"to_regclass(quote_ident(:schema) || '.' || quote_ident(:table)), "
|
|
49
|
+
"CAST(:partition AS text), CAST(:lower AS text), CAST(:upper AS text))"
|
|
50
|
+
)
|
|
51
|
+
DETACH_PARTITION: Final = (
|
|
52
|
+
"SELECT detach_partition(to_regclass(quote_ident(:schema) || '.' || quote_ident(:table)), "
|
|
53
|
+
"CAST(:partition AS text), CAST(:drop AS boolean))"
|
|
54
|
+
)
|
|
55
|
+
PARTITIONS: Final = (
|
|
56
|
+
"SELECT c.relname FROM pg_inherits i JOIN pg_class c ON c.oid = i.inhrelid "
|
|
57
|
+
"WHERE i.inhparent = to_regclass(quote_ident(:schema) || '.' || quote_ident(:table)) "
|
|
58
|
+
"ORDER BY c.relname"
|
|
59
|
+
)
|
|
60
|
+
LANDING: Final = "SELECT current_user, current_schema()"
|
|
45
61
|
GUARD_FIRST: Final = (
|
|
46
62
|
"SELECT set_config('search_path', quote_ident(:guard) || ', pg_catalog, pg_temp', true)"
|
|
47
63
|
)
|
|
@@ -62,6 +78,7 @@ MISSING_EVENT_TRIGGERS: Final = (
|
|
|
62
78
|
|
|
63
79
|
Parameters = dict[str, Any]
|
|
64
80
|
GuardCall = Callable[[Connection, Parameters], None]
|
|
81
|
+
PartitionCall = tuple[str, Parameters]
|
|
65
82
|
_OPEN_HATCH: Final = text(OPEN_HATCH)
|
|
66
83
|
_PROTECT: Final = text(PROTECT)
|
|
67
84
|
_GRANT_TABLE: Final = text(GRANT_TABLE)
|
|
@@ -108,6 +125,45 @@ def grant_parameters(
|
|
|
108
125
|
}
|
|
109
126
|
|
|
110
127
|
|
|
128
|
+
def create_partition_parameters(schema: str, table: str, partition: PartitionRange) -> Parameters:
|
|
129
|
+
"""Bound parameters of :data:`CREATE_RANGE_PARTITION` for one partition of ``schema.table``."""
|
|
130
|
+
return {
|
|
131
|
+
**table_parameters(schema, table),
|
|
132
|
+
"partition": sql_identifier(partition.name),
|
|
133
|
+
"lower": partition.lower,
|
|
134
|
+
"upper": partition.upper,
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def detach_partition_parameters(
|
|
139
|
+
schema: str, table: str, partition: str, *, drop: bool
|
|
140
|
+
) -> Parameters:
|
|
141
|
+
"""Bound parameters of :data:`DETACH_PARTITION` for one partition of ``schema.table``."""
|
|
142
|
+
return {**table_parameters(schema, table), "partition": sql_identifier(partition), "drop": drop}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def create_partition_calls(
|
|
146
|
+
schema: str, table: str, partitions: Iterable[PartitionRange]
|
|
147
|
+
) -> Iterator[PartitionCall]:
|
|
148
|
+
"""Each partition's name and the parameters of :data:`CREATE_RANGE_PARTITION`, in order.
|
|
149
|
+
|
|
150
|
+
The guard answers each call with whether it created the partition.
|
|
151
|
+
"""
|
|
152
|
+
for partition in partitions:
|
|
153
|
+
yield partition.name, create_partition_parameters(schema, table, partition)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def detach_partition_calls(
|
|
157
|
+
schema: str, table: str, names: Iterable[str], *, drop: bool
|
|
158
|
+
) -> Iterator[PartitionCall]:
|
|
159
|
+
"""Each name and the parameters of :data:`DETACH_PARTITION`, in order.
|
|
160
|
+
|
|
161
|
+
The guard answers each call with whether the partition existed.
|
|
162
|
+
"""
|
|
163
|
+
for name in names:
|
|
164
|
+
yield name, detach_partition_parameters(schema, table, name, drop=drop)
|
|
165
|
+
|
|
166
|
+
|
|
111
167
|
def table_parameters(schema: str, table: str) -> Parameters:
|
|
112
168
|
"""The validated schema and table a guard call resolves inside Postgres."""
|
|
113
169
|
return {"schema": schema_identifier(schema), "table": sql_identifier(table)}
|
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import functools
|
|
4
|
+
from collections import deque
|
|
4
5
|
from collections.abc import Mapping
|
|
5
6
|
from dataclasses import dataclass, field
|
|
6
|
-
from
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from typing import Any, Final
|
|
7
9
|
|
|
8
10
|
import msgspec
|
|
9
11
|
from sqlalchemy import (
|
|
10
12
|
JSON,
|
|
11
13
|
BigInteger,
|
|
12
14
|
Boolean,
|
|
15
|
+
CheckConstraint,
|
|
16
|
+
Constraint,
|
|
13
17
|
DateTime,
|
|
14
18
|
Float,
|
|
15
19
|
ForeignKey,
|
|
16
20
|
ForeignKeyConstraint,
|
|
17
21
|
Index,
|
|
18
22
|
Integer,
|
|
23
|
+
LargeBinary,
|
|
19
24
|
MetaData,
|
|
20
25
|
Numeric,
|
|
21
26
|
String,
|
|
@@ -23,21 +28,30 @@ from sqlalchemy import (
|
|
|
23
28
|
Text,
|
|
24
29
|
UniqueConstraint,
|
|
25
30
|
func,
|
|
31
|
+
text,
|
|
26
32
|
)
|
|
27
33
|
from sqlalchemy.dialects.postgresql import ARRAY as PG_ARRAY
|
|
34
|
+
from sqlalchemy.dialects.postgresql import INET as PG_INET
|
|
28
35
|
from sqlalchemy.dialects.postgresql import JSONB as PG_JSONB
|
|
29
36
|
from sqlalchemy.dialects.postgresql import TSVECTOR as PG_TSVECTOR
|
|
30
37
|
from sqlalchemy.dialects.postgresql import UUID as PG_UUID
|
|
31
38
|
from sqlalchemy.orm import DeclarativeBase, mapped_column, relationship
|
|
32
39
|
from sqlalchemy.orm import registry as sa_registry
|
|
40
|
+
from sqlalchemy.sql.naming import conv
|
|
41
|
+
from sqlalchemy.sql.schema import DEFAULT_NAMING_CONVENTION
|
|
33
42
|
|
|
34
43
|
from loom.core.backend.core_model import CoreModel, CoreProfilePlan, CoreRelationStep
|
|
35
44
|
from loom.core.backend.scoped_ddl import SCHEMA_KEY, register_listeners
|
|
45
|
+
from loom.core.config import ConfigError
|
|
36
46
|
from loom.core.model.enums import Cardinality, OnDelete, ServerDefault, ServerOnUpdate
|
|
37
47
|
from loom.core.model.field import ColumnType, Field
|
|
38
48
|
from loom.core.model.introspection import (
|
|
39
49
|
ColumnFieldInfo,
|
|
50
|
+
PartialUnique,
|
|
51
|
+
declared_checks,
|
|
40
52
|
declared_indexes,
|
|
53
|
+
declared_partial_unique,
|
|
54
|
+
declared_partition,
|
|
41
55
|
declared_privileges,
|
|
42
56
|
declared_unique,
|
|
43
57
|
extract_model_from_hint,
|
|
@@ -53,6 +67,7 @@ from loom.core.model.privilege import READ_WRITE, Privilege
|
|
|
53
67
|
from loom.core.model.relation import Relation
|
|
54
68
|
from loom.core.model.scoped import ScopeColumn, ScopedTable
|
|
55
69
|
from loom.core.projection.runtime import ProjectionStep, build_projection_plan_from_steps
|
|
70
|
+
from loom.core.schema_names import MAX_IDENTIFIER_LENGTH, naming_convention
|
|
56
71
|
|
|
57
72
|
_SA_TYPE_MAP: dict[str, type] = {
|
|
58
73
|
"String": String,
|
|
@@ -62,11 +77,13 @@ _SA_TYPE_MAP: dict[str, type] = {
|
|
|
62
77
|
"Boolean": Boolean,
|
|
63
78
|
"Text": Text,
|
|
64
79
|
"JSON": JSON,
|
|
80
|
+
"Bytes": LargeBinary,
|
|
65
81
|
"DateTime": DateTime,
|
|
66
82
|
"Numeric": Numeric,
|
|
67
83
|
"Postgres.JSONB": PG_JSONB,
|
|
68
84
|
"Postgres.UUID": PG_UUID,
|
|
69
85
|
"Postgres.TSVECTOR": PG_TSVECTOR,
|
|
86
|
+
"Postgres.INET": PG_INET,
|
|
70
87
|
}
|
|
71
88
|
|
|
72
89
|
_SERVER_DEFAULT_MAP = {
|
|
@@ -105,6 +122,16 @@ class _Compilation:
|
|
|
105
122
|
|
|
106
123
|
|
|
107
124
|
_COMPILATION_KEY = "loom.compilation"
|
|
125
|
+
_RULE_KEY = "loom.rule"
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class _Keep(Enum):
|
|
129
|
+
"""The default of :func:`reset_registry`: leave the naming convention as it is."""
|
|
130
|
+
|
|
131
|
+
CONVENTION = "keep"
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
_KEEP_CONVENTION: Final = _Keep.CONVENTION
|
|
108
135
|
|
|
109
136
|
|
|
110
137
|
@functools.cache
|
|
@@ -211,6 +238,7 @@ def _compile_model(
|
|
|
211
238
|
struct_cls, column_fields, boundary, models_by_table, comp
|
|
212
239
|
)
|
|
213
240
|
constraints += _declared_constraints(struct_cls, table_name)
|
|
241
|
+
partition = declared_partition(struct_cls)
|
|
214
242
|
|
|
215
243
|
attrs: dict[str, Any] = {
|
|
216
244
|
"__tablename__": table_name,
|
|
@@ -220,10 +248,15 @@ def _compile_model(
|
|
|
220
248
|
attrs[name] = _build_mapped_column(
|
|
221
249
|
field_info, inline_foreign_key=name not in composite_columns
|
|
222
250
|
)
|
|
223
|
-
|
|
224
|
-
|
|
251
|
+
table_args: list[Any] = list(constraints)
|
|
252
|
+
if partition is not None:
|
|
253
|
+
table_args.append({"postgresql_partition_by": f"RANGE ({partition.column})"})
|
|
254
|
+
if table_args:
|
|
255
|
+
attrs["__table_args__"] = tuple(table_args)
|
|
225
256
|
|
|
226
257
|
sa_cls: Any = type(struct_cls.__name__ + "SA", (comp.base,), attrs)
|
|
258
|
+
_check_declared_name_lengths(struct_cls, constraints)
|
|
259
|
+
_check_distinct_names(struct_cls, sa_cls.__table__)
|
|
227
260
|
comp.compiled[struct_cls] = sa_cls
|
|
228
261
|
comp.tables[table_name] = sa_cls
|
|
229
262
|
comp.pending[struct_cls] = get_relations(struct_cls)
|
|
@@ -235,6 +268,7 @@ def _compile_model(
|
|
|
235
268
|
name=table.name,
|
|
236
269
|
scopes=scopes,
|
|
237
270
|
privileges=frozenset(getattr(struct_cls, "__scope_privileges__", READ_WRITE)),
|
|
271
|
+
partition_by=None if partition is None else partition.column,
|
|
238
272
|
)
|
|
239
273
|
comp.scoped[(table.schema, table.name)] = scoped
|
|
240
274
|
schema = comp.metadata.info.get(SCHEMA_KEY)
|
|
@@ -248,15 +282,109 @@ def _compile_model(
|
|
|
248
282
|
return sa_cls
|
|
249
283
|
|
|
250
284
|
|
|
251
|
-
def _declared_constraints(struct_cls: type, table_name: str) -> list[
|
|
252
|
-
|
|
285
|
+
def _declared_constraints(struct_cls: type, table_name: str) -> list[Constraint | Index]:
|
|
286
|
+
"""Keys, indexes and checks declared on the model, in declaration order.
|
|
287
|
+
|
|
288
|
+
``__unique__`` constraints are unnamed, so the metadata's naming convention
|
|
289
|
+
names them. ``__checks__`` are named by their rule, which a ``ck``
|
|
290
|
+
convention may use as ``%(constraint_name)s``. Indexes carry a name loom
|
|
291
|
+
builds; :class:`~sqlalchemy.sql.naming.conv` marks it final so no convention
|
|
292
|
+
renames it, and :func:`_check_declared_name_lengths` refuses one over
|
|
293
|
+
Postgres's limit.
|
|
294
|
+
|
|
295
|
+
Alembic's autogenerate does not compare CHECK constraints and does not
|
|
296
|
+
compare the ``WHERE`` predicate of an index: adding, changing or removing a
|
|
297
|
+
check on an existing table, and changing a predicate, are written by hand in
|
|
298
|
+
a revision, and ``check`` does not report them as drift.
|
|
299
|
+
"""
|
|
300
|
+
constraints: list[Constraint | Index] = [
|
|
301
|
+
UniqueConstraint(*columns) for columns in declared_unique(struct_cls)
|
|
302
|
+
]
|
|
253
303
|
constraints += [
|
|
254
|
-
Index(
|
|
304
|
+
Index(
|
|
305
|
+
conv(f"ix_{table_name}_{'_'.join(columns)}"),
|
|
306
|
+
*columns,
|
|
307
|
+
info={_RULE_KEY: ("__indexes__", ", ".join(columns))},
|
|
308
|
+
)
|
|
255
309
|
for columns in declared_indexes(struct_cls)
|
|
256
310
|
]
|
|
311
|
+
constraints += [
|
|
312
|
+
_partial_unique_index(table_name, partial)
|
|
313
|
+
for partial in declared_partial_unique(struct_cls)
|
|
314
|
+
]
|
|
315
|
+
constraints += [
|
|
316
|
+
_check_constraint(rule, expression)
|
|
317
|
+
for rule, expression in declared_checks(struct_cls).items()
|
|
318
|
+
]
|
|
257
319
|
return constraints
|
|
258
320
|
|
|
259
321
|
|
|
322
|
+
def _check_distinct_names(struct_cls: type, table: Table) -> None:
|
|
323
|
+
"""Refuse a table where two constraints or indexes resolve to the same name.
|
|
324
|
+
|
|
325
|
+
Postgres would reject the second one at DDL time. Under a naming
|
|
326
|
+
convention the usual cause is ``fk_%(table_name)s_%(column_0_name)s``: every
|
|
327
|
+
composite FK of a scoped table starts with the boundary column.
|
|
328
|
+
"""
|
|
329
|
+
seen: set[str] = set()
|
|
330
|
+
items: list[Constraint | Index] = [*table.constraints, *table.indexes]
|
|
331
|
+
for item in items:
|
|
332
|
+
if item.name is None:
|
|
333
|
+
continue
|
|
334
|
+
name = str(item.name)
|
|
335
|
+
if name in seen:
|
|
336
|
+
raise ValueError(
|
|
337
|
+
f"{struct_cls.__name__}: table {table.name} has two constraints named {name!r}; "
|
|
338
|
+
"name them apart, for FKs with fk_%(table_name)s_%(column_0_N_name)s"
|
|
339
|
+
)
|
|
340
|
+
seen.add(name)
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def _partial_unique_index(table_name: str, partial: PartialUnique) -> Index:
|
|
344
|
+
"""The unique index of one ``__partial_unique__`` rule.
|
|
345
|
+
|
|
346
|
+
``partial.where`` is a DDL fragment the product declared on its model. It
|
|
347
|
+
must be a static literal with no runtime input; loom checks only that it is
|
|
348
|
+
a non-empty string.
|
|
349
|
+
"""
|
|
350
|
+
return Index(
|
|
351
|
+
conv(f"uq_{table_name}_{partial.rule}"),
|
|
352
|
+
*partial.columns,
|
|
353
|
+
unique=True,
|
|
354
|
+
postgresql_where=text(partial.where),
|
|
355
|
+
info={_RULE_KEY: ("__partial_unique__", partial.rule)},
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def _check_constraint(rule: str, expression: str) -> CheckConstraint:
|
|
360
|
+
"""The CHECK constraint of one ``__checks__`` rule.
|
|
361
|
+
|
|
362
|
+
``expression`` is a DDL fragment the product declared on its model. It must
|
|
363
|
+
be a static literal with no runtime input; loom checks only that it is a
|
|
364
|
+
non-empty string.
|
|
365
|
+
"""
|
|
366
|
+
return CheckConstraint(expression, name=rule, info={_RULE_KEY: ("__checks__", rule)})
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def _check_declared_name_lengths(struct_cls: type, constraints: list[Constraint | Index]) -> None:
|
|
370
|
+
"""Refuse a declared check or index whose final name Postgres would truncate.
|
|
371
|
+
|
|
372
|
+
SQLAlchemy would raise only when emitting DDL for a plain name, and would
|
|
373
|
+
shorten a final (``conv``) name with a hash; both are refused here instead.
|
|
374
|
+
"""
|
|
375
|
+
for constraint in constraints:
|
|
376
|
+
declared = constraint.info.get(_RULE_KEY)
|
|
377
|
+
if declared is None:
|
|
378
|
+
continue
|
|
379
|
+
attr, rule = declared
|
|
380
|
+
name = str(constraint.name)
|
|
381
|
+
if len(name.encode()) > MAX_IDENTIFIER_LENGTH:
|
|
382
|
+
raise ValueError(
|
|
383
|
+
f"{struct_cls.__name__}: {attr} rule {rule!r} is named {name!r}, longer than "
|
|
384
|
+
f"the {MAX_IDENTIFIER_LENGTH} bytes Postgres keeps; shorten it"
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
|
|
260
388
|
def _target_model(
|
|
261
389
|
table: str, models_by_table: Mapping[str, type], comp: _Compilation
|
|
262
390
|
) -> type | None:
|
|
@@ -549,29 +677,48 @@ def _topological_sort(
|
|
|
549
677
|
) -> list[type]:
|
|
550
678
|
"""Kahn's algorithm: return *models* with dependency leaves first.
|
|
551
679
|
|
|
552
|
-
|
|
553
|
-
cyclic models are appended in
|
|
554
|
-
|
|
555
|
-
are resolved after all
|
|
680
|
+
Ties are released in the input order of *models*. If a cycle is detected
|
|
681
|
+
(remaining nodes after BFS exhaustion), the cyclic models are appended in
|
|
682
|
+
their input order. Circular references are valid because
|
|
683
|
+
``compile_model`` is idempotent and relationships are resolved after all
|
|
684
|
+
models are registered.
|
|
556
685
|
"""
|
|
557
|
-
|
|
686
|
+
in_degree, dependents = _dependency_graph(models, deps)
|
|
687
|
+
result = _release_in_dependency_order(models, in_degree, dependents)
|
|
688
|
+
processed = set(result)
|
|
689
|
+
result.extend(m for m in models if m not in processed)
|
|
690
|
+
return result
|
|
558
691
|
|
|
559
|
-
model_set = set(models)
|
|
560
692
|
|
|
561
|
-
|
|
693
|
+
def _dependency_graph(
|
|
694
|
+
models: list[type],
|
|
695
|
+
deps: dict[type, frozenset[type]],
|
|
696
|
+
) -> tuple[dict[type, int], dict[type, list[type]]]:
|
|
697
|
+
"""Index the dependency edges that stay within *models*.
|
|
698
|
+
|
|
699
|
+
Returns:
|
|
700
|
+
``in_degree[m]``: how many of ``m``'s deps are in *models*, and
|
|
701
|
+
``dependents[dep]``: the models depending on ``dep``, in input order.
|
|
702
|
+
"""
|
|
703
|
+
model_set = set(models)
|
|
562
704
|
in_degree: dict[type, int] = dict.fromkeys(models, 0)
|
|
563
|
-
# dependents[dep] = list of models that depend on dep
|
|
564
705
|
dependents: dict[type, list[type]] = {m: [] for m in models}
|
|
565
|
-
|
|
566
706
|
for m in models:
|
|
567
707
|
for dep in deps.get(m, frozenset()):
|
|
568
708
|
if dep in model_set:
|
|
569
709
|
in_degree[m] += 1
|
|
570
710
|
dependents[dep].append(m)
|
|
711
|
+
return in_degree, dependents
|
|
712
|
+
|
|
571
713
|
|
|
714
|
+
def _release_in_dependency_order(
|
|
715
|
+
models: list[type],
|
|
716
|
+
in_degree: dict[type, int],
|
|
717
|
+
dependents: dict[type, list[type]],
|
|
718
|
+
) -> list[type]:
|
|
719
|
+
"""Run Kahn's BFS, consuming *in_degree*; models left in a cycle are omitted."""
|
|
572
720
|
queue: deque[type] = deque(m for m in models if in_degree[m] == 0)
|
|
573
721
|
result: list[type] = []
|
|
574
|
-
|
|
575
722
|
while queue:
|
|
576
723
|
node = queue.popleft()
|
|
577
724
|
result.append(node)
|
|
@@ -579,10 +726,6 @@ def _topological_sort(
|
|
|
579
726
|
in_degree[dependent] -= 1
|
|
580
727
|
if in_degree[dependent] == 0:
|
|
581
728
|
queue.append(dependent)
|
|
582
|
-
|
|
583
|
-
# Cyclic nodes: append in original order
|
|
584
|
-
processed = set(result)
|
|
585
|
-
result.extend(m for m in models if m not in processed)
|
|
586
729
|
return result
|
|
587
730
|
|
|
588
731
|
|
|
@@ -600,8 +743,6 @@ def _resolve_compile_closure(*roots: type) -> tuple[type, ...]:
|
|
|
600
743
|
Returns:
|
|
601
744
|
Tuple of all models (roots + transitive deps) in compilation order.
|
|
602
745
|
"""
|
|
603
|
-
from collections import deque
|
|
604
|
-
|
|
605
746
|
seen: set[type] = set()
|
|
606
747
|
all_deps: dict[type, frozenset[type]] = {}
|
|
607
748
|
queue: deque[type] = deque(roots)
|
|
@@ -678,8 +819,29 @@ def get_metadata() -> MetaData:
|
|
|
678
819
|
return SABase.metadata
|
|
679
820
|
|
|
680
821
|
|
|
681
|
-
def
|
|
682
|
-
"""
|
|
822
|
+
def configured_naming_convention(value: Mapping[str, str] | None) -> dict[str, str] | None:
|
|
823
|
+
"""Validate the ``database.schema.naming_convention`` setting.
|
|
824
|
+
|
|
825
|
+
Raises:
|
|
826
|
+
ConfigError: Naming the setting and the first unknown kind.
|
|
827
|
+
"""
|
|
828
|
+
try:
|
|
829
|
+
return naming_convention(value)
|
|
830
|
+
except ValueError as exc:
|
|
831
|
+
raise ConfigError(f"database.schema.naming_convention: {exc}") from exc
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
def reset_registry(
|
|
835
|
+
*, naming_convention: Mapping[str, str] | None | _Keep = _KEEP_CONVENTION
|
|
836
|
+
) -> None:
|
|
837
|
+
"""Clear compiled models and, when asked, set the shared metadata's naming convention.
|
|
838
|
+
|
|
839
|
+
The runtime compiles into the shared metadata after this call, so the
|
|
840
|
+
convention it receives, the one ``database.schema.naming_convention``
|
|
841
|
+
declares, names the tables ``create_all`` creates exactly as the
|
|
842
|
+
application metadata of the migration path does. Without the argument the
|
|
843
|
+
convention is left as it is; ``None`` restores SQLAlchemy's default.
|
|
844
|
+
"""
|
|
683
845
|
_registry.clear()
|
|
684
846
|
_table_registry.clear()
|
|
685
847
|
_core_registry.clear()
|
|
@@ -687,6 +849,11 @@ def reset_registry() -> None:
|
|
|
687
849
|
_shared().scoped.clear()
|
|
688
850
|
SABase.metadata.clear()
|
|
689
851
|
SABase.registry.dispose()
|
|
852
|
+
if naming_convention is _KEEP_CONVENTION:
|
|
853
|
+
return
|
|
854
|
+
SABase.metadata.naming_convention = (
|
|
855
|
+
dict(naming_convention) if naming_convention else DEFAULT_NAMING_CONVENTION
|
|
856
|
+
)
|
|
690
857
|
|
|
691
858
|
|
|
692
859
|
# ---------------------------------------------------------------------------
|