loom-kernel 0.2.1__tar.gz → 0.4.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.1 → loom_kernel-0.4.0}/.github/workflows/ci-pr.yml +1 -1
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/.github/workflows/release.yml +39 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/.gitignore +1 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/.readthedocs.yaml +6 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/CHANGELOG.md +85 -19
- loom_kernel-0.4.0/CHANGELOG_RELEASE.md +15 -0
- loom_kernel-0.2.1/README.md → loom_kernel-0.4.0/PKG-INFO +135 -2
- loom_kernel-0.2.1/PKG-INFO → loom_kernel-0.4.0/README.md +77 -37
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/conf.py +15 -3
- loom_kernel-0.4.0/docs/etl/examples.md +29 -0
- loom_kernel-0.4.0/docs/etl/pipelines.md +426 -0
- loom_kernel-0.4.0/docs/etl/testing.md +65 -0
- loom_kernel-0.4.0/docs/getting-started/etl.md +136 -0
- loom_kernel-0.4.0/docs/getting-started/rest.md +424 -0
- loom_kernel-0.4.0/docs/guides/etl.md +559 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/index.rst +17 -11
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/reference/api/core.rst +8 -0
- loom_kernel-0.4.0/docs/reference/api/etl.rst +50 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/reference/index.rst +1 -0
- loom_kernel-0.4.0/docs/rest/autocrud.md +166 -0
- loom_kernel-0.4.0/docs/rest/celery.md +538 -0
- loom_kernel-0.4.0/docs/rest/examples.md +642 -0
- loom_kernel-0.4.0/docs/rest/testing.md +67 -0
- loom_kernel-0.4.0/docs/rest/use-case-dsl.md +477 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/pyproject.toml +63 -2
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/config/__init__.py +2 -1
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/config/loader.py +149 -26
- loom_kernel-0.4.0/src/loom/core/config/resolver.py +82 -0
- loom_kernel-0.4.0/src/loom/etl/__init__.py +221 -0
- loom_kernel-0.4.0/src/loom/etl/backends/__init__.py +9 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_format_registry.py +37 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_historify/__init__.py +19 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_historify/_common.py +43 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_historify/_log.py +42 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_historify/_ops.py +90 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_historify/_snapshot.py +72 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_historify/_transform.py +97 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_merge.py +276 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_predicate.py +144 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_schema_aligner/__init__.py +6 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_schema_aligner/_aligner.py +23 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_schema_aligner/_policy.py +66 -0
- loom_kernel-0.4.0/src/loom/etl/backends/_write_policy.py +543 -0
- loom_kernel-0.4.0/src/loom/etl/backends/polars/__init__.py +14 -0
- loom_kernel-0.4.0/src/loom/etl/backends/polars/_dtype.py +257 -0
- loom_kernel-0.4.0/src/loom/etl/backends/polars/_file_writer.py +92 -0
- loom_kernel-0.4.0/src/loom/etl/backends/polars/_historify.py +192 -0
- loom_kernel-0.4.0/src/loom/etl/backends/polars/_predicate.py +102 -0
- loom_kernel-0.4.0/src/loom/etl/backends/polars/_reader.py +193 -0
- loom_kernel-0.4.0/src/loom/etl/backends/polars/_schema.py +180 -0
- loom_kernel-0.4.0/src/loom/etl/backends/polars/_schema_aligner.py +37 -0
- loom_kernel-0.4.0/src/loom/etl/backends/polars/_writer.py +456 -0
- loom_kernel-0.4.0/src/loom/etl/backends/polars/provider.py +138 -0
- loom_kernel-0.4.0/src/loom/etl/backends/spark/__init__.py +16 -0
- loom_kernel-0.4.0/src/loom/etl/backends/spark/_dtype.py +126 -0
- loom_kernel-0.4.0/src/loom/etl/backends/spark/_historify.py +227 -0
- loom_kernel-0.4.0/src/loom/etl/backends/spark/_reader.py +196 -0
- loom_kernel-0.4.0/src/loom/etl/backends/spark/_schema.py +41 -0
- loom_kernel-0.4.0/src/loom/etl/backends/spark/_schema_aligner.py +40 -0
- loom_kernel-0.4.0/src/loom/etl/backends/spark/_writer.py +517 -0
- loom_kernel-0.4.0/src/loom/etl/backends/spark/provider.py +79 -0
- loom_kernel-0.4.0/src/loom/etl/checkpoint/__init__.py +15 -0
- loom_kernel-0.4.0/src/loom/etl/checkpoint/_backends/_polars.py +106 -0
- loom_kernel-0.4.0/src/loom/etl/checkpoint/_backends/_spark.py +135 -0
- loom_kernel-0.4.0/src/loom/etl/checkpoint/_cleaners.py +64 -0
- loom_kernel-0.4.0/src/loom/etl/checkpoint/_paths.py +52 -0
- loom_kernel-0.4.0/src/loom/etl/checkpoint/_scope.py +35 -0
- loom_kernel-0.4.0/src/loom/etl/checkpoint/_store.py +234 -0
- loom_kernel-0.4.0/src/loom/etl/compiler/__init__.py +48 -0
- loom_kernel-0.4.0/src/loom/etl/compiler/_binding.py +111 -0
- loom_kernel-0.4.0/src/loom/etl/compiler/_compiler.py +268 -0
- loom_kernel-0.4.0/src/loom/etl/compiler/_errors.py +316 -0
- loom_kernel-0.4.0/src/loom/etl/compiler/_plan.py +206 -0
- loom_kernel-0.4.0/src/loom/etl/compiler/_validators.py +43 -0
- loom_kernel-0.4.0/src/loom/etl/compiler/_validators_plan.py +267 -0
- loom_kernel-0.4.0/src/loom/etl/compiler/_validators_step.py +473 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/__init__.py +80 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/_format.py +21 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/_read_options.py +91 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/_utils.py +18 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/_write_options.py +111 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/expr/__init__.py +50 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/expr/_params.py +61 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/expr/_predicate.py +174 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/expr/_predicate_dialect.py +160 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/expr/_refs.py +122 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/source/__init__.py +43 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/source/_from.py +569 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/source/_specs.py +149 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/__init__.py +111 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/_file.py +34 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/__init__.py +30 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/_builder.py +241 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/_enums.py +58 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/_errors.py +78 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/_report.py +27 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/_history/_spec.py +69 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/_into.py +453 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/_schema_mode.py +23 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/_table.py +103 -0
- loom_kernel-0.4.0/src/loom/etl/declarative/target/_temp.py +43 -0
- loom_kernel-0.4.0/src/loom/etl/executor/__init__.py +61 -0
- loom_kernel-0.4.0/src/loom/etl/executor/_dispatcher.py +94 -0
- loom_kernel-0.4.0/src/loom/etl/executor/_executor.py +357 -0
- loom_kernel-0.4.0/src/loom/etl/observability/__init__.py +59 -0
- loom_kernel-0.4.0/src/loom/etl/observability/config.py +106 -0
- loom_kernel-0.4.0/src/loom/etl/observability/factory.py +52 -0
- loom_kernel-0.4.0/src/loom/etl/observability/observers/__init__.py +13 -0
- loom_kernel-0.4.0/src/loom/etl/observability/observers/_labels.py +57 -0
- loom_kernel-0.4.0/src/loom/etl/observability/observers/composite.py +62 -0
- loom_kernel-0.4.0/src/loom/etl/observability/observers/noop.py +36 -0
- loom_kernel-0.4.0/src/loom/etl/observability/observers/otel.py +263 -0
- loom_kernel-0.4.0/src/loom/etl/observability/observers/protocol.py +37 -0
- loom_kernel-0.4.0/src/loom/etl/observability/observers/structlog.py +100 -0
- loom_kernel-0.4.0/src/loom/etl/observability/recording/__init__.py +5 -0
- loom_kernel-0.4.0/src/loom/etl/observability/recording/_recorder.py +225 -0
- loom_kernel-0.4.0/src/loom/etl/observability/records.py +241 -0
- loom_kernel-0.4.0/src/loom/etl/observability/sinks/__init__.py +17 -0
- loom_kernel-0.4.0/src/loom/etl/observability/sinks/_protocol.py +44 -0
- loom_kernel-0.4.0/src/loom/etl/observability/sinks/_table.py +42 -0
- loom_kernel-0.4.0/src/loom/etl/observability/sinks/_writer.py +26 -0
- loom_kernel-0.4.0/src/loom/etl/pipeline/__init__.py +12 -0
- loom_kernel-0.4.0/src/loom/etl/pipeline/_generics.py +31 -0
- loom_kernel-0.4.0/src/loom/etl/pipeline/_params.py +27 -0
- loom_kernel-0.4.0/src/loom/etl/pipeline/_pipeline.py +62 -0
- loom_kernel-0.4.0/src/loom/etl/pipeline/_process.py +64 -0
- loom_kernel-0.4.0/src/loom/etl/pipeline/_sql.py +55 -0
- loom_kernel-0.4.0/src/loom/etl/pipeline/_step.py +154 -0
- loom_kernel-0.4.0/src/loom/etl/pipeline/_step_sql.py +91 -0
- loom_kernel-0.4.0/src/loom/etl/runner/__init__.py +6 -0
- loom_kernel-0.4.0/src/loom/etl/runner/_providers.py +64 -0
- loom_kernel-0.4.0/src/loom/etl/runner/_wiring.py +112 -0
- loom_kernel-0.4.0/src/loom/etl/runner/config_loader.py +45 -0
- loom_kernel-0.4.0/src/loom/etl/runner/core.py +166 -0
- loom_kernel-0.4.0/src/loom/etl/runner/errors.py +17 -0
- loom_kernel-0.4.0/src/loom/etl/runner/filtering.py +107 -0
- loom_kernel-0.4.0/src/loom/etl/runtime/__init__.py +5 -0
- loom_kernel-0.4.0/src/loom/etl/runtime/contracts.py +128 -0
- loom_kernel-0.4.0/src/loom/etl/schema/__init__.py +46 -0
- loom_kernel-0.4.0/src/loom/etl/schema/_contract.py +220 -0
- loom_kernel-0.4.0/src/loom/etl/schema/_schema.py +334 -0
- loom_kernel-0.4.0/src/loom/etl/storage/__init__.py +60 -0
- loom_kernel-0.4.0/src/loom/etl/storage/_config.py +373 -0
- loom_kernel-0.4.0/src/loom/etl/storage/_file_locator.py +146 -0
- loom_kernel-0.4.0/src/loom/etl/storage/_locator.py +253 -0
- loom_kernel-0.4.0/src/loom/etl/storage/routing.py +230 -0
- loom_kernel-0.4.0/src/loom/etl/testing/__init__.py +58 -0
- loom_kernel-0.4.0/src/loom/etl/testing/_result.py +88 -0
- loom_kernel-0.4.0/src/loom/etl/testing/_runners.py +142 -0
- loom_kernel-0.4.0/src/loom/etl/testing/_scenario.py +79 -0
- loom_kernel-0.4.0/src/loom/etl/testing/_stubs.py +212 -0
- loom_kernel-0.4.0/src/loom/etl/testing/spark.py +324 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/conftest.py +34 -0
- loom_kernel-0.4.0/tests/integration/etl/__init__.py +1 -0
- loom_kernel-0.4.0/tests/integration/etl/test_runner_integration.py +241 -0
- loom_kernel-0.4.0/tests/integration/etl/test_runtime_contracts.py +455 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/config/test_config.py +98 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/_historify_contract.py +885 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_historify_common.py +52 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/conftest.py +175 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_apply_schema.py +90 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_backend.py +390 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_dtype.py +137 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_file_writer.py +71 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_historify_polars.py +212 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_predicate_pushdown.py +160 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_reader_columns.py +162 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_reader_json_columns.py +199 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_step_execution.py +223 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_upsert_writer.py +209 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_polars/test_writer_to_frame.py +75 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_spark/conftest.py +89 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_spark/test_dtype.py +104 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_spark/test_historify_spark.py +238 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_spark/test_spark_apply_schema.py +215 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_spark/test_step_execution.py +404 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_spark/test_writer_to_frame.py +102 -0
- loom_kernel-0.4.0/tests/unit/etl/backends/test_write_policy_historify.py +283 -0
- loom_kernel-0.4.0/tests/unit/etl/checkpoint/__init__.py +0 -0
- loom_kernel-0.4.0/tests/unit/etl/checkpoint/backends/test_checkpoint_polars.py +33 -0
- loom_kernel-0.4.0/tests/unit/etl/checkpoint/test_checkpoint_paths.py +61 -0
- loom_kernel-0.4.0/tests/unit/etl/checkpoint/test_cleaners.py +81 -0
- loom_kernel-0.4.0/tests/unit/etl/checkpoint/test_store.py +248 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/__init__.py +0 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_catalog_validator.py +92 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_compiler.py +502 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_compiler_catalog.py +132 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_compiler_upsert.py +133 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_errors.py +223 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_errors_additional_factories.py +76 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_errors_runtime_factories.py +159 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_historify_validator.py +432 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_param_exprs_validator.py +150 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_plan_traversal.py +207 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_step_validator.py +81 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_structural.py +135 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_temp_validator.py +205 -0
- loom_kernel-0.4.0/tests/unit/etl/compiler/test_upsert_validator.py +125 -0
- loom_kernel-0.4.0/tests/unit/etl/conftest.py +40 -0
- loom_kernel-0.4.0/tests/unit/etl/io/__init__.py +0 -0
- loom_kernel-0.4.0/tests/unit/etl/io/test_history_target.py +739 -0
- loom_kernel-0.4.0/tests/unit/etl/io/test_source.py +263 -0
- loom_kernel-0.4.0/tests/unit/etl/io/test_source_json.py +236 -0
- loom_kernel-0.4.0/tests/unit/etl/io/test_source_options.py +178 -0
- loom_kernel-0.4.0/tests/unit/etl/io/test_target.py +225 -0
- loom_kernel-0.4.0/tests/unit/etl/io/test_utils.py +32 -0
- loom_kernel-0.4.0/tests/unit/etl/io/test_variants.py +125 -0
- loom_kernel-0.4.0/tests/unit/etl/pipeline/__init__.py +1 -0
- loom_kernel-0.4.0/tests/unit/etl/pipeline/test_pipeline_process.py +67 -0
- loom_kernel-0.4.0/tests/unit/etl/pipeline/test_proxy.py +90 -0
- loom_kernel-0.4.0/tests/unit/etl/pipeline/test_step.py +132 -0
- loom_kernel-0.4.0/tests/unit/etl/schema/__init__.py +0 -0
- loom_kernel-0.4.0/tests/unit/etl/schema/test_contract.py +249 -0
- loom_kernel-0.4.0/tests/unit/etl/schema/test_schema.py +181 -0
- loom_kernel-0.4.0/tests/unit/etl/schema/test_table.py +63 -0
- loom_kernel-0.4.0/tests/unit/etl/sql/__init__.py +0 -0
- loom_kernel-0.4.0/tests/unit/etl/sql/test_merge.py +214 -0
- loom_kernel-0.4.0/tests/unit/etl/sql/test_predicate.py +99 -0
- loom_kernel-0.4.0/tests/unit/etl/sql/test_predicate_dialect.py +98 -0
- loom_kernel-0.4.0/tests/unit/etl/sql/test_sql_runtime.py +172 -0
- loom_kernel-0.4.0/tests/unit/etl/storage/__init__.py +0 -0
- loom_kernel-0.4.0/tests/unit/etl/storage/test_backend_factory.py +426 -0
- loom_kernel-0.4.0/tests/unit/etl/storage/test_io_protocols.py +101 -0
- loom_kernel-0.4.0/tests/unit/etl/storage/test_locator.py +87 -0
- loom_kernel-0.4.0/tests/unit/etl/storage/test_observability_and_protocols.py +149 -0
- loom_kernel-0.4.0/tests/unit/etl/storage/test_route_build.py +146 -0
- loom_kernel-0.4.0/tests/unit/etl/storage/test_schema_readers.py +91 -0
- loom_kernel-0.4.0/tests/unit/etl/storage/test_storage_config.py +341 -0
- loom_kernel-0.4.0/tests/unit/etl/test_config_loader.py +85 -0
- loom_kernel-0.4.0/tests/unit/etl/test_executor.py +317 -0
- loom_kernel-0.4.0/tests/unit/etl/test_format_registry.py +30 -0
- loom_kernel-0.4.0/tests/unit/etl/test_module_contracts.py +422 -0
- loom_kernel-0.4.0/tests/unit/etl/test_observer.py +351 -0
- loom_kernel-0.4.0/tests/unit/etl/test_observer_internals.py +448 -0
- loom_kernel-0.4.0/tests/unit/etl/test_public_api_discovery.py +57 -0
- loom_kernel-0.4.0/tests/unit/etl/test_record_schema_coverage.py +65 -0
- loom_kernel-0.4.0/tests/unit/etl/test_runner.py +300 -0
- loom_kernel-0.4.0/tests/unit/etl/test_runner_errors.py +19 -0
- loom_kernel-0.4.0/tests/unit/etl/test_spark_testing.py +78 -0
- loom_kernel-0.4.0/tests/unit/etl/testing/test_runners.py +146 -0
- loom_kernel-0.4.0/tests/unit/etl/testing/test_scenario_and_stubs.py +106 -0
- loom_kernel-0.4.0/tests/unit/etl/testing/test_spark_helpers.py +167 -0
- loom_kernel-0.4.0/tests/unit/prometheus/__init__.py +0 -0
- loom_kernel-0.4.0/tests/unit/rest/__init__.py +0 -0
- loom_kernel-0.4.0/tests/unit/testing/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/uv.lock +638 -5
- loom_kernel-0.2.1/CHANGELOG_RELEASE.md +0 -39
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/.github/workflows/ci-main.yml +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/.github/workflows/docs.yml +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/.pre-commit-config.yaml +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/LICENSE +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/Makefile +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/codecov.yml +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/_static/.gitkeep +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/_static/custom.css +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/_static/logo-transparent.png +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/_static/logo.svg +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/architecture/adr/README.md +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/architecture/clean-architecture.md +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/architecture/overview.md +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/examples-repo/index.md +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/guides/autocrud.md +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/guides/celery.md +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/guides/fake-repo-examples.md +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/guides/quickstart.md +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/guides/use-case-dsl.md +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/reference/api/repository.rst +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/reference/api/rest.rst +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/reference/api/testing.rst +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/docs/requirements.txt +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/sonar-project.properties +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/celery/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/celery/auto.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/celery/bootstrap.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/celery/config.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/celery/constants.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/celery/event_loop.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/celery/runner.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/celery/service.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/backend/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/backend/core_model.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/backend/protocol.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/backend/sqlalchemy.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/bootstrap/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/bootstrap/kernel.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/abc/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/abc/backend.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/abc/config.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/abc/dependency.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/codec.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/decorators.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/dependency.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/gateway.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/keys.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/repository.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/cache/serializer.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/command/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/command/adapter.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/command/base.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/command/field.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/command/introspection.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/config/errors.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/config/keys.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/config/model.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/contracts/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/contracts/manifest.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/di/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/di/container.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/di/scope.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/discovery/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/discovery/_utils.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/discovery/base.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/discovery/interfaces.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/discovery/manifest.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/discovery/modules.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/engine/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/engine/compilable.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/engine/compiler.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/engine/events.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/engine/executor.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/engine/metrics.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/engine/plan.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/errors/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/errors/codes.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/errors/errors.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/job/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/job/callback.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/job/context.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/job/handle.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/job/job.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/job/service.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/logger/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/logger/abc.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/logger/config.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/logger/registry.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/logger/structlogger.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/model/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/model/base.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/model/enums.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/model/field.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/model/introspection.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/model/projection.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/model/relation.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/model/struct.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/model/timestamped.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/model/types.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/model/types_postgres.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/projection/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/projection/loaders.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/projection/runtime.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/abc/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/abc/query.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/abc/repo_for.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/abc/repository.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/mutation.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/registration.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/registry.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/response/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/response/base.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/tracing/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/tracing/context.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/transport/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/transport/adapter.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/uow/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/uow/abc.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/uow/context.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/_predicates.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/compute.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/constants.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/factory.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/field_ref.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/invoker.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/keys.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/markers.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/registry.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/rule.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/core/use_case/use_case.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/prometheus/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/prometheus/adapter.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/prometheus/middleware.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/adapter.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/autocrud.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/compiler.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/constants.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/errors.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/fastapi/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/fastapi/app.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/fastapi/auto.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/fastapi/openapi.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/fastapi/response.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/middleware.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/model.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/rest/rest_adapter.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/testing/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/testing/golden.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/testing/http_harness.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/testing/in_memory.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/testing/repository_harness.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/src/loom/testing/runner.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/golden/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/golden/baselines/.gitkeep +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/golden/outputs/.gitkeep +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/golden/plans/.gitkeep +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/helpers/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/celery_bootstrap/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/celery_bootstrap/config/conf.celery.integration.yaml +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/celery_bootstrap/test_auto_create_app_integration.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/celery_bootstrap/test_bootstrap_worker.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/conftest.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/core/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/core/repository/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/core/repository/sqlalchemy/conftest.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/core/repository/sqlalchemy/test_cache_integration.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/core/repository/sqlalchemy/test_repository_integration.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/core/rest/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/core/rest/test_auto_interface_integration.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/core/rest/test_fastapi_app_integration.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/core/use_case/test_custom_repository_integration.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/core/use_case/test_use_case_crud_integration.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/config/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/config/conf.interfaces.yaml +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/config/conf.manifest.yaml +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/config/conf.modules.yaml +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/config/conf.yaml +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/main.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/manifest.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/category/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/category/model.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/category/schemas.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/interface.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/jobs.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/model.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/relations.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/repository.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/repository_contract.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/review/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/review/model.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/review/schemas.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/schemas.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/fake_repo/product/use_cases.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/support/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/integration/support/logical_repo_fixtures.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/celery_bootstrap/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/celery_bootstrap/test_bootstrap.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/celery_bootstrap/test_event_loop.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/celery_jobs/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/celery_jobs/test_auto.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/celery_jobs/test_celery_service.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/celery_jobs/test_config.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/celery_jobs/test_runner.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/backend/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/backend/test_backend_compiler.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/bootstrap/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/bootstrap/test_bootstrap.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/bootstrap/test_bootstrap_metrics.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/bootstrap/test_kernel.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/cache/test_cached_repository.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/command/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/command/test_command_base.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/command/test_command_field.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/command/test_command_patch.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/command/test_introspection.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/config/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/di/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/di/test_container.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/discovery/test_manifest.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/engine/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/engine/test_compiler.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/engine/test_executor.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/engine/test_executor_trace.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/engine/test_executor_uow.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/engine/test_metrics.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/engine/test_plan.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/errors/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/errors/test_errors.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/job/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/job/conftest.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/job/test_callback.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/job/test_context.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/job/test_handle.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/job/test_inline_service.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/job/test_job.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/logger/test_registry.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/model/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/model/test_model.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/model/test_struct.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/model/test_timestamped.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/projection/test_runtime.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/repository/abc/conftest.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/repository/abc/test_query.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/repository/abc/test_repository_contract.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/repository/sqlalchemy/conftest.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/repository/sqlalchemy/test_loaders.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/repository/sqlalchemy/test_repository.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/repository/sqlalchemy/test_transactional.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/tracing/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/tracing/test_context.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/uow/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/uow/test_executor_uow.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/uow/test_sqlalchemy_uow.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/uow/test_uow_protocols.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/use_case/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_compute.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_factory.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_field_ref.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_invoker.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_markers.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_rule.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/core/use_case/test_use_case.py +0 -0
- {loom_kernel-0.2.1/tests/unit/prometheus → loom_kernel-0.4.0/tests/unit/etl}/__init__.py +0 -0
- {loom_kernel-0.2.1/tests/unit/rest → loom_kernel-0.4.0/tests/unit/etl/backends/test_polars}/__init__.py +0 -0
- {loom_kernel-0.2.1/tests/unit/testing → loom_kernel-0.4.0/tests/unit/etl/backends/test_spark}/__init__.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/prometheus/test_adapter.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/prometheus/test_middleware.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/rest/test_autocrud.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/rest/test_fastapi_auto_logger.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/rest/test_middleware.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/rest/test_pydantic_adapter.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/rest/test_response.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/rest/test_rest_adapter.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/rest/test_rest_compiler.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/rest/test_rest_model.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/rest/test_router_runtime.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/testing/test_golden.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/testing/test_http_harness.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/testing/test_in_memory.py +0 -0
- {loom_kernel-0.2.1 → loom_kernel-0.4.0}/tests/unit/testing/test_runner.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,43 @@ 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
|
+
HEADER=$(head -1 CHANGELOG_RELEASE.md)
|
|
106
|
+
if ! grep -qF "${HEADER}" CHANGELOG.md; then
|
|
107
|
+
cat CHANGELOG_RELEASE.md CHANGELOG.md > CHANGELOG_MERGED.md
|
|
108
|
+
mv CHANGELOG_MERGED.md CHANGELOG.md
|
|
109
|
+
fi
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
git add pyproject.toml CHANGELOG.md
|
|
113
|
+
git diff --staged --quiet && exit 0
|
|
114
|
+
git commit -m "chore(release): bump version to ${VERSION}"
|
|
115
|
+
git push origin "${BRANCH}" --force
|
|
116
|
+
|
|
117
|
+
if ! gh pr list --head "${BRANCH}" --state open --json number --jq '.[0].number' | grep -qE '^[0-9]+$'; then
|
|
118
|
+
gh pr create \
|
|
119
|
+
--title "chore(release): bump version to ${VERSION}" \
|
|
120
|
+
--body "Automated version bump and changelog update after release v${VERSION}." \
|
|
121
|
+
--base master \
|
|
122
|
+
--head "${BRANCH}"
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
gh pr merge "${BRANCH}" --squash --auto --delete-branch
|
|
126
|
+
|
|
88
127
|
- name: Build package
|
|
89
128
|
if: ${{ steps.version.outputs.deploy == 'true' }}
|
|
90
129
|
shell: bash
|
|
@@ -1,43 +1,109 @@
|
|
|
1
|
-
# 🚀 Release 0.
|
|
1
|
+
# 🚀 Release 0.4.0 ([#18](https://github.com/the-reacher-data/loom-py/pull/18)) ([`09e5aa3`](https://github.com/the-reacher-data/loom-py/commit/09e5aa340f88e0488daca2bf10320aad7aebbe1d))
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
## ✨ Features
|
|
5
|
-
###
|
|
6
|
-
- **
|
|
5
|
+
### etl
|
|
6
|
+
- **etl:** add IntoHistory builder and SCD Type 2 domain contracts
|
|
7
7
|
|
|
8
|
-
### repository
|
|
9
|
-
- **repository:** generalize main repo registration for loom structs
|
|
10
8
|
|
|
11
9
|
|
|
12
|
-
## 🐛 Fixes
|
|
13
|
-
### rest
|
|
14
|
-
- **rest:** serialize pagination envelopes in camel case
|
|
15
|
-
- **rest:** support loom structs in autocrud tests
|
|
16
10
|
|
|
17
|
-
### prometheus
|
|
18
|
-
- **prometheus:** expose metrics at exact path
|
|
19
11
|
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# 🚀 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))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## ✨ Features
|
|
22
|
+
### config
|
|
23
|
+
- **config:** add cloud URI support and pluggable resolver extension point<br>
|
|
24
|
+
> Add fsspec as a hard dependency of loom[config]
|
|
25
|
+
> load_config() now accepts s3://, gs://, abfss://, r2:// URIs via fsspec
|
|
26
|
+
> Add ConfigResolver protocol for pluggable ${prefix:key} resolution at
|
|
27
|
+
> parse time (enables SSM, Key Vault, etc. without baking secrets into images)
|
|
28
|
+
> Resolver registration is idempotent; resolvers are evaluated at job startup
|
|
29
|
+
> so secret rotation takes effect on the next run
|
|
30
|
+
> Migrate loom.etl.runner.config_loader to use core load_config, removing
|
|
31
|
+
> the parallel OmegaConf implementation
|
|
32
|
+
> ETL _load_yaml inherits cloud URI and resolver support transparently
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### etl
|
|
36
|
+
- **etl:** add FileLocator with explicit alias API for file routes<br>
|
|
37
|
+
> Introduces `FileLocator` protocol and `MappingFileLocator` so that
|
|
38
|
+
> `FromFile.alias("name")` / `IntoFile.alias("name")` specs resolve at
|
|
39
|
+
> runtime through `storage.files` config rather than hard-coded URIs.
|
|
40
|
+
> `FileLocation` / `FileLocator` / `MappingFileLocator` in `storage/_file_locator.py`
|
|
41
|
+
> `StorageConfig.to_file_locator()` returns `MappingFileLocator | None`
|
|
42
|
+
> (None when `files` is empty — no conditional needed at call sites)
|
|
43
|
+
> `FromFile.alias()` / `IntoFile.alias()` classmethods set `is_alias=True`
|
|
44
|
+
> on the emitted spec
|
|
45
|
+
> `is_alias: bool` added to `FileSourceSpec` and `FileSpec`
|
|
46
|
+
> Polars and Spark backends resolve aliases via injected `file_locator`
|
|
47
|
+
> Both providers wired: `file_locator = config.to_file_locator()`
|
|
48
|
+
> Full test coverage across io, storage, and backend layers
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## 🐛 Fixes
|
|
53
|
+
### observability
|
|
54
|
+
- **observability:** honor missing table policy for record store writers
|
|
22
55
|
|
|
23
56
|
|
|
24
57
|
## 📖 Documentation
|
|
25
|
-
###
|
|
26
|
-
- **
|
|
58
|
+
### etl
|
|
59
|
+
- **etl:** keep only user guide and drop refactor docs
|
|
60
|
+
- **etl:** expand ETL documentation and update directory table<br>
|
|
61
|
+
> Add dummy-loom-etl companion repo link in README and etl guide
|
|
62
|
+
> Expand README subpaths table with loom.etl and loom.core.config entries
|
|
63
|
+
> Add FileLocator/alias API, cloud config URI, and ConfigResolver sections to etl guide
|
|
64
|
+
> Add loom.etl.backends (polars + spark) to etl.rst API reference
|
|
65
|
+
> Add loom.core.config to core.rst API reference
|
|
66
|
+
|
|
27
67
|
|
|
28
68
|
|
|
29
69
|
|
|
30
70
|
## ♻️ Refactor
|
|
31
|
-
###
|
|
32
|
-
- **
|
|
33
|
-
|
|
34
|
-
|
|
71
|
+
### stepsql
|
|
72
|
+
- **stepsql:** delegate SQL execution to backend readers
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
35
77
|
|
|
78
|
+
# 🚀 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))
|
|
36
79
|
|
|
80
|
+
## ✨ Features
|
|
37
81
|
|
|
82
|
+
### logger
|
|
83
|
+
- **logger:** support per-logger levels from config<br>
|
|
84
|
+
> `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.
|
|
85
|
+
|
|
86
|
+
### repository
|
|
87
|
+
- **repository:** generalize main repo registration for loom structs<br>
|
|
88
|
+
> `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.
|
|
38
89
|
|
|
90
|
+
## 🐛 Bug Fixes
|
|
91
|
+
|
|
92
|
+
### rest
|
|
93
|
+
- **rest:** serialize pagination envelopes in camel case<br>
|
|
94
|
+
> `PageResult` and list-envelope responses were serialized in snake_case. All envelope fields now follow the camelCase contract of the HTTP layer.
|
|
95
|
+
- **rest:** support loom structs in autocrud tests<br>
|
|
96
|
+
> Auto-CRUD route generation was not exercising the `msgspec.Struct` code path in integration tests.
|
|
97
|
+
|
|
98
|
+
### prometheus
|
|
99
|
+
- **prometheus:** expose metrics at exact path<br>
|
|
100
|
+
> Metrics endpoint was registered with a trailing-slash variant that did not match the documented `/metrics` path.
|
|
39
101
|
|
|
102
|
+
### docs
|
|
103
|
+
- **docs:** fix RTD build failure, logo and docs examples (#10, #11)<br>
|
|
104
|
+
> 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.
|
|
40
105
|
|
|
106
|
+
---
|
|
41
107
|
|
|
42
108
|
# 🚀 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))
|
|
43
109
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 🚀 Release 0.4.0 ([#18](https://github.com/the-reacher-data/loom-py/pull/18)) ([`09e5aa3`](https://github.com/the-reacher-data/loom-py/commit/09e5aa340f88e0488daca2bf10320aad7aebbe1d))
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## ✨ Features
|
|
5
|
+
### etl
|
|
6
|
+
- **etl:** add IntoHistory builder and SCD Type 2 domain contracts
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
@@ -1,3 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: loom-kernel
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Loom Python project
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Requires-Dist: aiocache<1.0,>=0.12
|
|
8
|
+
Requires-Dist: msgspec<1.0,>=0.18
|
|
9
|
+
Requires-Dist: omegaconf<3.0,>=2.3
|
|
10
|
+
Requires-Dist: prometheus-client>=0.20
|
|
11
|
+
Requires-Dist: structlog<26.0,>=24.4
|
|
12
|
+
Provides-Extra: cache
|
|
13
|
+
Requires-Dist: aiocache<1.0,>=0.12; extra == 'cache'
|
|
14
|
+
Requires-Dist: omegaconf<3.0,>=2.3; extra == 'cache'
|
|
15
|
+
Provides-Extra: celery
|
|
16
|
+
Requires-Dist: celery<6.0,>=5.3; extra == 'celery'
|
|
17
|
+
Requires-Dist: kombu<6.0,>=5.3; extra == 'celery'
|
|
18
|
+
Requires-Dist: redis<6.0,>=5.0; extra == 'celery'
|
|
19
|
+
Provides-Extra: config
|
|
20
|
+
Requires-Dist: fsspec>=2024.2.0; extra == 'config'
|
|
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'
|
|
44
|
+
Provides-Extra: prometheus
|
|
45
|
+
Requires-Dist: prometheus-client>=0.20; extra == 'prometheus'
|
|
46
|
+
Provides-Extra: pyspark
|
|
47
|
+
Requires-Dist: pyspark<4.0,>=3.5; extra == 'pyspark'
|
|
48
|
+
Provides-Extra: rest
|
|
49
|
+
Requires-Dist: fastapi<1.0,>=0.115; extra == 'rest'
|
|
50
|
+
Requires-Dist: httptools<1.0,>=0.6; extra == 'rest'
|
|
51
|
+
Requires-Dist: prometheus-client>=0.20; extra == 'rest'
|
|
52
|
+
Requires-Dist: pydantic<3.0,>=2.0; extra == 'rest'
|
|
53
|
+
Requires-Dist: uvicorn<1.0,>=0.30; extra == 'rest'
|
|
54
|
+
Requires-Dist: uvloop<1.0,>=0.21; (sys_platform != 'win32') and extra == 'rest'
|
|
55
|
+
Provides-Extra: sqlalchemy
|
|
56
|
+
Requires-Dist: sqlalchemy<3.0,>=2.0; extra == 'sqlalchemy'
|
|
57
|
+
Description-Content-Type: text/markdown
|
|
58
|
+
|
|
1
59
|
<p align="center">
|
|
2
60
|
<img src="docs/_static/logo-transparent.png" alt="loom-kernel" width="160" style="background:#ffffff;border-radius:6px;padding:8px 20px;" />
|
|
3
61
|
</p>
|
|
@@ -20,7 +78,8 @@ Framework-agnostic Python toolkit to build backend applications with:
|
|
|
20
78
|
- repositories decoupled from infrastructure
|
|
21
79
|
- REST/FastAPI adapters with OpenAPI generation
|
|
22
80
|
- background jobs and Celery workers, first-class
|
|
23
|
-
-
|
|
81
|
+
- **declarative ETL** — compile-time-validated pipelines for Polars and Spark
|
|
82
|
+
- testing utilities for business workflows and ETL steps
|
|
24
83
|
|
|
25
84
|
## Purpose
|
|
26
85
|
|
|
@@ -35,7 +94,8 @@ infrastructure (DB, cache, transport) without breaking business logic.
|
|
|
35
94
|
|
|
36
95
|
- Usage guides and architecture docs are available in the `docs/` site.
|
|
37
96
|
- API reference is autogenerated from public docstrings.
|
|
38
|
-
- End-to-end demo
|
|
97
|
+
- End-to-end REST demo: [`dummy-loom`](https://github.com/the-reacher-data/dummy-loom).
|
|
98
|
+
- End-to-end ETL demo: [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl) — full Polars and Spark pipeline examples.
|
|
39
99
|
|
|
40
100
|
## Main subpaths
|
|
41
101
|
|
|
@@ -47,10 +107,23 @@ infrastructure (DB, cache, transport) without breaking business logic.
|
|
|
47
107
|
| `src/loom/core/repository/sqlalchemy` | Concrete async SQLAlchemy repository implementation. |
|
|
48
108
|
| `src/loom/core/model` | Base model, fields, relations, and entity introspection. |
|
|
49
109
|
| `src/loom/core/cache` | Decorators and cached repository with dependency invalidation. |
|
|
110
|
+
| `src/loom/core/config` | YAML config loader with cloud URI support and pluggable resolvers. |
|
|
50
111
|
| `src/loom/rest` | Framework-agnostic REST model and route compiler. |
|
|
51
112
|
| `src/loom/rest/fastapi` | Direct FastAPI integration (auto wiring and runtime router). |
|
|
52
113
|
| `src/loom/prometheus` | Middleware and adapter for runtime metrics. |
|
|
53
114
|
| `src/loom/testing` | Harnesses for unit/integration tests and golden tests. |
|
|
115
|
+
| `src/loom/etl` | Declarative ETL subsystem — pipelines, Polars/Spark backends, observability. |
|
|
116
|
+
| `src/loom/etl/pipeline` | `ETLStep`, `ETLProcess`, `ETLPipeline`, `StepSQL`, and `ETLParams`. |
|
|
117
|
+
| `src/loom/etl/declarative` | `FromTable`, `FromFile`, `IntoTable`, `IntoFile`, predicate DSL, and `params` proxy. |
|
|
118
|
+
| `src/loom/etl/schema` | Backend-agnostic schema model (`LoomDtype`, `ColumnSchema`, `TableRef`). |
|
|
119
|
+
| `src/loom/etl/storage` | Storage config, table/file locators, and route resolution. |
|
|
120
|
+
| `src/loom/etl/compiler` | Compile-time validation and execution plan builder. |
|
|
121
|
+
| `src/loom/etl/runner` | `ETLRunner` entry point and YAML config loader. |
|
|
122
|
+
| `src/loom/etl/checkpoint` | Step-level checkpoint store for incremental re-runs. |
|
|
123
|
+
| `src/loom/etl/observability` | Run/step observers, OTEL sink, structlog sink, and execution records. |
|
|
124
|
+
| `src/loom/etl/backends/polars` | Polars + Delta Lake reader, writer, and schema aligner. |
|
|
125
|
+
| `src/loom/etl/backends/spark` | Spark + Delta reader, writer, and schema aligner. |
|
|
126
|
+
| `src/loom/etl/testing` | `PolarsStepRunner`, `SparkStepRunner`, `ETLScenario`, and test stubs. |
|
|
54
127
|
|
|
55
128
|
## Quick start
|
|
56
129
|
|
|
@@ -380,6 +453,66 @@ For deeper references, review the integration examples under
|
|
|
380
453
|
For a runnable full-stack sample with all patterns combined, check the companion repository
|
|
381
454
|
[`dummy-loom`](https://github.com/the-reacher-data/dummy-loom).
|
|
382
455
|
|
|
456
|
+
## ETL quick start
|
|
457
|
+
|
|
458
|
+
Install a backend:
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
pip install "loom-kernel[etl-polars]"
|
|
462
|
+
# or
|
|
463
|
+
pip install "loom-kernel[etl-spark]"
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Declare a pipeline — sources, targets, and transformation logic are explicit and compile-time validated:
|
|
467
|
+
|
|
468
|
+
```python
|
|
469
|
+
from datetime import date
|
|
470
|
+
import polars as pl
|
|
471
|
+
from loom.etl import ETLParams, ETLStep, ETLProcess, ETLPipeline, ETLRunner, FromTable, IntoTable
|
|
472
|
+
|
|
473
|
+
class DailyParams(ETLParams):
|
|
474
|
+
run_date: date
|
|
475
|
+
|
|
476
|
+
class CleanOrders(ETLStep[DailyParams]):
|
|
477
|
+
orders = FromTable("raw.orders").columns("id", "amount", "run_date")
|
|
478
|
+
target = IntoTable("staging.orders").replace()
|
|
479
|
+
|
|
480
|
+
def execute(self, params: DailyParams, *, orders: pl.LazyFrame) -> pl.LazyFrame:
|
|
481
|
+
return orders.filter(pl.col("amount") > 0)
|
|
482
|
+
|
|
483
|
+
class DailyProcess(ETLProcess[DailyParams]):
|
|
484
|
+
steps = [CleanOrders]
|
|
485
|
+
|
|
486
|
+
class DailyPipeline(ETLPipeline[DailyParams]):
|
|
487
|
+
processes = [DailyProcess]
|
|
488
|
+
|
|
489
|
+
runner = ETLRunner.from_yaml("config/etl.yaml")
|
|
490
|
+
runner.run(DailyPipeline, DailyParams(run_date=date.today()))
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
Write modes — `replace`, `append`, `replace_partition`, `replace_partitions`, `replace_where`, `upsert` — are declared on the target, validated at compile time. Partition predicates use the `params` proxy so no values are hard-coded:
|
|
494
|
+
|
|
495
|
+
```python
|
|
496
|
+
from loom.etl import params
|
|
497
|
+
|
|
498
|
+
target = IntoTable("staging.orders").replace_partition(
|
|
499
|
+
year=params.run_date.year,
|
|
500
|
+
month=params.run_date.month,
|
|
501
|
+
)
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
File aliases decouple paths from pipelines — declare once in YAML, reference by name:
|
|
505
|
+
|
|
506
|
+
```python
|
|
507
|
+
events = FromFile.alias("events_raw", format=Format.CSV)
|
|
508
|
+
target = IntoFile.alias("exports_daily", format=Format.PARQUET)
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
For a full Polars + Spark + Delta Lake example see [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl).
|
|
512
|
+
For the complete API reference and write-mode guide see the [ETL docs](https://loom-py.readthedocs.io/en/latest/guides/etl.html).
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
383
516
|
## Performance
|
|
384
517
|
|
|
385
518
|
`loom-kernel` adds zero measurable overhead at the concurrency levels typical of
|
|
@@ -1,38 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: loom-kernel
|
|
3
|
-
Version: 0.2.1
|
|
4
|
-
Summary: Loom Python project
|
|
5
|
-
License-File: LICENSE
|
|
6
|
-
Requires-Python: >=3.11
|
|
7
|
-
Requires-Dist: aiocache<1.0,>=0.12
|
|
8
|
-
Requires-Dist: msgspec<1.0,>=0.18
|
|
9
|
-
Requires-Dist: omegaconf<3.0,>=2.3
|
|
10
|
-
Requires-Dist: prometheus-client>=0.20
|
|
11
|
-
Requires-Dist: structlog<26.0,>=24.4
|
|
12
|
-
Provides-Extra: cache
|
|
13
|
-
Requires-Dist: aiocache<1.0,>=0.12; extra == 'cache'
|
|
14
|
-
Requires-Dist: omegaconf<3.0,>=2.3; extra == 'cache'
|
|
15
|
-
Provides-Extra: celery
|
|
16
|
-
Requires-Dist: celery<6.0,>=5.3; extra == 'celery'
|
|
17
|
-
Requires-Dist: kombu<6.0,>=5.3; extra == 'celery'
|
|
18
|
-
Requires-Dist: redis<6.0,>=5.0; extra == 'celery'
|
|
19
|
-
Provides-Extra: config
|
|
20
|
-
Requires-Dist: omegaconf<3.0,>=2.3; extra == 'config'
|
|
21
|
-
Provides-Extra: prometheus
|
|
22
|
-
Requires-Dist: prometheus-client>=0.20; extra == 'prometheus'
|
|
23
|
-
Provides-Extra: pyspark
|
|
24
|
-
Requires-Dist: pyspark<4.0,>=3.5; extra == 'pyspark'
|
|
25
|
-
Provides-Extra: rest
|
|
26
|
-
Requires-Dist: fastapi<1.0,>=0.115; extra == 'rest'
|
|
27
|
-
Requires-Dist: httptools<1.0,>=0.6; extra == 'rest'
|
|
28
|
-
Requires-Dist: prometheus-client>=0.20; extra == 'rest'
|
|
29
|
-
Requires-Dist: pydantic<3.0,>=2.0; extra == 'rest'
|
|
30
|
-
Requires-Dist: uvicorn<1.0,>=0.30; extra == 'rest'
|
|
31
|
-
Requires-Dist: uvloop<1.0,>=0.21; (sys_platform != 'win32') and extra == 'rest'
|
|
32
|
-
Provides-Extra: sqlalchemy
|
|
33
|
-
Requires-Dist: sqlalchemy<3.0,>=2.0; extra == 'sqlalchemy'
|
|
34
|
-
Description-Content-Type: text/markdown
|
|
35
|
-
|
|
36
1
|
<p align="center">
|
|
37
2
|
<img src="docs/_static/logo-transparent.png" alt="loom-kernel" width="160" style="background:#ffffff;border-radius:6px;padding:8px 20px;" />
|
|
38
3
|
</p>
|
|
@@ -55,7 +20,8 @@ Framework-agnostic Python toolkit to build backend applications with:
|
|
|
55
20
|
- repositories decoupled from infrastructure
|
|
56
21
|
- REST/FastAPI adapters with OpenAPI generation
|
|
57
22
|
- background jobs and Celery workers, first-class
|
|
58
|
-
-
|
|
23
|
+
- **declarative ETL** — compile-time-validated pipelines for Polars and Spark
|
|
24
|
+
- testing utilities for business workflows and ETL steps
|
|
59
25
|
|
|
60
26
|
## Purpose
|
|
61
27
|
|
|
@@ -70,7 +36,8 @@ infrastructure (DB, cache, transport) without breaking business logic.
|
|
|
70
36
|
|
|
71
37
|
- Usage guides and architecture docs are available in the `docs/` site.
|
|
72
38
|
- API reference is autogenerated from public docstrings.
|
|
73
|
-
- End-to-end demo
|
|
39
|
+
- End-to-end REST demo: [`dummy-loom`](https://github.com/the-reacher-data/dummy-loom).
|
|
40
|
+
- End-to-end ETL demo: [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl) — full Polars and Spark pipeline examples.
|
|
74
41
|
|
|
75
42
|
## Main subpaths
|
|
76
43
|
|
|
@@ -82,10 +49,23 @@ infrastructure (DB, cache, transport) without breaking business logic.
|
|
|
82
49
|
| `src/loom/core/repository/sqlalchemy` | Concrete async SQLAlchemy repository implementation. |
|
|
83
50
|
| `src/loom/core/model` | Base model, fields, relations, and entity introspection. |
|
|
84
51
|
| `src/loom/core/cache` | Decorators and cached repository with dependency invalidation. |
|
|
52
|
+
| `src/loom/core/config` | YAML config loader with cloud URI support and pluggable resolvers. |
|
|
85
53
|
| `src/loom/rest` | Framework-agnostic REST model and route compiler. |
|
|
86
54
|
| `src/loom/rest/fastapi` | Direct FastAPI integration (auto wiring and runtime router). |
|
|
87
55
|
| `src/loom/prometheus` | Middleware and adapter for runtime metrics. |
|
|
88
56
|
| `src/loom/testing` | Harnesses for unit/integration tests and golden tests. |
|
|
57
|
+
| `src/loom/etl` | Declarative ETL subsystem — pipelines, Polars/Spark backends, observability. |
|
|
58
|
+
| `src/loom/etl/pipeline` | `ETLStep`, `ETLProcess`, `ETLPipeline`, `StepSQL`, and `ETLParams`. |
|
|
59
|
+
| `src/loom/etl/declarative` | `FromTable`, `FromFile`, `IntoTable`, `IntoFile`, predicate DSL, and `params` proxy. |
|
|
60
|
+
| `src/loom/etl/schema` | Backend-agnostic schema model (`LoomDtype`, `ColumnSchema`, `TableRef`). |
|
|
61
|
+
| `src/loom/etl/storage` | Storage config, table/file locators, and route resolution. |
|
|
62
|
+
| `src/loom/etl/compiler` | Compile-time validation and execution plan builder. |
|
|
63
|
+
| `src/loom/etl/runner` | `ETLRunner` entry point and YAML config loader. |
|
|
64
|
+
| `src/loom/etl/checkpoint` | Step-level checkpoint store for incremental re-runs. |
|
|
65
|
+
| `src/loom/etl/observability` | Run/step observers, OTEL sink, structlog sink, and execution records. |
|
|
66
|
+
| `src/loom/etl/backends/polars` | Polars + Delta Lake reader, writer, and schema aligner. |
|
|
67
|
+
| `src/loom/etl/backends/spark` | Spark + Delta reader, writer, and schema aligner. |
|
|
68
|
+
| `src/loom/etl/testing` | `PolarsStepRunner`, `SparkStepRunner`, `ETLScenario`, and test stubs. |
|
|
89
69
|
|
|
90
70
|
## Quick start
|
|
91
71
|
|
|
@@ -415,6 +395,66 @@ For deeper references, review the integration examples under
|
|
|
415
395
|
For a runnable full-stack sample with all patterns combined, check the companion repository
|
|
416
396
|
[`dummy-loom`](https://github.com/the-reacher-data/dummy-loom).
|
|
417
397
|
|
|
398
|
+
## ETL quick start
|
|
399
|
+
|
|
400
|
+
Install a backend:
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
pip install "loom-kernel[etl-polars]"
|
|
404
|
+
# or
|
|
405
|
+
pip install "loom-kernel[etl-spark]"
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
Declare a pipeline — sources, targets, and transformation logic are explicit and compile-time validated:
|
|
409
|
+
|
|
410
|
+
```python
|
|
411
|
+
from datetime import date
|
|
412
|
+
import polars as pl
|
|
413
|
+
from loom.etl import ETLParams, ETLStep, ETLProcess, ETLPipeline, ETLRunner, FromTable, IntoTable
|
|
414
|
+
|
|
415
|
+
class DailyParams(ETLParams):
|
|
416
|
+
run_date: date
|
|
417
|
+
|
|
418
|
+
class CleanOrders(ETLStep[DailyParams]):
|
|
419
|
+
orders = FromTable("raw.orders").columns("id", "amount", "run_date")
|
|
420
|
+
target = IntoTable("staging.orders").replace()
|
|
421
|
+
|
|
422
|
+
def execute(self, params: DailyParams, *, orders: pl.LazyFrame) -> pl.LazyFrame:
|
|
423
|
+
return orders.filter(pl.col("amount") > 0)
|
|
424
|
+
|
|
425
|
+
class DailyProcess(ETLProcess[DailyParams]):
|
|
426
|
+
steps = [CleanOrders]
|
|
427
|
+
|
|
428
|
+
class DailyPipeline(ETLPipeline[DailyParams]):
|
|
429
|
+
processes = [DailyProcess]
|
|
430
|
+
|
|
431
|
+
runner = ETLRunner.from_yaml("config/etl.yaml")
|
|
432
|
+
runner.run(DailyPipeline, DailyParams(run_date=date.today()))
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Write modes — `replace`, `append`, `replace_partition`, `replace_partitions`, `replace_where`, `upsert` — are declared on the target, validated at compile time. Partition predicates use the `params` proxy so no values are hard-coded:
|
|
436
|
+
|
|
437
|
+
```python
|
|
438
|
+
from loom.etl import params
|
|
439
|
+
|
|
440
|
+
target = IntoTable("staging.orders").replace_partition(
|
|
441
|
+
year=params.run_date.year,
|
|
442
|
+
month=params.run_date.month,
|
|
443
|
+
)
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
File aliases decouple paths from pipelines — declare once in YAML, reference by name:
|
|
447
|
+
|
|
448
|
+
```python
|
|
449
|
+
events = FromFile.alias("events_raw", format=Format.CSV)
|
|
450
|
+
target = IntoFile.alias("exports_daily", format=Format.PARQUET)
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
For a full Polars + Spark + Delta Lake example see [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl).
|
|
454
|
+
For the complete API reference and write-mode guide see the [ETL docs](https://loom-py.readthedocs.io/en/latest/guides/etl.html).
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
418
458
|
## Performance
|
|
419
459
|
|
|
420
460
|
`loom-kernel` adds zero measurable overhead at the concurrency levels typical of
|
|
@@ -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"
|
|
@@ -28,7 +29,7 @@ extensions = [
|
|
|
28
29
|
]
|
|
29
30
|
|
|
30
31
|
templates_path = ["_templates"]
|
|
31
|
-
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
|
32
|
+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "guides", "architecture", "examples-repo"]
|
|
32
33
|
|
|
33
34
|
html_theme = "furo"
|
|
34
35
|
html_static_path = ["_static"]
|
|
@@ -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")
|
|
@@ -81,9 +89,13 @@ intersphinx_mapping = {
|
|
|
81
89
|
autodoc_mock_imports = [
|
|
82
90
|
"aiocache",
|
|
83
91
|
"celery",
|
|
92
|
+
"deltalake",
|
|
84
93
|
"fastapi",
|
|
94
|
+
"fsspec",
|
|
85
95
|
"kombu",
|
|
86
96
|
"omegaconf",
|
|
97
|
+
"polars",
|
|
98
|
+
"pyarrow",
|
|
87
99
|
"prometheus_client",
|
|
88
100
|
"pydantic",
|
|
89
101
|
"pyspark",
|
|
@@ -94,6 +106,6 @@ autodoc_mock_imports = [
|
|
|
94
106
|
]
|
|
95
107
|
|
|
96
108
|
|
|
97
|
-
def setup(app):
|
|
109
|
+
def setup(app: Any) -> None:
|
|
98
110
|
"""Register Sphinx hooks."""
|
|
99
111
|
app.connect("autodoc-skip-member", _skip_duplicate_reexports)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# ETL Examples
|
|
2
|
+
|
|
3
|
+
The companion repository [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl)
|
|
4
|
+
contains runnable end-to-end examples of `loom.etl` with both Polars and Spark
|
|
5
|
+
backends.
|
|
6
|
+
|
|
7
|
+
## What it covers
|
|
8
|
+
|
|
9
|
+
- Polars and Spark pipeline declarations
|
|
10
|
+
- Delta Lake read/write modes (`replace`, `upsert`, `replace_partitions`)
|
|
11
|
+
- Cloud storage configuration (S3, GCS, Azure) via `fsspec`
|
|
12
|
+
- File aliases with `FromFile.alias` / `IntoFile.alias`
|
|
13
|
+
- Observability and run sinks
|
|
14
|
+
- Integration tests with `PolarsStepRunner` and `SparkTestSession`
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git clone https://github.com/the-reacher-data/dummy-loom-etl
|
|
20
|
+
cd dummy-loom-etl
|
|
21
|
+
make test # run Polars and Spark test suites
|
|
22
|
+
make run # run the sample pipeline locally
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Next steps
|
|
26
|
+
|
|
27
|
+
- [ETL pipelines guide](pipelines.md)
|
|
28
|
+
- [ETL testing guide](testing.md)
|
|
29
|
+
- [API reference](../reference/api/etl)
|