loom-kernel 0.2.0__tar.gz → 0.3.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-0.2.0 → loom_kernel-0.3.0}/.github/workflows/ci-pr.yml +1 -1
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/.github/workflows/release.yml +34 -0
- loom_kernel-0.3.0/CHANGELOG.md +216 -0
- loom_kernel-0.3.0/CHANGELOG_RELEASE.md +60 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/PKG-INFO +42 -7
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/README.md +18 -6
- loom_kernel-0.3.0/docs/_static/custom.css +13 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/conf.py +18 -2
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/examples-repo/index.md +171 -6
- loom_kernel-0.3.0/docs/guides/etl.md +426 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/guides/fake-repo-examples.md +18 -1
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/guides/quickstart.md +24 -6
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/guides/use-case-dsl.md +4 -1
- loom_kernel-0.3.0/docs/index.rst +69 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/reference/api/core.rst +8 -0
- loom_kernel-0.3.0/docs/reference/api/etl.rst +49 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/reference/index.rst +1 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/pyproject.toml +63 -2
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/celery/bootstrap.py +3 -2
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/config/__init__.py +2 -1
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/config/loader.py +149 -26
- loom_kernel-0.3.0/src/loom/core/config/resolver.py +82 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/di/container.py +26 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/discovery/_utils.py +3 -5
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/logger/config.py +23 -1
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/model/__init__.py +2 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/model/base.py +7 -15
- loom_kernel-0.3.0/src/loom/core/model/struct.py +14 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/model/timestamped.py +4 -13
- loom_kernel-0.3.0/src/loom/core/repository/__init__.py +39 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/abc/__init__.py +15 -1
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/abc/query.py +2 -2
- loom_kernel-0.3.0/src/loom/core/repository/abc/repo_for.py +151 -0
- loom_kernel-0.3.0/src/loom/core/repository/registration.py +213 -0
- loom_kernel-0.3.0/src/loom/core/repository/registry.py +140 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/__init__.py +4 -10
- loom_kernel-0.3.0/src/loom/core/repository/sqlalchemy/registry.py +121 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/repository.py +17 -2
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/response/base.py +2 -2
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/factory.py +1 -25
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/use_case.py +47 -17
- loom_kernel-0.3.0/src/loom/etl/__init__.py +199 -0
- loom_kernel-0.3.0/src/loom/etl/backends/__init__.py +9 -0
- loom_kernel-0.3.0/src/loom/etl/backends/_format_registry.py +37 -0
- loom_kernel-0.3.0/src/loom/etl/backends/_merge.py +276 -0
- loom_kernel-0.3.0/src/loom/etl/backends/_predicate.py +144 -0
- loom_kernel-0.3.0/src/loom/etl/backends/_schema_aligner/__init__.py +6 -0
- loom_kernel-0.3.0/src/loom/etl/backends/_schema_aligner/_aligner.py +23 -0
- loom_kernel-0.3.0/src/loom/etl/backends/_schema_aligner/_policy.py +66 -0
- loom_kernel-0.3.0/src/loom/etl/backends/_write_policy.py +376 -0
- loom_kernel-0.3.0/src/loom/etl/backends/polars/__init__.py +14 -0
- loom_kernel-0.3.0/src/loom/etl/backends/polars/_dtype.py +257 -0
- loom_kernel-0.3.0/src/loom/etl/backends/polars/_file_writer.py +92 -0
- loom_kernel-0.3.0/src/loom/etl/backends/polars/_predicate.py +102 -0
- loom_kernel-0.3.0/src/loom/etl/backends/polars/_reader.py +193 -0
- loom_kernel-0.3.0/src/loom/etl/backends/polars/_schema.py +180 -0
- loom_kernel-0.3.0/src/loom/etl/backends/polars/_schema_aligner.py +37 -0
- loom_kernel-0.3.0/src/loom/etl/backends/polars/_writer.py +354 -0
- loom_kernel-0.3.0/src/loom/etl/backends/polars/provider.py +138 -0
- loom_kernel-0.3.0/src/loom/etl/backends/spark/__init__.py +16 -0
- loom_kernel-0.3.0/src/loom/etl/backends/spark/_dtype.py +126 -0
- loom_kernel-0.3.0/src/loom/etl/backends/spark/_reader.py +196 -0
- loom_kernel-0.3.0/src/loom/etl/backends/spark/_schema.py +41 -0
- loom_kernel-0.3.0/src/loom/etl/backends/spark/_schema_aligner.py +40 -0
- loom_kernel-0.3.0/src/loom/etl/backends/spark/_writer.py +408 -0
- loom_kernel-0.3.0/src/loom/etl/backends/spark/provider.py +79 -0
- loom_kernel-0.3.0/src/loom/etl/checkpoint/__init__.py +15 -0
- loom_kernel-0.3.0/src/loom/etl/checkpoint/_backends/_polars.py +106 -0
- loom_kernel-0.3.0/src/loom/etl/checkpoint/_backends/_spark.py +135 -0
- loom_kernel-0.3.0/src/loom/etl/checkpoint/_cleaners.py +64 -0
- loom_kernel-0.3.0/src/loom/etl/checkpoint/_paths.py +52 -0
- loom_kernel-0.3.0/src/loom/etl/checkpoint/_scope.py +35 -0
- loom_kernel-0.3.0/src/loom/etl/checkpoint/_store.py +234 -0
- loom_kernel-0.3.0/src/loom/etl/compiler/__init__.py +48 -0
- loom_kernel-0.3.0/src/loom/etl/compiler/_binding.py +111 -0
- loom_kernel-0.3.0/src/loom/etl/compiler/_compiler.py +268 -0
- loom_kernel-0.3.0/src/loom/etl/compiler/_errors.py +316 -0
- loom_kernel-0.3.0/src/loom/etl/compiler/_plan.py +206 -0
- loom_kernel-0.3.0/src/loom/etl/compiler/_validators.py +40 -0
- loom_kernel-0.3.0/src/loom/etl/compiler/_validators_plan.py +267 -0
- loom_kernel-0.3.0/src/loom/etl/compiler/_validators_step.py +294 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/__init__.py +53 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/_format.py +21 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/_read_options.py +91 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/_utils.py +18 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/_write_options.py +111 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/expr/__init__.py +50 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/expr/_params.py +61 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/expr/_predicate.py +174 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/expr/_predicate_dialect.py +160 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/expr/_refs.py +122 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/source/__init__.py +43 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/source/_from.py +569 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/source/_specs.py +149 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/target/__init__.py +70 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/target/_file.py +34 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/target/_into.py +453 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/target/_schema_mode.py +23 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/target/_table.py +103 -0
- loom_kernel-0.3.0/src/loom/etl/declarative/target/_temp.py +43 -0
- loom_kernel-0.3.0/src/loom/etl/executor/__init__.py +61 -0
- loom_kernel-0.3.0/src/loom/etl/executor/_dispatcher.py +94 -0
- loom_kernel-0.3.0/src/loom/etl/executor/_executor.py +357 -0
- loom_kernel-0.3.0/src/loom/etl/observability/__init__.py +59 -0
- loom_kernel-0.3.0/src/loom/etl/observability/config.py +106 -0
- loom_kernel-0.3.0/src/loom/etl/observability/factory.py +52 -0
- loom_kernel-0.3.0/src/loom/etl/observability/observers/__init__.py +13 -0
- loom_kernel-0.3.0/src/loom/etl/observability/observers/_labels.py +57 -0
- loom_kernel-0.3.0/src/loom/etl/observability/observers/composite.py +62 -0
- loom_kernel-0.3.0/src/loom/etl/observability/observers/noop.py +36 -0
- loom_kernel-0.3.0/src/loom/etl/observability/observers/otel.py +263 -0
- loom_kernel-0.3.0/src/loom/etl/observability/observers/protocol.py +37 -0
- loom_kernel-0.3.0/src/loom/etl/observability/observers/structlog.py +100 -0
- loom_kernel-0.3.0/src/loom/etl/observability/recording/__init__.py +5 -0
- loom_kernel-0.3.0/src/loom/etl/observability/recording/_recorder.py +225 -0
- loom_kernel-0.3.0/src/loom/etl/observability/records.py +241 -0
- loom_kernel-0.3.0/src/loom/etl/observability/sinks/__init__.py +17 -0
- loom_kernel-0.3.0/src/loom/etl/observability/sinks/_protocol.py +44 -0
- loom_kernel-0.3.0/src/loom/etl/observability/sinks/_table.py +42 -0
- loom_kernel-0.3.0/src/loom/etl/observability/sinks/_writer.py +26 -0
- loom_kernel-0.3.0/src/loom/etl/pipeline/__init__.py +12 -0
- loom_kernel-0.3.0/src/loom/etl/pipeline/_generics.py +31 -0
- loom_kernel-0.3.0/src/loom/etl/pipeline/_params.py +27 -0
- loom_kernel-0.3.0/src/loom/etl/pipeline/_pipeline.py +62 -0
- loom_kernel-0.3.0/src/loom/etl/pipeline/_process.py +64 -0
- loom_kernel-0.3.0/src/loom/etl/pipeline/_sql.py +55 -0
- loom_kernel-0.3.0/src/loom/etl/pipeline/_step.py +154 -0
- loom_kernel-0.3.0/src/loom/etl/pipeline/_step_sql.py +91 -0
- loom_kernel-0.3.0/src/loom/etl/runner/__init__.py +6 -0
- loom_kernel-0.3.0/src/loom/etl/runner/_providers.py +64 -0
- loom_kernel-0.3.0/src/loom/etl/runner/_wiring.py +112 -0
- loom_kernel-0.3.0/src/loom/etl/runner/config_loader.py +45 -0
- loom_kernel-0.3.0/src/loom/etl/runner/core.py +166 -0
- loom_kernel-0.3.0/src/loom/etl/runner/errors.py +17 -0
- loom_kernel-0.3.0/src/loom/etl/runner/filtering.py +107 -0
- loom_kernel-0.3.0/src/loom/etl/runtime/__init__.py +5 -0
- loom_kernel-0.3.0/src/loom/etl/runtime/contracts.py +128 -0
- loom_kernel-0.3.0/src/loom/etl/schema/__init__.py +46 -0
- loom_kernel-0.3.0/src/loom/etl/schema/_contract.py +220 -0
- loom_kernel-0.3.0/src/loom/etl/schema/_schema.py +334 -0
- loom_kernel-0.3.0/src/loom/etl/storage/__init__.py +60 -0
- loom_kernel-0.3.0/src/loom/etl/storage/_config.py +373 -0
- loom_kernel-0.3.0/src/loom/etl/storage/_file_locator.py +146 -0
- loom_kernel-0.3.0/src/loom/etl/storage/_locator.py +253 -0
- loom_kernel-0.3.0/src/loom/etl/storage/routing.py +230 -0
- loom_kernel-0.3.0/src/loom/etl/testing/__init__.py +58 -0
- loom_kernel-0.3.0/src/loom/etl/testing/_result.py +88 -0
- loom_kernel-0.3.0/src/loom/etl/testing/_runners.py +142 -0
- loom_kernel-0.3.0/src/loom/etl/testing/_scenario.py +79 -0
- loom_kernel-0.3.0/src/loom/etl/testing/_stubs.py +212 -0
- loom_kernel-0.3.0/src/loom/etl/testing/spark.py +324 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/prometheus/__init__.py +1 -1
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/prometheus/middleware.py +3 -8
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/autocrud.py +43 -3
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/fastapi/auto.py +21 -5
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/model.py +1 -1
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/testing/repository_harness.py +11 -5
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/conftest.py +34 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/core/rest/test_auto_interface_integration.py +77 -6
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/core/rest/test_fastapi_app_integration.py +11 -8
- loom_kernel-0.3.0/tests/integration/core/use_case/test_custom_repository_integration.py +238 -0
- loom_kernel-0.3.0/tests/integration/etl/__init__.py +1 -0
- loom_kernel-0.3.0/tests/integration/etl/test_runner_integration.py +241 -0
- loom_kernel-0.3.0/tests/integration/etl/test_runtime_contracts.py +455 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/repository.py +4 -3
- loom_kernel-0.3.0/tests/integration/support/__init__.py +1 -0
- loom_kernel-0.3.0/tests/integration/support/logical_repo_fixtures.py +34 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/bootstrap/test_bootstrap_metrics.py +2 -2
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/config/test_config.py +98 -0
- loom_kernel-0.3.0/tests/unit/core/model/test_struct.py +12 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/use_case/test_factory.py +49 -16
- loom_kernel-0.3.0/tests/unit/etl/backends/test_polars/conftest.py +175 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_polars/test_apply_schema.py +90 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_polars/test_backend.py +390 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_polars/test_file_writer.py +71 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_polars/test_predicate_pushdown.py +160 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_polars/test_reader_columns.py +162 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_polars/test_reader_json_columns.py +199 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_polars/test_step_execution.py +223 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_polars/test_upsert_writer.py +209 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_polars/test_writer_to_frame.py +75 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_spark/conftest.py +89 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_spark/test_dtype.py +104 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_spark/test_spark_apply_schema.py +215 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_spark/test_step_execution.py +404 -0
- loom_kernel-0.3.0/tests/unit/etl/backends/test_spark/test_writer_to_frame.py +102 -0
- loom_kernel-0.3.0/tests/unit/etl/checkpoint/__init__.py +0 -0
- loom_kernel-0.3.0/tests/unit/etl/checkpoint/backends/test_checkpoint_polars.py +33 -0
- loom_kernel-0.3.0/tests/unit/etl/checkpoint/test_checkpoint_paths.py +61 -0
- loom_kernel-0.3.0/tests/unit/etl/checkpoint/test_cleaners.py +81 -0
- loom_kernel-0.3.0/tests/unit/etl/checkpoint/test_store.py +248 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/__init__.py +0 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_catalog_validator.py +92 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_compiler.py +502 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_compiler_catalog.py +132 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_compiler_upsert.py +133 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_errors.py +223 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_errors_additional_factories.py +76 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_errors_runtime_factories.py +159 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_param_exprs_validator.py +150 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_plan_traversal.py +207 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_step_validator.py +81 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_structural.py +135 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_temp_validator.py +205 -0
- loom_kernel-0.3.0/tests/unit/etl/compiler/test_upsert_validator.py +125 -0
- loom_kernel-0.3.0/tests/unit/etl/conftest.py +40 -0
- loom_kernel-0.3.0/tests/unit/etl/io/__init__.py +0 -0
- loom_kernel-0.3.0/tests/unit/etl/io/test_source.py +263 -0
- loom_kernel-0.3.0/tests/unit/etl/io/test_source_json.py +236 -0
- loom_kernel-0.3.0/tests/unit/etl/io/test_source_options.py +178 -0
- loom_kernel-0.3.0/tests/unit/etl/io/test_target.py +225 -0
- loom_kernel-0.3.0/tests/unit/etl/io/test_utils.py +32 -0
- loom_kernel-0.3.0/tests/unit/etl/io/test_variants.py +125 -0
- loom_kernel-0.3.0/tests/unit/etl/pipeline/__init__.py +1 -0
- loom_kernel-0.3.0/tests/unit/etl/pipeline/test_pipeline_process.py +67 -0
- loom_kernel-0.3.0/tests/unit/etl/pipeline/test_proxy.py +90 -0
- loom_kernel-0.3.0/tests/unit/etl/pipeline/test_step.py +132 -0
- loom_kernel-0.3.0/tests/unit/etl/schema/__init__.py +0 -0
- loom_kernel-0.3.0/tests/unit/etl/schema/test_contract.py +249 -0
- loom_kernel-0.3.0/tests/unit/etl/schema/test_schema.py +181 -0
- loom_kernel-0.3.0/tests/unit/etl/schema/test_table.py +63 -0
- loom_kernel-0.3.0/tests/unit/etl/sql/__init__.py +0 -0
- loom_kernel-0.3.0/tests/unit/etl/sql/test_merge.py +214 -0
- loom_kernel-0.3.0/tests/unit/etl/sql/test_predicate.py +99 -0
- loom_kernel-0.3.0/tests/unit/etl/sql/test_predicate_dialect.py +98 -0
- loom_kernel-0.3.0/tests/unit/etl/sql/test_sql_runtime.py +172 -0
- loom_kernel-0.3.0/tests/unit/etl/storage/__init__.py +0 -0
- loom_kernel-0.3.0/tests/unit/etl/storage/test_backend_factory.py +426 -0
- loom_kernel-0.3.0/tests/unit/etl/storage/test_io_protocols.py +101 -0
- loom_kernel-0.3.0/tests/unit/etl/storage/test_locator.py +87 -0
- loom_kernel-0.3.0/tests/unit/etl/storage/test_observability_and_protocols.py +149 -0
- loom_kernel-0.3.0/tests/unit/etl/storage/test_route_build.py +31 -0
- loom_kernel-0.3.0/tests/unit/etl/storage/test_schema_readers.py +91 -0
- loom_kernel-0.3.0/tests/unit/etl/storage/test_storage_config.py +341 -0
- loom_kernel-0.3.0/tests/unit/etl/test_config_loader.py +85 -0
- loom_kernel-0.3.0/tests/unit/etl/test_executor.py +317 -0
- loom_kernel-0.3.0/tests/unit/etl/test_format_registry.py +30 -0
- loom_kernel-0.3.0/tests/unit/etl/test_module_contracts.py +452 -0
- loom_kernel-0.3.0/tests/unit/etl/test_observer.py +351 -0
- loom_kernel-0.3.0/tests/unit/etl/test_observer_internals.py +448 -0
- loom_kernel-0.3.0/tests/unit/etl/test_public_api_discovery.py +57 -0
- loom_kernel-0.3.0/tests/unit/etl/test_record_schema_coverage.py +65 -0
- loom_kernel-0.3.0/tests/unit/etl/test_runner.py +300 -0
- loom_kernel-0.3.0/tests/unit/etl/test_runner_errors.py +19 -0
- loom_kernel-0.3.0/tests/unit/etl/test_spark_testing.py +78 -0
- loom_kernel-0.3.0/tests/unit/etl/testing/test_runners.py +146 -0
- loom_kernel-0.3.0/tests/unit/etl/testing/test_scenario_and_stubs.py +106 -0
- loom_kernel-0.3.0/tests/unit/etl/testing/test_spark_helpers.py +167 -0
- loom_kernel-0.3.0/tests/unit/prometheus/__init__.py +0 -0
- loom_kernel-0.3.0/tests/unit/rest/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/rest/test_autocrud.py +9 -9
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/rest/test_fastapi_auto_logger.py +29 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/rest/test_rest_adapter.py +34 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/rest/test_rest_model.py +2 -2
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/rest/test_router_runtime.py +3 -3
- loom_kernel-0.3.0/tests/unit/testing/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/testing/test_golden.py +12 -4
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/testing/test_http_harness.py +3 -4
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/testing/test_runner.py +11 -3
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/uv.lock +638 -5
- loom_kernel-0.2.0/CHANGELOG.md +0 -120
- loom_kernel-0.2.0/CHANGELOG_RELEASE.md +0 -125
- loom_kernel-0.2.0/docs/_static/custom.css +0 -11
- loom_kernel-0.2.0/docs/index.rst +0 -41
- loom_kernel-0.2.0/src/loom/core/repository/__init__.py +0 -21
- loom_kernel-0.2.0/src/loom/core/repository/abc/repo_for.py +0 -74
- loom_kernel-0.2.0/src/loom/core/repository/sqlalchemy/registry.py +0 -125
- loom_kernel-0.2.0/tests/integration/core/use_case/test_custom_repository_integration.py +0 -103
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/.github/workflows/ci-main.yml +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/.github/workflows/docs.yml +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/.gitignore +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/.pre-commit-config.yaml +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/.readthedocs.yaml +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/LICENSE +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/Makefile +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/codecov.yml +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/_static/.gitkeep +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/_static/logo-transparent.png +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/_static/logo.svg +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/architecture/adr/README.md +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/architecture/clean-architecture.md +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/architecture/overview.md +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/guides/autocrud.md +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/guides/celery.md +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/reference/api/repository.rst +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/reference/api/rest.rst +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/reference/api/testing.rst +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/docs/requirements.txt +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/sonar-project.properties +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/celery/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/celery/auto.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/celery/config.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/celery/constants.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/celery/event_loop.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/celery/runner.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/celery/service.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/backend/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/backend/core_model.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/backend/protocol.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/backend/sqlalchemy.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/bootstrap/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/bootstrap/kernel.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/abc/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/abc/backend.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/abc/config.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/abc/dependency.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/codec.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/decorators.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/dependency.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/gateway.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/keys.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/repository.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/cache/serializer.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/command/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/command/adapter.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/command/base.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/command/field.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/command/introspection.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/config/errors.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/config/keys.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/config/model.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/contracts/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/contracts/manifest.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/di/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/di/scope.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/discovery/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/discovery/base.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/discovery/interfaces.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/discovery/manifest.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/discovery/modules.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/engine/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/engine/compilable.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/engine/compiler.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/engine/events.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/engine/executor.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/engine/metrics.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/engine/plan.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/errors/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/errors/codes.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/errors/errors.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/job/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/job/callback.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/job/context.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/job/handle.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/job/job.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/job/service.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/logger/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/logger/abc.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/logger/registry.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/logger/structlogger.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/model/enums.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/model/field.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/model/introspection.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/model/projection.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/model/relation.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/model/types.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/model/types_postgres.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/projection/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/projection/loaders.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/projection/runtime.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/abc/repository.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/mutation.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/response/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/tracing/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/tracing/context.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/transport/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/transport/adapter.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/uow/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/uow/abc.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/uow/context.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/_predicates.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/compute.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/constants.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/field_ref.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/invoker.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/keys.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/markers.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/registry.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/core/use_case/rule.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/prometheus/adapter.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/adapter.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/compiler.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/constants.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/errors.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/fastapi/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/fastapi/app.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/fastapi/openapi.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/fastapi/response.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/middleware.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/rest/rest_adapter.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/testing/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/testing/golden.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/testing/http_harness.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/testing/in_memory.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/src/loom/testing/runner.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/golden/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/golden/baselines/.gitkeep +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/golden/outputs/.gitkeep +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/golden/plans/.gitkeep +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/helpers/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/celery_bootstrap/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/celery_bootstrap/config/conf.celery.integration.yaml +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/celery_bootstrap/test_auto_create_app_integration.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/celery_bootstrap/test_bootstrap_worker.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/conftest.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/core/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/core/repository/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/core/repository/sqlalchemy/conftest.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/core/repository/sqlalchemy/test_cache_integration.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/core/repository/sqlalchemy/test_repository_integration.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/core/rest/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/core/use_case/test_use_case_crud_integration.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/config/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/config/conf.interfaces.yaml +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/config/conf.manifest.yaml +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/config/conf.modules.yaml +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/config/conf.yaml +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/main.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/manifest.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/category/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/category/model.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/category/schemas.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/interface.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/jobs.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/model.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/relations.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/repository_contract.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/review/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/review/model.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/review/schemas.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/schemas.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/integration/fake_repo/product/use_cases.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/celery_bootstrap/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/celery_bootstrap/test_bootstrap.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/celery_bootstrap/test_event_loop.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/celery_jobs/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/celery_jobs/test_auto.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/celery_jobs/test_celery_service.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/celery_jobs/test_config.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/celery_jobs/test_runner.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/backend/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/backend/test_backend_compiler.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/bootstrap/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/bootstrap/test_bootstrap.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/bootstrap/test_kernel.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/cache/test_cached_repository.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/command/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/command/test_command_base.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/command/test_command_field.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/command/test_command_patch.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/command/test_introspection.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/config/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/di/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/di/test_container.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/discovery/test_manifest.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/engine/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/engine/test_compiler.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/engine/test_executor.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/engine/test_executor_trace.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/engine/test_executor_uow.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/engine/test_metrics.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/engine/test_plan.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/errors/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/errors/test_errors.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/job/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/job/conftest.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/job/test_callback.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/job/test_context.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/job/test_handle.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/job/test_inline_service.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/job/test_job.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/logger/test_registry.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/model/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/model/test_model.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/model/test_timestamped.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/projection/test_runtime.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/repository/abc/conftest.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/repository/abc/test_query.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/repository/abc/test_repository_contract.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/repository/sqlalchemy/conftest.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/repository/sqlalchemy/test_loaders.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/repository/sqlalchemy/test_repository.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/repository/sqlalchemy/test_transactional.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/tracing/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/tracing/test_context.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/uow/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/uow/test_executor_uow.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/uow/test_sqlalchemy_uow.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/uow/test_uow_protocols.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/use_case/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/use_case/test_compute.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/use_case/test_field_ref.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/use_case/test_invoker.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/use_case/test_markers.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/use_case/test_rule.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/core/use_case/test_use_case.py +0 -0
- {loom_kernel-0.2.0/tests/unit/prometheus → loom_kernel-0.3.0/tests/unit/etl}/__init__.py +0 -0
- {loom_kernel-0.2.0/tests/unit/rest → loom_kernel-0.3.0/tests/unit/etl/backends/test_polars}/__init__.py +0 -0
- {loom_kernel-0.2.0/tests/unit/testing → loom_kernel-0.3.0/tests/unit/etl/backends/test_spark}/__init__.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/prometheus/test_adapter.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/prometheus/test_middleware.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/rest/test_middleware.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/rest/test_pydantic_adapter.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/rest/test_response.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/rest/test_rest_compiler.py +0 -0
- {loom_kernel-0.2.0 → loom_kernel-0.3.0}/tests/unit/testing/test_in_memory.py +0 -0
|
@@ -14,6 +14,7 @@ on:
|
|
|
14
14
|
permissions:
|
|
15
15
|
contents: write
|
|
16
16
|
id-token: write
|
|
17
|
+
pull-requests: write
|
|
17
18
|
|
|
18
19
|
concurrency:
|
|
19
20
|
group: release-${{ github.ref }}
|
|
@@ -30,6 +31,7 @@ jobs:
|
|
|
30
31
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
31
32
|
with:
|
|
32
33
|
fetch-depth: 0
|
|
34
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
33
35
|
|
|
34
36
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
35
37
|
with:
|
|
@@ -85,6 +87,38 @@ jobs:
|
|
|
85
87
|
sed -i "0,/^version = \".*\"/s//version = \"${VERSION}\"/" pyproject.toml
|
|
86
88
|
sed -i "/^\[tool.commitizen\]/,/^\[/ s/^version = \".*\"/version = \"${VERSION}\"/" pyproject.toml
|
|
87
89
|
|
|
90
|
+
- name: Open version bump PR
|
|
91
|
+
if: ${{ steps.version.outputs.deploy == 'true' }}
|
|
92
|
+
env:
|
|
93
|
+
VERSION: ${{ steps.version.outputs.version }}
|
|
94
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
95
|
+
shell: bash
|
|
96
|
+
run: |
|
|
97
|
+
set -euo pipefail
|
|
98
|
+
git config user.name "github-actions[bot]"
|
|
99
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
100
|
+
|
|
101
|
+
BRANCH="docs/release-v${VERSION}"
|
|
102
|
+
git checkout -b "${BRANCH}"
|
|
103
|
+
|
|
104
|
+
if [ -f CHANGELOG_RELEASE.md ]; then
|
|
105
|
+
cat CHANGELOG_RELEASE.md CHANGELOG.md > CHANGELOG_MERGED.md
|
|
106
|
+
mv CHANGELOG_MERGED.md CHANGELOG.md
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
git add pyproject.toml CHANGELOG.md
|
|
110
|
+
git diff --staged --quiet && exit 0
|
|
111
|
+
git commit -m "chore(release): bump version to ${VERSION}"
|
|
112
|
+
git push origin "${BRANCH}"
|
|
113
|
+
|
|
114
|
+
gh pr create \
|
|
115
|
+
--title "chore(release): bump version to ${VERSION}" \
|
|
116
|
+
--body "Automated version bump and changelog update after release v${VERSION}." \
|
|
117
|
+
--base master \
|
|
118
|
+
--head "${BRANCH}"
|
|
119
|
+
|
|
120
|
+
gh pr merge "${BRANCH}" --squash --auto --delete-branch
|
|
121
|
+
|
|
88
122
|
- name: Build package
|
|
89
123
|
if: ${{ steps.version.outputs.deploy == 'true' }}
|
|
90
124
|
shell: bash
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# 🚀 Release 0.3.0 ([#14](https://github.com/the-reacher-data/loom-py/pull/14)) ([`ef414c5`](https://github.com/the-reacher-data/loom-py/commit/ef414c5bfd303296af450840318dfbe9d301e5d1))
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## ✨ Features
|
|
5
|
+
### config
|
|
6
|
+
- **config:** add cloud URI support and pluggable resolver extension point<br>
|
|
7
|
+
> Add fsspec as a hard dependency of loom[config]
|
|
8
|
+
> load_config() now accepts s3://, gs://, abfss://, r2:// URIs via fsspec
|
|
9
|
+
> Add ConfigResolver protocol for pluggable ${prefix:key} resolution at
|
|
10
|
+
> parse time (enables SSM, Key Vault, etc. without baking secrets into images)
|
|
11
|
+
> Resolver registration is idempotent; resolvers are evaluated at job startup
|
|
12
|
+
> so secret rotation takes effect on the next run
|
|
13
|
+
> Migrate loom.etl.runner.config_loader to use core load_config, removing
|
|
14
|
+
> the parallel OmegaConf implementation
|
|
15
|
+
> ETL _load_yaml inherits cloud URI and resolver support transparently
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### etl
|
|
19
|
+
- **etl:** add FileLocator with explicit alias API for file routes<br>
|
|
20
|
+
> Introduces `FileLocator` protocol and `MappingFileLocator` so that
|
|
21
|
+
> `FromFile.alias("name")` / `IntoFile.alias("name")` specs resolve at
|
|
22
|
+
> runtime through `storage.files` config rather than hard-coded URIs.
|
|
23
|
+
> `FileLocation` / `FileLocator` / `MappingFileLocator` in `storage/_file_locator.py`
|
|
24
|
+
> `StorageConfig.to_file_locator()` returns `MappingFileLocator | None`
|
|
25
|
+
> (None when `files` is empty — no conditional needed at call sites)
|
|
26
|
+
> `FromFile.alias()` / `IntoFile.alias()` classmethods set `is_alias=True`
|
|
27
|
+
> on the emitted spec
|
|
28
|
+
> `is_alias: bool` added to `FileSourceSpec` and `FileSpec`
|
|
29
|
+
> Polars and Spark backends resolve aliases via injected `file_locator`
|
|
30
|
+
> Both providers wired: `file_locator = config.to_file_locator()`
|
|
31
|
+
> Full test coverage across io, storage, and backend layers
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## 🐛 Fixes
|
|
36
|
+
### observability
|
|
37
|
+
- **observability:** honor missing table policy for record store writers
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## 📖 Documentation
|
|
41
|
+
### etl
|
|
42
|
+
- **etl:** keep only user guide and drop refactor docs
|
|
43
|
+
- **etl:** expand ETL documentation and update directory table<br>
|
|
44
|
+
> Add dummy-loom-etl companion repo link in README and etl guide
|
|
45
|
+
> Expand README subpaths table with loom.etl and loom.core.config entries
|
|
46
|
+
> Add FileLocator/alias API, cloud config URI, and ConfigResolver sections to etl guide
|
|
47
|
+
> Add loom.etl.backends (polars + spark) to etl.rst API reference
|
|
48
|
+
> Add loom.core.config to core.rst API reference
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## ♻️ Refactor
|
|
54
|
+
### stepsql
|
|
55
|
+
- **stepsql:** delegate SQL execution to backend readers
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# 🚀 Release 0.3.0 ([#14](https://github.com/the-reacher-data/loom-py/pull/14)) ([`ef414c5`](https://github.com/the-reacher-data/loom-py/commit/ef414c5bfd303296af450840318dfbe9d301e5d1))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
## ✨ Features
|
|
65
|
+
### config
|
|
66
|
+
- **config:** add cloud URI support and pluggable resolver extension point<br>
|
|
67
|
+
> Add fsspec as a hard dependency of loom[config]
|
|
68
|
+
> load_config() now accepts s3://, gs://, abfss://, r2:// URIs via fsspec
|
|
69
|
+
> Add ConfigResolver protocol for pluggable ${prefix:key} resolution at
|
|
70
|
+
> parse time (enables SSM, Key Vault, etc. without baking secrets into images)
|
|
71
|
+
> Resolver registration is idempotent; resolvers are evaluated at job startup
|
|
72
|
+
> so secret rotation takes effect on the next run
|
|
73
|
+
> Migrate loom.etl.runner.config_loader to use core load_config, removing
|
|
74
|
+
> the parallel OmegaConf implementation
|
|
75
|
+
> ETL _load_yaml inherits cloud URI and resolver support transparently
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
### etl
|
|
79
|
+
- **etl:** add FileLocator with explicit alias API for file routes<br>
|
|
80
|
+
> Introduces `FileLocator` protocol and `MappingFileLocator` so that
|
|
81
|
+
> `FromFile.alias("name")` / `IntoFile.alias("name")` specs resolve at
|
|
82
|
+
> runtime through `storage.files` config rather than hard-coded URIs.
|
|
83
|
+
> `FileLocation` / `FileLocator` / `MappingFileLocator` in `storage/_file_locator.py`
|
|
84
|
+
> `StorageConfig.to_file_locator()` returns `MappingFileLocator | None`
|
|
85
|
+
> (None when `files` is empty — no conditional needed at call sites)
|
|
86
|
+
> `FromFile.alias()` / `IntoFile.alias()` classmethods set `is_alias=True`
|
|
87
|
+
> on the emitted spec
|
|
88
|
+
> `is_alias: bool` added to `FileSourceSpec` and `FileSpec`
|
|
89
|
+
> Polars and Spark backends resolve aliases via injected `file_locator`
|
|
90
|
+
> Both providers wired: `file_locator = config.to_file_locator()`
|
|
91
|
+
> Full test coverage across io, storage, and backend layers
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
## 🐛 Fixes
|
|
96
|
+
### observability
|
|
97
|
+
- **observability:** honor missing table policy for record store writers
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
## 📖 Documentation
|
|
101
|
+
### etl
|
|
102
|
+
- **etl:** keep only user guide and drop refactor docs
|
|
103
|
+
- **etl:** expand ETL documentation and update directory table<br>
|
|
104
|
+
> Add dummy-loom-etl companion repo link in README and etl guide
|
|
105
|
+
> Expand README subpaths table with loom.etl and loom.core.config entries
|
|
106
|
+
> Add FileLocator/alias API, cloud config URI, and ConfigResolver sections to etl guide
|
|
107
|
+
> Add loom.etl.backends (polars + spark) to etl.rst API reference
|
|
108
|
+
> Add loom.core.config to core.rst API reference
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
## ♻️ Refactor
|
|
114
|
+
### stepsql
|
|
115
|
+
- **stepsql:** delegate SQL execution to backend readers
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# 🚀 Release 0.2.1 ([#12](https://github.com/the-reacher-data/loom-py/pull/12)) ([`87f7d1f`](https://github.com/the-reacher-data/loom-py/commit/87f7d1f1eb1ccde71d0aca1c5584b83317e30707))
|
|
124
|
+
|
|
125
|
+
## ✨ Features
|
|
126
|
+
|
|
127
|
+
### logger
|
|
128
|
+
- **logger:** support per-logger levels from config<br>
|
|
129
|
+
> `LoomConfig` now accepts a `loggers` mapping to override the log level per named logger. Resolves `structlog` / stdlib incompatibility when mixing loom-managed and third-party loggers.
|
|
130
|
+
|
|
131
|
+
### repository
|
|
132
|
+
- **repository:** generalize main repo registration for loom structs<br>
|
|
133
|
+
> `repository_for` is now importable from `loom.core.repository` (top-level). The SQLAlchemy-specific import path still works but is no longer the canonical one.
|
|
134
|
+
|
|
135
|
+
## 🐛 Bug Fixes
|
|
136
|
+
|
|
137
|
+
### rest
|
|
138
|
+
- **rest:** serialize pagination envelopes in camel case<br>
|
|
139
|
+
> `PageResult` and list-envelope responses were serialized in snake_case. All envelope fields now follow the camelCase contract of the HTTP layer.
|
|
140
|
+
- **rest:** support loom structs in autocrud tests<br>
|
|
141
|
+
> Auto-CRUD route generation was not exercising the `msgspec.Struct` code path in integration tests.
|
|
142
|
+
|
|
143
|
+
### prometheus
|
|
144
|
+
- **prometheus:** expose metrics at exact path<br>
|
|
145
|
+
> Metrics endpoint was registered with a trailing-slash variant that did not match the documented `/metrics` path.
|
|
146
|
+
|
|
147
|
+
### docs
|
|
148
|
+
- **docs:** fix RTD build failure, logo and docs examples (#10, #11)<br>
|
|
149
|
+
> Mock `starlette`, `celery`, `kombu`, `redis` in `autodoc_mock_imports`. Logo resized to natural proportions with dark-mode safe background. Status badges added to index. Rule/Compute examples updated to named predicates.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
# 🚀 Release 0.2.0 ([#9](https://github.com/the-reacher-data/loom-py/pull/9)) ([`2f669ab`](https://github.com/the-reacher-data/loom-py/commit/2f669ab205c7255eb6494e4cdb8ab8092817af62))
|
|
154
|
+
|
|
155
|
+
## ✨ Features
|
|
156
|
+
|
|
157
|
+
### cache
|
|
158
|
+
- **cache:** aiocache gateway with auto-inferred invalidation specs<br>
|
|
159
|
+
> CachedRepository wraps any repository with read-through/write-through caching. ONE_TO_MANY depends_on specs are auto-generated from field annotations — no explicit declaration needed. Explicit depends_on always wins.
|
|
160
|
+
|
|
161
|
+
### celery
|
|
162
|
+
- **celery:** production-ready Celery integration layer<br>
|
|
163
|
+
> CeleryJobService, persistent worker event loop, trace propagation, eager fallback, and task_default_queue routing so callbacks land on the correct consumed queue. bootstrap_worker compiles use cases, repositories, and registers Celery tasks in a single call.
|
|
164
|
+
|
|
165
|
+
- **celery:** worker job discovery from modules or manifest<br>
|
|
166
|
+
> bootstrap_worker discovers and registers Job classes automatically from module include paths (mode: modules) or from a typed WorkerManifest (mode: manifest). WorkerManifest replaces scattered JOBS/USE_CASES/INTERFACES module attributes with a single typed contract.
|
|
167
|
+
|
|
168
|
+
- **celery:** interfaces= and use_cases= on bootstrap_worker<br>
|
|
169
|
+
> Callbacks that call ApplicationInvoker need matching use-case keys compiled in the worker. interfaces= extracts use-case types from RestInterface route declarations (including AutoCRUD-generated ones). use_cases= handles non-AutoCRUD scenarios. Both can be combined with discovery mode.
|
|
170
|
+
|
|
171
|
+
### core
|
|
172
|
+
- **core:** typed repository abstractions and SQLAlchemy backend<br>
|
|
173
|
+
> Async repository protocol (RepositoryRead, RepositoryWrite, RepoFor) backed by SQLAlchemy 2.0 async session. Struct-based model system using msgspec.Struct as the single source of truth — models compile to SA mapped classes at startup via compile_all(). count() and UPDATE RETURNING included as first-class operations.
|
|
174
|
+
|
|
175
|
+
- **core:** use-case DSL with field refs, compute, rules and typed markers<br>
|
|
176
|
+
> Declarative use-case definition via Input, Load, LoadById, Exists, Compute and Rule markers. Signature inspection runs once at compile time; RuntimeExecutor drives execution from an immutable ExecutionPlan. No per-request reflection.
|
|
177
|
+
|
|
178
|
+
- **core:** ApplicationInvoker and named use-case registry<br>
|
|
179
|
+
> Use cases and job callbacks invoke other use cases by type through ApplicationInvoker without direct coupling. A named registry maps use-case keys to compiled instances at bootstrap, providing a stable cross-invocation contract.
|
|
180
|
+
|
|
181
|
+
- **core:** compiled model artifact and cache entity keys<br>
|
|
182
|
+
> compile_all() produces a typed CompiledCore artifact exposing stable entity keys used by the cache layer for deterministic repository-level invalidation across reads and writes.
|
|
183
|
+
|
|
184
|
+
- **core:** executor skips UoW for read-only use cases and GET routes<br>
|
|
185
|
+
> UseCase.read_only=True and all GET routes bypass UoW.begin/commit, removing at minimum one BEGIN+COMMIT round-trip from every read request on PostgreSQL.
|
|
186
|
+
|
|
187
|
+
### job
|
|
188
|
+
- **job:** async job domain model and orchestration primitives<br>
|
|
189
|
+
> Job[ResultT] base class with Celery routing ClassVars. JobHandle / JobGroup with dual-mode waiting (Celery + inline). JobCallback lifecycle with on_success/on_failure. Dispatch is transactionally safe — jobs flush on UoW commit and are cleared on rollback.
|
|
190
|
+
|
|
191
|
+
### observability
|
|
192
|
+
- **observability:** trace_id propagation and Prometheus adapter<br>
|
|
193
|
+
> trace_id injected into every request context and propagated to job callbacks. MetricsAdapter protocol emits execution events; PrometheusAdapter records latency histograms and error counters with low cardinality labels.
|
|
194
|
+
|
|
195
|
+
### projection
|
|
196
|
+
- **projection:** compiler-driven memory/SQL routing<br>
|
|
197
|
+
> Projections are source-agnostic at declaration time. The backend compiler decides at compile_all() whether each projection runs in-memory (relation already loaded in the active profile) or via SQL. Users declare only CountLoader, ExistsLoader, or JoinFieldsLoader — no source= parameter. Internal _Memory* and _Sql* loaders are synthesized at compile time.
|
|
198
|
+
|
|
199
|
+
### rest
|
|
200
|
+
- **rest:** AutoCRUD and FastAPI adapter<br>
|
|
201
|
+
> RestInterface.auto=True generates full CRUD routes at class definition time via build_auto_routes(). OpenAPI contracts expose query params, pagination defaults, and decoupled CreateInput/UpdateInput write DTOs. Discovery engine mounts all declared interfaces at bootstrap.
|
|
202
|
+
|
|
203
|
+
## 📖 Documentation
|
|
204
|
+
|
|
205
|
+
- Sphinx documentation platform with full public guides<br>
|
|
206
|
+
> Quickstart, use-case DSL reference, AutoCRUD guide, Celery integration guide (job definition, dispatch, callbacks, YAML reference, bootstrap options, ApplicationInvoker, Docker-compose stack), and dummy-loom examples-repo walkthrough. Deployed to Read the Docs.
|
|
207
|
+
|
|
208
|
+
## ⚡ Performance
|
|
209
|
+
|
|
210
|
+
### engine
|
|
211
|
+
- **engine:** UPDATE RETURNING replaces SELECT + flush + refresh<br>
|
|
212
|
+
> SQLAlchemyUpdateMixin.update() issues a single UPDATE ... RETURNING round-trip. Server-side onupdate expressions are pre-computed at init time and injected into the SET clause automatically.
|
|
213
|
+
|
|
214
|
+
### repository
|
|
215
|
+
- **repository:** single-query total count for offset pagination<br>
|
|
216
|
+
> list_with_query with PaginationMode.OFFSET issues a single SELECT COUNT(*) instead of a separate full-table scan, eliminating one round-trip per paginated list operation.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# 🚀 Release 0.3.0 ([#14](https://github.com/the-reacher-data/loom-py/pull/14)) ([`ef414c5`](https://github.com/the-reacher-data/loom-py/commit/ef414c5bfd303296af450840318dfbe9d301e5d1))
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## ✨ Features
|
|
5
|
+
### config
|
|
6
|
+
- **config:** add cloud URI support and pluggable resolver extension point<br>
|
|
7
|
+
> Add fsspec as a hard dependency of loom[config]
|
|
8
|
+
> load_config() now accepts s3://, gs://, abfss://, r2:// URIs via fsspec
|
|
9
|
+
> Add ConfigResolver protocol for pluggable ${prefix:key} resolution at
|
|
10
|
+
> parse time (enables SSM, Key Vault, etc. without baking secrets into images)
|
|
11
|
+
> Resolver registration is idempotent; resolvers are evaluated at job startup
|
|
12
|
+
> so secret rotation takes effect on the next run
|
|
13
|
+
> Migrate loom.etl.runner.config_loader to use core load_config, removing
|
|
14
|
+
> the parallel OmegaConf implementation
|
|
15
|
+
> ETL _load_yaml inherits cloud URI and resolver support transparently
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### etl
|
|
19
|
+
- **etl:** add FileLocator with explicit alias API for file routes<br>
|
|
20
|
+
> Introduces `FileLocator` protocol and `MappingFileLocator` so that
|
|
21
|
+
> `FromFile.alias("name")` / `IntoFile.alias("name")` specs resolve at
|
|
22
|
+
> runtime through `storage.files` config rather than hard-coded URIs.
|
|
23
|
+
> `FileLocation` / `FileLocator` / `MappingFileLocator` in `storage/_file_locator.py`
|
|
24
|
+
> `StorageConfig.to_file_locator()` returns `MappingFileLocator | None`
|
|
25
|
+
> (None when `files` is empty — no conditional needed at call sites)
|
|
26
|
+
> `FromFile.alias()` / `IntoFile.alias()` classmethods set `is_alias=True`
|
|
27
|
+
> on the emitted spec
|
|
28
|
+
> `is_alias: bool` added to `FileSourceSpec` and `FileSpec`
|
|
29
|
+
> Polars and Spark backends resolve aliases via injected `file_locator`
|
|
30
|
+
> Both providers wired: `file_locator = config.to_file_locator()`
|
|
31
|
+
> Full test coverage across io, storage, and backend layers
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## 🐛 Fixes
|
|
36
|
+
### observability
|
|
37
|
+
- **observability:** honor missing table policy for record store writers
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## 📖 Documentation
|
|
41
|
+
### etl
|
|
42
|
+
- **etl:** keep only user guide and drop refactor docs
|
|
43
|
+
- **etl:** expand ETL documentation and update directory table<br>
|
|
44
|
+
> Add dummy-loom-etl companion repo link in README and etl guide
|
|
45
|
+
> Expand README subpaths table with loom.etl and loom.core.config entries
|
|
46
|
+
> Add FileLocator/alias API, cloud config URI, and ConfigResolver sections to etl guide
|
|
47
|
+
> Add loom.etl.backends (polars + spark) to etl.rst API reference
|
|
48
|
+
> Add loom.core.config to core.rst API reference
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## ♻️ Refactor
|
|
54
|
+
### stepsql
|
|
55
|
+
- **stepsql:** delegate SQL execution to backend readers
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: loom-kernel
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Loom Python project
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -17,7 +17,30 @@ Requires-Dist: celery<6.0,>=5.3; extra == 'celery'
|
|
|
17
17
|
Requires-Dist: kombu<6.0,>=5.3; extra == 'celery'
|
|
18
18
|
Requires-Dist: redis<6.0,>=5.0; extra == 'celery'
|
|
19
19
|
Provides-Extra: config
|
|
20
|
+
Requires-Dist: fsspec>=2024.2.0; extra == 'config'
|
|
20
21
|
Requires-Dist: omegaconf<3.0,>=2.3; extra == 'config'
|
|
22
|
+
Provides-Extra: etl-otel
|
|
23
|
+
Requires-Dist: opentelemetry-api<2.0,>=1.20; extra == 'etl-otel'
|
|
24
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2.0,>=1.20; extra == 'etl-otel'
|
|
25
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2.0,>=1.20; extra == 'etl-otel'
|
|
26
|
+
Requires-Dist: opentelemetry-sdk<2.0,>=1.20; extra == 'etl-otel'
|
|
27
|
+
Provides-Extra: etl-polars
|
|
28
|
+
Requires-Dist: deltalake<2.0,>=1.5; extra == 'etl-polars'
|
|
29
|
+
Requires-Dist: fsspec>=2024.2.0; extra == 'etl-polars'
|
|
30
|
+
Requires-Dist: opentelemetry-api<2.0,>=1.20; extra == 'etl-polars'
|
|
31
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2.0,>=1.20; extra == 'etl-polars'
|
|
32
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2.0,>=1.20; extra == 'etl-polars'
|
|
33
|
+
Requires-Dist: opentelemetry-sdk<2.0,>=1.20; extra == 'etl-polars'
|
|
34
|
+
Requires-Dist: polars<2.0,>=1.0; extra == 'etl-polars'
|
|
35
|
+
Provides-Extra: etl-spark
|
|
36
|
+
Requires-Dist: delta-spark<4.0,>=3.2; extra == 'etl-spark'
|
|
37
|
+
Requires-Dist: findspark<3.0,>=2.0; extra == 'etl-spark'
|
|
38
|
+
Requires-Dist: fsspec>=2024.2.0; extra == 'etl-spark'
|
|
39
|
+
Requires-Dist: opentelemetry-api<2.0,>=1.20; extra == 'etl-spark'
|
|
40
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2.0,>=1.20; extra == 'etl-spark'
|
|
41
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2.0,>=1.20; extra == 'etl-spark'
|
|
42
|
+
Requires-Dist: opentelemetry-sdk<2.0,>=1.20; extra == 'etl-spark'
|
|
43
|
+
Requires-Dist: pyspark<4.0,>=3.5; extra == 'etl-spark'
|
|
21
44
|
Provides-Extra: prometheus
|
|
22
45
|
Requires-Dist: prometheus-client>=0.20; extra == 'prometheus'
|
|
23
46
|
Provides-Extra: pyspark
|
|
@@ -33,11 +56,9 @@ Provides-Extra: sqlalchemy
|
|
|
33
56
|
Requires-Dist: sqlalchemy<3.0,>=2.0; extra == 'sqlalchemy'
|
|
34
57
|
Description-Content-Type: text/markdown
|
|
35
58
|
|
|
36
|
-
<
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
</p>
|
|
40
|
-
</div>
|
|
59
|
+
<p align="center">
|
|
60
|
+
<img src="docs/_static/logo-transparent.png" alt="loom-kernel" width="160" style="background:#ffffff;border-radius:6px;padding:8px 20px;" />
|
|
61
|
+
</p>
|
|
41
62
|
|
|
42
63
|
# loom-kernel
|
|
43
64
|
|
|
@@ -72,7 +93,8 @@ infrastructure (DB, cache, transport) without breaking business logic.
|
|
|
72
93
|
|
|
73
94
|
- Usage guides and architecture docs are available in the `docs/` site.
|
|
74
95
|
- API reference is autogenerated from public docstrings.
|
|
75
|
-
- End-to-end demo
|
|
96
|
+
- End-to-end REST demo: [`dummy-loom`](https://github.com/the-reacher-data/dummy-loom).
|
|
97
|
+
- End-to-end ETL demo: [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl) — full Polars and Spark pipeline examples.
|
|
76
98
|
|
|
77
99
|
## Main subpaths
|
|
78
100
|
|
|
@@ -84,10 +106,23 @@ infrastructure (DB, cache, transport) without breaking business logic.
|
|
|
84
106
|
| `src/loom/core/repository/sqlalchemy` | Concrete async SQLAlchemy repository implementation. |
|
|
85
107
|
| `src/loom/core/model` | Base model, fields, relations, and entity introspection. |
|
|
86
108
|
| `src/loom/core/cache` | Decorators and cached repository with dependency invalidation. |
|
|
109
|
+
| `src/loom/core/config` | YAML config loader with cloud URI support and pluggable resolvers. |
|
|
87
110
|
| `src/loom/rest` | Framework-agnostic REST model and route compiler. |
|
|
88
111
|
| `src/loom/rest/fastapi` | Direct FastAPI integration (auto wiring and runtime router). |
|
|
89
112
|
| `src/loom/prometheus` | Middleware and adapter for runtime metrics. |
|
|
90
113
|
| `src/loom/testing` | Harnesses for unit/integration tests and golden tests. |
|
|
114
|
+
| `src/loom/etl` | Declarative ETL subsystem — pipelines, Polars/Spark backends, observability. |
|
|
115
|
+
| `src/loom/etl/pipeline` | `ETLStep`, `ETLProcess`, `ETLPipeline`, `StepSQL`, and `ETLParams`. |
|
|
116
|
+
| `src/loom/etl/declarative` | `FromTable`, `FromFile`, `IntoTable`, `IntoFile`, predicate DSL, and `params` proxy. |
|
|
117
|
+
| `src/loom/etl/schema` | Backend-agnostic schema model (`LoomDtype`, `ColumnSchema`, `TableRef`). |
|
|
118
|
+
| `src/loom/etl/storage` | Storage config, table/file locators, and route resolution. |
|
|
119
|
+
| `src/loom/etl/compiler` | Compile-time validation and execution plan builder. |
|
|
120
|
+
| `src/loom/etl/runner` | `ETLRunner` entry point and YAML config loader. |
|
|
121
|
+
| `src/loom/etl/checkpoint` | Step-level checkpoint store for incremental re-runs. |
|
|
122
|
+
| `src/loom/etl/observability` | Run/step observers, OTEL sink, structlog sink, and execution records. |
|
|
123
|
+
| `src/loom/etl/backends/polars` | Polars + Delta Lake reader, writer, and schema aligner. |
|
|
124
|
+
| `src/loom/etl/backends/spark` | Spark + Delta reader, writer, and schema aligner. |
|
|
125
|
+
| `src/loom/etl/testing` | `PolarsStepRunner`, `SparkStepRunner`, `ETLScenario`, and test stubs. |
|
|
91
126
|
|
|
92
127
|
## Quick start
|
|
93
128
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
<
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
</p>
|
|
5
|
-
</div>
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/_static/logo-transparent.png" alt="loom-kernel" width="160" style="background:#ffffff;border-radius:6px;padding:8px 20px;" />
|
|
3
|
+
</p>
|
|
6
4
|
|
|
7
5
|
# loom-kernel
|
|
8
6
|
|
|
@@ -37,7 +35,8 @@ infrastructure (DB, cache, transport) without breaking business logic.
|
|
|
37
35
|
|
|
38
36
|
- Usage guides and architecture docs are available in the `docs/` site.
|
|
39
37
|
- API reference is autogenerated from public docstrings.
|
|
40
|
-
- End-to-end demo
|
|
38
|
+
- End-to-end REST demo: [`dummy-loom`](https://github.com/the-reacher-data/dummy-loom).
|
|
39
|
+
- End-to-end ETL demo: [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl) — full Polars and Spark pipeline examples.
|
|
41
40
|
|
|
42
41
|
## Main subpaths
|
|
43
42
|
|
|
@@ -49,10 +48,23 @@ infrastructure (DB, cache, transport) without breaking business logic.
|
|
|
49
48
|
| `src/loom/core/repository/sqlalchemy` | Concrete async SQLAlchemy repository implementation. |
|
|
50
49
|
| `src/loom/core/model` | Base model, fields, relations, and entity introspection. |
|
|
51
50
|
| `src/loom/core/cache` | Decorators and cached repository with dependency invalidation. |
|
|
51
|
+
| `src/loom/core/config` | YAML config loader with cloud URI support and pluggable resolvers. |
|
|
52
52
|
| `src/loom/rest` | Framework-agnostic REST model and route compiler. |
|
|
53
53
|
| `src/loom/rest/fastapi` | Direct FastAPI integration (auto wiring and runtime router). |
|
|
54
54
|
| `src/loom/prometheus` | Middleware and adapter for runtime metrics. |
|
|
55
55
|
| `src/loom/testing` | Harnesses for unit/integration tests and golden tests. |
|
|
56
|
+
| `src/loom/etl` | Declarative ETL subsystem — pipelines, Polars/Spark backends, observability. |
|
|
57
|
+
| `src/loom/etl/pipeline` | `ETLStep`, `ETLProcess`, `ETLPipeline`, `StepSQL`, and `ETLParams`. |
|
|
58
|
+
| `src/loom/etl/declarative` | `FromTable`, `FromFile`, `IntoTable`, `IntoFile`, predicate DSL, and `params` proxy. |
|
|
59
|
+
| `src/loom/etl/schema` | Backend-agnostic schema model (`LoomDtype`, `ColumnSchema`, `TableRef`). |
|
|
60
|
+
| `src/loom/etl/storage` | Storage config, table/file locators, and route resolution. |
|
|
61
|
+
| `src/loom/etl/compiler` | Compile-time validation and execution plan builder. |
|
|
62
|
+
| `src/loom/etl/runner` | `ETLRunner` entry point and YAML config loader. |
|
|
63
|
+
| `src/loom/etl/checkpoint` | Step-level checkpoint store for incremental re-runs. |
|
|
64
|
+
| `src/loom/etl/observability` | Run/step observers, OTEL sink, structlog sink, and execution records. |
|
|
65
|
+
| `src/loom/etl/backends/polars` | Polars + Delta Lake reader, writer, and schema aligner. |
|
|
66
|
+
| `src/loom/etl/backends/spark` | Spark + Delta reader, writer, and schema aligner. |
|
|
67
|
+
| `src/loom/etl/testing` | `PolarsStepRunner`, `SparkStepRunner`, `ETLScenario`, and test stubs. |
|
|
56
68
|
|
|
57
69
|
## Quick start
|
|
58
70
|
|
|
@@ -6,6 +6,7 @@ import os
|
|
|
6
6
|
import sys
|
|
7
7
|
from datetime import datetime
|
|
8
8
|
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
9
10
|
|
|
10
11
|
ROOT = Path(__file__).resolve().parents[1]
|
|
11
12
|
SRC = ROOT / "src"
|
|
@@ -52,7 +53,14 @@ napoleon_google_docstring = True
|
|
|
52
53
|
napoleon_numpy_docstring = False
|
|
53
54
|
|
|
54
55
|
|
|
55
|
-
def _skip_duplicate_reexports(
|
|
56
|
+
def _skip_duplicate_reexports(
|
|
57
|
+
app: Any,
|
|
58
|
+
what: str,
|
|
59
|
+
name: str,
|
|
60
|
+
obj: Any,
|
|
61
|
+
skip: bool,
|
|
62
|
+
options: Any,
|
|
63
|
+
) -> bool:
|
|
56
64
|
"""Skip known re-exported symbols that duplicate canonical API objects."""
|
|
57
65
|
del what, obj, options
|
|
58
66
|
current_module = app.env.temp_data.get("autodoc:module")
|
|
@@ -80,16 +88,24 @@ intersphinx_mapping = {
|
|
|
80
88
|
# Optional dependencies are mocked to keep docs builds lightweight and stable.
|
|
81
89
|
autodoc_mock_imports = [
|
|
82
90
|
"aiocache",
|
|
91
|
+
"celery",
|
|
92
|
+
"deltalake",
|
|
83
93
|
"fastapi",
|
|
94
|
+
"fsspec",
|
|
95
|
+
"kombu",
|
|
84
96
|
"omegaconf",
|
|
97
|
+
"polars",
|
|
98
|
+
"pyarrow",
|
|
85
99
|
"prometheus_client",
|
|
86
100
|
"pydantic",
|
|
87
101
|
"pyspark",
|
|
102
|
+
"redis",
|
|
88
103
|
"sqlalchemy",
|
|
104
|
+
"starlette",
|
|
89
105
|
"uvicorn",
|
|
90
106
|
]
|
|
91
107
|
|
|
92
108
|
|
|
93
|
-
def setup(app):
|
|
109
|
+
def setup(app: Any) -> None:
|
|
94
110
|
"""Register Sphinx hooks."""
|
|
95
111
|
app.connect("autodoc-skip-member", _skip_duplicate_reexports)
|