loom-kernel 0.7.0__tar.gz → 0.9.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.
Files changed (798) hide show
  1. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.github/workflows/ci-main.yml +2 -1
  2. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.github/workflows/ci-pr.yml +2 -1
  3. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.github/workflows/docs.yml +2 -1
  4. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.github/workflows/release.yml +32 -14
  5. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.gitignore +2 -0
  6. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/CHANGELOG.md +209 -0
  7. loom_kernel-0.9.0/CHANGELOG_RELEASE.md +98 -0
  8. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/PKG-INFO +5 -1
  9. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/pyproject.toml +17 -2
  10. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/keys.py +1 -0
  11. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/observability.py +16 -1
  12. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/__init__.py +2 -0
  13. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/types.py +11 -0
  14. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/config.py +10 -1
  15. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/observer/otel.py +120 -8
  16. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/runtime.py +75 -3
  17. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/session_manager.py +47 -1
  18. loom_kernel-0.9.0/src/loom/core/schema/__init__.py +5 -0
  19. loom_kernel-0.9.0/src/loom/core/schema/schema_mode.py +22 -0
  20. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/__init__.py +5 -0
  21. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_predicate.py +4 -11
  22. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_write_policy.py +47 -3
  23. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_reader.py +140 -7
  24. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_writer.py +147 -11
  25. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/provider.py +33 -7
  26. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/__init__.py +7 -1
  27. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_backends/_polars.py +2 -2
  28. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_cleaners.py +29 -4
  29. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/__init__.py +10 -0
  30. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/source/__init__.py +14 -0
  31. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/source/_from.py +5 -7
  32. loom_kernel-0.9.0/src/loom/etl/declarative/source/_from_clickhouse.py +106 -0
  33. loom_kernel-0.9.0/src/loom/etl/declarative/source/_from_mongo.py +178 -0
  34. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/source/_specs.py +82 -2
  35. loom_kernel-0.9.0/src/loom/etl/declarative/target/_schema_mode.py +5 -0
  36. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/executor/_executor.py +39 -7
  37. loom_kernel-0.9.0/src/loom/etl/io/__init__.py +29 -0
  38. loom_kernel-0.9.0/src/loom/etl/io/_registry.py +65 -0
  39. loom_kernel-0.9.0/src/loom/etl/io/sources/_clickhouse.py +153 -0
  40. loom_kernel-0.9.0/src/loom/etl/io/sources/_mongo.py +258 -0
  41. loom_kernel-0.9.0/src/loom/etl/io/sources/_mongo_batch.py +869 -0
  42. loom_kernel-0.9.0/src/loom/etl/io/sources/_mongo_bson.py +181 -0
  43. loom_kernel-0.9.0/src/loom/etl/io/sources/_mongo_predicate.py +223 -0
  44. loom_kernel-0.9.0/src/loom/etl/io/targets/_clickhouse.py +158 -0
  45. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/_records.py +23 -0
  46. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_step.py +1 -4
  47. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/core.py +1 -1
  48. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runtime/contracts.py +14 -2
  49. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/storage/__init__.py +4 -0
  50. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/storage/_config.py +98 -13
  51. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/storage/_locator.py +11 -0
  52. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/_runners.py +8 -2
  53. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/_stubs.py +8 -1
  54. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/spark.py +8 -2
  55. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/__init__.py +51 -5
  56. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_adapter.py +13 -1
  57. loom_kernel-0.9.0/src/loom/streaming/bytewax/_resource_manager.py +160 -0
  58. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_runtime_io.py +17 -5
  59. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/_shared.py +9 -0
  60. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +9 -0
  61. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/routing.py +76 -1
  62. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/steps.py +59 -2
  63. loom_kernel-0.9.0/src/loom/streaming/bytewax/handlers/storage.py +212 -0
  64. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/runner.py +32 -5
  65. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/__init__.py +4 -2
  66. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/_bindings.py +17 -0
  67. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/_compiler.py +4 -0
  68. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/_plan.py +47 -2
  69. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/phases/build_plan.py +151 -39
  70. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/compiler/phases/validate.py +254 -77
  71. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/graph/_flow.py +5 -2
  72. loom_kernel-0.9.0/src/loom/streaming/mongo/__init__.py +28 -0
  73. loom_kernel-0.9.0/src/loom/streaming/mongo/_bytewax_source.py +246 -0
  74. loom_kernel-0.9.0/src/loom/streaming/mongo/_config.py +55 -0
  75. loom_kernel-0.9.0/src/loom/streaming/mongo/_event.py +79 -0
  76. loom_kernel-0.9.0/src/loom/streaming/mongo/_normalize.py +287 -0
  77. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/__init__.py +26 -4
  78. loom_kernel-0.9.0/src/loom/streaming/nodes/_decompose.py +89 -0
  79. loom_kernel-0.9.0/src/loom/streaming/nodes/_expand_routes.py +75 -0
  80. loom_kernel-0.9.0/src/loom/streaming/nodes/_mongo.py +50 -0
  81. loom_kernel-0.9.0/src/loom/streaming/nodes/_sink.py +120 -0
  82. loom_kernel-0.9.0/src/loom/streaming/nodes/_table/__init__.py +23 -0
  83. loom_kernel-0.9.0/src/loom/streaming/nodes/_table/common.py +1177 -0
  84. loom_kernel-0.9.0/src/loom/streaming/nodes/_table/config.py +137 -0
  85. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/testing.py +8 -8
  86. loom_kernel-0.9.0/src/loom/testing/__init__.py +37 -0
  87. loom_kernel-0.9.0/tests/integration/streaming/test_into_table_integration.py +511 -0
  88. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/observability/test_observers.py +47 -0
  89. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/observability/test_runtime.py +108 -1
  90. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/conftest.py +2 -1
  91. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_backend.py +142 -1
  92. loom_kernel-0.9.0/tests/unit/etl/backends/test_polars/test_reader_json_columns.py +431 -0
  93. loom_kernel-0.9.0/tests/unit/etl/backends/test_polars/test_writer_null_schema.py +55 -0
  94. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/checkpoint/test_store.py +1 -1
  95. loom_kernel-0.9.0/tests/unit/etl/io/sources/test_clickhouse_reader.py +121 -0
  96. loom_kernel-0.9.0/tests/unit/etl/io/sources/test_from_clickhouse.py +106 -0
  97. loom_kernel-0.9.0/tests/unit/etl/io/sources/test_from_mongo.py +224 -0
  98. loom_kernel-0.9.0/tests/unit/etl/io/sources/test_mongo_predicate.py +188 -0
  99. loom_kernel-0.9.0/tests/unit/etl/io/sources/test_mongo_reader.py +1681 -0
  100. loom_kernel-0.9.0/tests/unit/etl/io/targets/test_clickhouse_writer.py +104 -0
  101. loom_kernel-0.9.0/tests/unit/etl/io/targets/test_into_clickhouse.py +66 -0
  102. loom_kernel-0.9.0/tests/unit/etl/io/test_registry.py +149 -0
  103. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_source.py +14 -0
  104. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_source_options.py +17 -0
  105. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/sql/test_merge.py +1 -1
  106. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/sql/test_sql_runtime.py +15 -3
  107. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_backend_factory.py +12 -4
  108. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_locator.py +4 -0
  109. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_storage_config.py +99 -8
  110. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_runner.py +102 -5
  111. loom_kernel-0.9.0/tests/unit/streaming/bytewax/test_resource_manager.py +52 -0
  112. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_runner.py +172 -7
  113. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_runtime_io.py +17 -0
  114. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_steps.py +1 -1
  115. loom_kernel-0.9.0/tests/unit/streaming/bytewax/test_storage.py +147 -0
  116. loom_kernel-0.9.0/tests/unit/streaming/compiler/test_async_walk.py +182 -0
  117. loom_kernel-0.9.0/tests/unit/streaming/compiler/test_mongo_source.py +64 -0
  118. loom_kernel-0.9.0/tests/unit/streaming/contracts/__init__.py +0 -0
  119. loom_kernel-0.9.0/tests/unit/streaming/contracts/test_mongo_contracts.py +242 -0
  120. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/__init__.py +2 -0
  121. loom_kernel-0.9.0/tests/unit/streaming/flows/cases/explode.py +134 -0
  122. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/conftest.py +2 -0
  123. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/test_compiler_examples.py +13 -1
  124. loom_kernel-0.9.0/tests/unit/streaming/mongo/test_bytewax_source.py +287 -0
  125. loom_kernel-0.9.0/tests/unit/streaming/nodes/__init__.py +0 -0
  126. loom_kernel-0.9.0/tests/unit/streaming/nodes/test_delta_config.py +36 -0
  127. loom_kernel-0.9.0/tests/unit/streaming/nodes/test_table_package.py +19 -0
  128. loom_kernel-0.9.0/tests/unit/streaming/observability/__init__.py +0 -0
  129. loom_kernel-0.9.0/tests/unit/streaming/support/__init__.py +0 -0
  130. loom_kernel-0.9.0/tests/unit/streaming/test_expand_routes.py +92 -0
  131. loom_kernel-0.9.0/tests/unit/streaming/test_testing_mongo.py +90 -0
  132. loom_kernel-0.9.0/tests/unit/testing/__init__.py +0 -0
  133. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/uv.lock +322 -2
  134. loom_kernel-0.7.0/CHANGELOG_RELEASE.md +0 -96
  135. loom_kernel-0.7.0/src/loom/etl/declarative/target/_schema_mode.py +0 -23
  136. loom_kernel-0.7.0/src/loom/streaming/bytewax/_resource_manager.py +0 -68
  137. loom_kernel-0.7.0/src/loom/testing/__init__.py +0 -20
  138. loom_kernel-0.7.0/tests/unit/etl/backends/test_polars/test_reader_json_columns.py +0 -199
  139. loom_kernel-0.7.0/tests/unit/streaming/compiler/test_async_walk.py +0 -91
  140. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.pre-commit-config.yaml +0 -0
  141. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/.readthedocs.yaml +0 -0
  142. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/LICENSE +0 -0
  143. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/Makefile +0 -0
  144. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/README.md +0 -0
  145. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/codecov.yml +0 -0
  146. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/_static/.gitkeep +0 -0
  147. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/_static/custom.css +0 -0
  148. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/_static/logo-transparent.png +0 -0
  149. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/_static/logo.svg +0 -0
  150. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/architecture/adr/README.md +0 -0
  151. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/architecture/clean-architecture.md +0 -0
  152. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/architecture/overview.md +0 -0
  153. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/conf.py +0 -0
  154. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/etl/examples.md +0 -0
  155. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/etl/pipelines.md +0 -0
  156. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/etl/testing.md +0 -0
  157. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/examples-repo/index.md +0 -0
  158. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/getting-started/etl.md +0 -0
  159. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/getting-started/rest.md +0 -0
  160. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/getting-started/streaming.md +0 -0
  161. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/autocrud.md +0 -0
  162. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/celery.md +0 -0
  163. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/etl.md +0 -0
  164. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/fake-repo-examples.md +0 -0
  165. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/quickstart.md +0 -0
  166. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/guides/use-case-dsl.md +0 -0
  167. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/index.rst +0 -0
  168. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/overview.md +0 -0
  169. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/core.rst +0 -0
  170. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/etl.rst +0 -0
  171. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/repository.rst +0 -0
  172. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/rest.rst +0 -0
  173. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/streaming.rst +0 -0
  174. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/api/testing.rst +0 -0
  175. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/reference/index.rst +0 -0
  176. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/requirements.txt +0 -0
  177. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/rest/autocrud.md +0 -0
  178. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/rest/celery.md +0 -0
  179. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/rest/examples.md +0 -0
  180. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/rest/testing.md +0 -0
  181. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/rest/use-case-dsl.md +0 -0
  182. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/docs/streaming/bytewax.md +0 -0
  183. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/sonar-project.properties +0 -0
  184. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/__init__.py +0 -0
  185. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/__init__.py +0 -0
  186. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/auto.py +0 -0
  187. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/bootstrap.py +0 -0
  188. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/config.py +0 -0
  189. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/constants.py +0 -0
  190. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/runner.py +0 -0
  191. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/celery/service.py +0 -0
  192. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/async_bridge.py +0 -0
  193. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/backend/__init__.py +0 -0
  194. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/backend/core_model.py +0 -0
  195. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/backend/protocol.py +0 -0
  196. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/backend/sqlalchemy.py +0 -0
  197. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/bootstrap/__init__.py +0 -0
  198. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
  199. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/bootstrap/kernel.py +0 -0
  200. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/__init__.py +0 -0
  201. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/abc/__init__.py +0 -0
  202. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/abc/backend.py +0 -0
  203. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/abc/config.py +0 -0
  204. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/abc/dependency.py +0 -0
  205. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/codec.py +0 -0
  206. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/decorators.py +0 -0
  207. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/dependency.py +0 -0
  208. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/gateway.py +0 -0
  209. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/keys.py +0 -0
  210. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/repository.py +0 -0
  211. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/cache/serializer.py +0 -0
  212. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/command/__init__.py +0 -0
  213. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/command/adapter.py +0 -0
  214. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/command/base.py +0 -0
  215. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/command/field.py +0 -0
  216. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/command/introspection.py +0 -0
  217. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/compiler.py +0 -0
  218. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/__init__.py +0 -0
  219. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/binder.py +0 -0
  220. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/configurable.py +0 -0
  221. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/context.py +0 -0
  222. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/errors.py +0 -0
  223. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/loader.py +0 -0
  224. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/model.py +0 -0
  225. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/config/resolver.py +0 -0
  226. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/contracts/__init__.py +0 -0
  227. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/contracts/manifest.py +0 -0
  228. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/di/__init__.py +0 -0
  229. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/di/container.py +0 -0
  230. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/di/scope.py +0 -0
  231. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/__init__.py +0 -0
  232. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/_utils.py +0 -0
  233. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/base.py +0 -0
  234. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/interfaces.py +0 -0
  235. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/manifest.py +0 -0
  236. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/discovery/modules.py +0 -0
  237. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/__init__.py +0 -0
  238. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/compilable.py +0 -0
  239. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/compiler.py +0 -0
  240. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/events.py +0 -0
  241. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/executor.py +0 -0
  242. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/metrics.py +0 -0
  243. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/engine/plan.py +0 -0
  244. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/errors/__init__.py +0 -0
  245. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/errors/codes.py +0 -0
  246. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/errors/errors.py +0 -0
  247. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/expr/__init__.py +0 -0
  248. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/expr/eval.py +0 -0
  249. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/expr/nodes.py +0 -0
  250. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/expr/refs.py +0 -0
  251. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/__init__.py +0 -0
  252. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/callback.py +0 -0
  253. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/context.py +0 -0
  254. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/handle.py +0 -0
  255. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/job.py +0 -0
  256. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/job/service.py +0 -0
  257. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/logger/__init__.py +0 -0
  258. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/logger/abc.py +0 -0
  259. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/logger/config.py +0 -0
  260. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/logger/registry.py +0 -0
  261. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/logger/structlogger.py +0 -0
  262. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/base.py +0 -0
  263. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/enums.py +0 -0
  264. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/field.py +0 -0
  265. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/introspection.py +0 -0
  266. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/projection.py +0 -0
  267. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/relation.py +0 -0
  268. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/struct.py +0 -0
  269. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/timestamped.py +0 -0
  270. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/model/types_postgres.py +0 -0
  271. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/__init__.py +0 -0
  272. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/event.py +0 -0
  273. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/observer/__init__.py +0 -0
  274. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/observer/noop.py +0 -0
  275. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/observer/structlog.py +0 -0
  276. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/protocol.py +0 -0
  277. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/observability/topology.py +0 -0
  278. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/projection/__init__.py +0 -0
  279. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/projection/loaders.py +0 -0
  280. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/projection/runtime.py +0 -0
  281. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/__init__.py +0 -0
  282. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/abc/__init__.py +0 -0
  283. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/abc/query.py +0 -0
  284. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/abc/repo_for.py +0 -0
  285. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/abc/repository.py +0 -0
  286. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/mutation.py +0 -0
  287. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/registration.py +0 -0
  288. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/registry.py +0 -0
  289. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
  290. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
  291. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
  292. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
  293. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
  294. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
  295. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
  296. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
  297. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
  298. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
  299. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
  300. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
  301. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
  302. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
  303. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
  304. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
  305. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
  306. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
  307. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
  308. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/response/__init__.py +0 -0
  309. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/response/base.py +0 -0
  310. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/routing/__init__.py +0 -0
  311. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/routing/ref.py +0 -0
  312. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/routing/resolver.py +0 -0
  313. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/runner.py +0 -0
  314. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/tracing/__init__.py +0 -0
  315. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/tracing/context.py +0 -0
  316. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/transport/__init__.py +0 -0
  317. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/transport/adapter.py +0 -0
  318. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/uow/__init__.py +0 -0
  319. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/uow/abc.py +0 -0
  320. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/uow/context.py +0 -0
  321. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/__init__.py +0 -0
  322. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/_predicates.py +0 -0
  323. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/compute.py +0 -0
  324. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/constants.py +0 -0
  325. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/factory.py +0 -0
  326. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/field_ref.py +0 -0
  327. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/invoker.py +0 -0
  328. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/keys.py +0 -0
  329. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/markers.py +0 -0
  330. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/registry.py +0 -0
  331. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/rule.py +0 -0
  332. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/core/use_case/use_case.py +0 -0
  333. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/__init__.py +0 -0
  334. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_format_registry.py +0 -0
  335. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
  336. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/_common.py +0 -0
  337. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/_log.py +0 -0
  338. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
  339. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
  340. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
  341. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_merge.py +0 -0
  342. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
  343. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
  344. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
  345. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/__init__.py +0 -0
  346. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
  347. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
  348. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_historify.py +0 -0
  349. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
  350. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_schema.py +0 -0
  351. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
  352. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/__init__.py +0 -0
  353. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
  354. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_historify.py +0 -0
  355. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_reader.py +0 -0
  356. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_schema.py +0 -0
  357. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
  358. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/_writer.py +0 -0
  359. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/backends/spark/provider.py +0 -0
  360. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
  361. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_paths.py +0 -0
  362. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_scope.py +0 -0
  363. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/checkpoint/_store.py +0 -0
  364. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/__init__.py +0 -0
  365. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_binding.py +0 -0
  366. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_compiler.py +0 -0
  367. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_errors.py +0 -0
  368. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_plan.py +0 -0
  369. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_validators.py +0 -0
  370. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
  371. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/compiler/_validators_step.py +0 -0
  372. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/_format.py +0 -0
  373. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/_read_options.py +0 -0
  374. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/_utils.py +0 -0
  375. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/_write_options.py +0 -0
  376. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
  377. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/expr/_params.py +0 -0
  378. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
  379. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
  380. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
  381. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/__init__.py +0 -0
  382. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_file.py +0 -0
  383. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
  384. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
  385. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
  386. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
  387. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
  388. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
  389. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_into.py +0 -0
  390. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_table.py +0 -0
  391. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/declarative/target/_temp.py +0 -0
  392. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/executor/__init__.py +0 -0
  393. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/executor/_dispatcher.py +0 -0
  394. {loom_kernel-0.7.0/tests → loom_kernel-0.9.0/src/loom/etl/io/sources}/__init__.py +0 -0
  395. {loom_kernel-0.7.0/tests/golden → loom_kernel-0.9.0/src/loom/etl/io/targets}/__init__.py +0 -0
  396. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/__init__.py +0 -0
  397. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/_config.py +0 -0
  398. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/_observer.py +0 -0
  399. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
  400. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
  401. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
  402. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
  403. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/__init__.py +0 -0
  404. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_generics.py +0 -0
  405. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_params.py +0 -0
  406. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
  407. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_process.py +0 -0
  408. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_sql.py +0 -0
  409. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
  410. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/__init__.py +0 -0
  411. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/_providers.py +0 -0
  412. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/_wiring.py +0 -0
  413. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/config_loader.py +0 -0
  414. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/errors.py +0 -0
  415. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runner/filtering.py +0 -0
  416. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/runtime/__init__.py +0 -0
  417. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/schema/__init__.py +0 -0
  418. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/schema/_contract.py +0 -0
  419. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/schema/_schema.py +0 -0
  420. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/storage/_file_locator.py +0 -0
  421. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/storage/routing.py +0 -0
  422. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/__init__.py +0 -0
  423. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/_result.py +0 -0
  424. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/etl/testing/_scenario.py +0 -0
  425. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/prometheus/__init__.py +0 -0
  426. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/prometheus/adapter.py +0 -0
  427. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/prometheus/kafka.py +0 -0
  428. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/prometheus/lifecycle.py +0 -0
  429. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/prometheus/middleware.py +0 -0
  430. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/__init__.py +0 -0
  431. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/adapter.py +0 -0
  432. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/autocrud.py +0 -0
  433. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/compiler.py +0 -0
  434. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/constants.py +0 -0
  435. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/errors.py +0 -0
  436. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/__init__.py +0 -0
  437. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/app.py +0 -0
  438. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/auto.py +0 -0
  439. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/openapi.py +0 -0
  440. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/response.py +0 -0
  441. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
  442. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/middleware.py +0 -0
  443. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/model.py +0 -0
  444. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/rest/rest_adapter.py +0 -0
  445. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/__init__.py +0 -0
  446. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
  447. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
  448. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
  449. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/_operators.py +0 -0
  450. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
  451. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
  452. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
  453. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
  454. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/core/__init__.py +0 -0
  455. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/core/_errors.py +0 -0
  456. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/core/_exceptions.py +0 -0
  457. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/core/_message.py +0 -0
  458. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/core/_typing.py +0 -0
  459. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/graph/__init__.py +0 -0
  460. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/__init__.py +0 -0
  461. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_codec.py +0 -0
  462. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_config.py +0 -0
  463. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_errors.py +0 -0
  464. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
  465. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_message.py +0 -0
  466. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_record.py +0 -0
  467. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/_wire.py +0 -0
  468. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
  469. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
  470. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
  471. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
  472. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
  473. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
  474. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
  475. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
  476. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_boundary.py +0 -0
  477. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
  478. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
  479. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
  480. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_fork.py +0 -0
  481. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_helpers.py +0 -0
  482. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_protocols.py +0 -0
  483. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_router.py +0 -0
  484. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_shape.py +0 -0
  485. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_step.py +0 -0
  486. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/_with.py +0 -0
  487. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/streaming/nodes/refs.py +0 -0
  488. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/testing/golden.py +0 -0
  489. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/testing/http_harness.py +0 -0
  490. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/testing/in_memory.py +0 -0
  491. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/testing/repository_harness.py +0 -0
  492. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/src/loom/testing/runner.py +0 -0
  493. {loom_kernel-0.7.0/tests/integration → loom_kernel-0.9.0/tests}/__init__.py +0 -0
  494. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/conftest.py +0 -0
  495. {loom_kernel-0.7.0/tests/integration/celery_bootstrap → loom_kernel-0.9.0/tests/golden}/__init__.py +0 -0
  496. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/golden/baselines/.gitkeep +0 -0
  497. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/golden/outputs/.gitkeep +0 -0
  498. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/golden/plans/.gitkeep +0 -0
  499. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/helpers/__init__.py +0 -0
  500. {loom_kernel-0.7.0/tests/integration/core → loom_kernel-0.9.0/tests/integration}/__init__.py +0 -0
  501. {loom_kernel-0.7.0/tests/integration/core/bootstrap → loom_kernel-0.9.0/tests/integration/celery_bootstrap}/__init__.py +0 -0
  502. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/celery_bootstrap/config/conf.celery.integration.yaml +0 -0
  503. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/celery_bootstrap/test_auto_create_app_integration.py +0 -0
  504. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/celery_bootstrap/test_bootstrap_worker.py +0 -0
  505. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/conftest.py +0 -0
  506. {loom_kernel-0.7.0/tests/integration/core/repository → loom_kernel-0.9.0/tests/integration/core}/__init__.py +0 -0
  507. {loom_kernel-0.7.0/tests/integration/core/repository/sqlalchemy → loom_kernel-0.9.0/tests/integration/core/bootstrap}/__init__.py +0 -0
  508. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/bootstrap/test_bootstrap_integration.py +0 -0
  509. {loom_kernel-0.7.0/tests/integration/core/rest → loom_kernel-0.9.0/tests/integration/core/repository}/__init__.py +0 -0
  510. {loom_kernel-0.7.0/tests/integration/core/use_case → loom_kernel-0.9.0/tests/integration/core/repository/sqlalchemy}/__init__.py +0 -0
  511. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/repository/sqlalchemy/conftest.py +0 -0
  512. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/repository/sqlalchemy/test_cache_integration.py +0 -0
  513. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/repository/sqlalchemy/test_repository_integration.py +0 -0
  514. {loom_kernel-0.7.0/tests/integration/fake_repo → loom_kernel-0.9.0/tests/integration/core/rest}/__init__.py +0 -0
  515. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/rest/test_auto_interface_integration.py +0 -0
  516. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/rest/test_fastapi_app_integration.py +0 -0
  517. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/rest/test_rest_error_mapping.py +0 -0
  518. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/rest/test_rest_observability.py +0 -0
  519. {loom_kernel-0.7.0/tests/integration/fake_repo/product/category → loom_kernel-0.9.0/tests/integration/core/use_case}/__init__.py +0 -0
  520. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/use_case/test_custom_repository_integration.py +0 -0
  521. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/core/use_case/test_use_case_crud_integration.py +0 -0
  522. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/etl/__init__.py +0 -0
  523. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/etl/test_runner_integration.py +0 -0
  524. {loom_kernel-0.7.0/tests/integration/fake_repo/product/review → loom_kernel-0.9.0/tests/integration/fake_repo}/__init__.py +0 -0
  525. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/config/__init__.py +0 -0
  526. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/config/conf.interfaces.yaml +0 -0
  527. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/config/conf.manifest.yaml +0 -0
  528. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/config/conf.modules.yaml +0 -0
  529. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/config/conf.yaml +0 -0
  530. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/main.py +0 -0
  531. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/manifest.py +0 -0
  532. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/__init__.py +0 -0
  533. {loom_kernel-0.7.0/tests/unit → loom_kernel-0.9.0/tests/integration/fake_repo/product/category}/__init__.py +0 -0
  534. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/category/model.py +0 -0
  535. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/category/schemas.py +0 -0
  536. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/interface.py +0 -0
  537. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/jobs.py +0 -0
  538. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/model.py +0 -0
  539. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/relations.py +0 -0
  540. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/repository.py +0 -0
  541. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/repository_contract.py +0 -0
  542. {loom_kernel-0.7.0/tests/unit/celery_bootstrap → loom_kernel-0.9.0/tests/integration/fake_repo/product/review}/__init__.py +0 -0
  543. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/review/model.py +0 -0
  544. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/review/schemas.py +0 -0
  545. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/schemas.py +0 -0
  546. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/fake_repo/product/use_cases.py +0 -0
  547. {loom_kernel-0.7.0/tests/unit/celery_jobs → loom_kernel-0.9.0/tests/integration/streaming}/__init__.py +0 -0
  548. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/support/__init__.py +0 -0
  549. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/integration/support/logical_repo_fixtures.py +0 -0
  550. {loom_kernel-0.7.0/tests/unit/core → loom_kernel-0.9.0/tests/unit}/__init__.py +0 -0
  551. {loom_kernel-0.7.0/tests/unit/core/backend → loom_kernel-0.9.0/tests/unit/celery_bootstrap}/__init__.py +0 -0
  552. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_bootstrap/test_async_runtime.py +0 -0
  553. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_bootstrap/test_bootstrap.py +0 -0
  554. {loom_kernel-0.7.0/tests/unit/core/bootstrap → loom_kernel-0.9.0/tests/unit/celery_jobs}/__init__.py +0 -0
  555. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_jobs/test_auto.py +0 -0
  556. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_jobs/test_celery_service.py +0 -0
  557. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_jobs/test_config.py +0 -0
  558. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/celery_jobs/test_runner.py +0 -0
  559. {loom_kernel-0.7.0/tests/unit/core/cache → loom_kernel-0.9.0/tests/unit/core}/__init__.py +0 -0
  560. {loom_kernel-0.7.0/tests/unit/core/command → loom_kernel-0.9.0/tests/unit/core/backend}/__init__.py +0 -0
  561. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/backend/test_backend_compiler.py +0 -0
  562. {loom_kernel-0.7.0/tests/unit/core/config → loom_kernel-0.9.0/tests/unit/core/bootstrap}/__init__.py +0 -0
  563. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/bootstrap/test_bootstrap.py +0 -0
  564. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/bootstrap/test_bootstrap_metrics.py +0 -0
  565. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/bootstrap/test_kernel.py +0 -0
  566. {loom_kernel-0.7.0/tests/unit/core/di → loom_kernel-0.9.0/tests/unit/core/cache}/__init__.py +0 -0
  567. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/cache/test_cached_repository.py +0 -0
  568. {loom_kernel-0.7.0/tests/unit/core/discovery → loom_kernel-0.9.0/tests/unit/core/command}/__init__.py +0 -0
  569. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/command/test_command_base.py +0 -0
  570. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/command/test_command_field.py +0 -0
  571. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/command/test_command_patch.py +0 -0
  572. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/command/test_introspection.py +0 -0
  573. {loom_kernel-0.7.0/tests/unit/core/engine → loom_kernel-0.9.0/tests/unit/core/config}/__init__.py +0 -0
  574. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/config/test_binder.py +0 -0
  575. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/config/test_config.py +0 -0
  576. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/config/test_configurable.py +0 -0
  577. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/config/test_context.py +0 -0
  578. {loom_kernel-0.7.0/tests/unit/core/errors → loom_kernel-0.9.0/tests/unit/core/di}/__init__.py +0 -0
  579. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/di/test_container.py +0 -0
  580. {loom_kernel-0.7.0/tests/unit/core/expr → loom_kernel-0.9.0/tests/unit/core/discovery}/__init__.py +0 -0
  581. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/discovery/test_manifest.py +0 -0
  582. {loom_kernel-0.7.0/tests/unit/core/job → loom_kernel-0.9.0/tests/unit/core/engine}/__init__.py +0 -0
  583. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_compiler.py +0 -0
  584. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_executor.py +0 -0
  585. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_executor_trace.py +0 -0
  586. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_executor_uow.py +0 -0
  587. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_metrics.py +0 -0
  588. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/engine/test_plan.py +0 -0
  589. {loom_kernel-0.7.0/tests/unit/core/logger → loom_kernel-0.9.0/tests/unit/core/errors}/__init__.py +0 -0
  590. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/errors/test_errors.py +0 -0
  591. {loom_kernel-0.7.0/tests/unit/core/model → loom_kernel-0.9.0/tests/unit/core/expr}/__init__.py +0 -0
  592. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/expr/test_expr.py +0 -0
  593. {loom_kernel-0.7.0/tests/unit/core/observability → loom_kernel-0.9.0/tests/unit/core/job}/__init__.py +0 -0
  594. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/conftest.py +0 -0
  595. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/test_callback.py +0 -0
  596. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/test_context.py +0 -0
  597. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/test_handle.py +0 -0
  598. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/test_inline_service.py +0 -0
  599. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/job/test_job.py +0 -0
  600. {loom_kernel-0.7.0/tests/unit/core/projection → loom_kernel-0.9.0/tests/unit/core/logger}/__init__.py +0 -0
  601. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/logger/test_config.py +0 -0
  602. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/logger/test_registry.py +0 -0
  603. {loom_kernel-0.7.0/tests/unit/core/repository → loom_kernel-0.9.0/tests/unit/core/model}/__init__.py +0 -0
  604. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/model/test_model.py +0 -0
  605. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/model/test_struct.py +0 -0
  606. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/model/test_timestamped.py +0 -0
  607. {loom_kernel-0.7.0/tests/unit/core/repository/abc → loom_kernel-0.9.0/tests/unit/core/observability}/__init__.py +0 -0
  608. {loom_kernel-0.7.0/tests/unit/core/repository/sqlalchemy → loom_kernel-0.9.0/tests/unit/core/projection}/__init__.py +0 -0
  609. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/projection/test_runtime.py +0 -0
  610. {loom_kernel-0.7.0/tests/unit/core/routing → loom_kernel-0.9.0/tests/unit/core/repository}/__init__.py +0 -0
  611. {loom_kernel-0.7.0/tests/unit/core/tracing → loom_kernel-0.9.0/tests/unit/core/repository/abc}/__init__.py +0 -0
  612. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/abc/conftest.py +0 -0
  613. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/abc/test_query.py +0 -0
  614. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/abc/test_repository_contract.py +0 -0
  615. {loom_kernel-0.7.0/tests/unit/core/uow → loom_kernel-0.9.0/tests/unit/core/repository/sqlalchemy}/__init__.py +0 -0
  616. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/sqlalchemy/conftest.py +0 -0
  617. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/sqlalchemy/test_loaders.py +0 -0
  618. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/sqlalchemy/test_repository.py +0 -0
  619. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/repository/sqlalchemy/test_transactional.py +0 -0
  620. {loom_kernel-0.7.0/tests/unit/core/use_case → loom_kernel-0.9.0/tests/unit/core/routing}/__init__.py +0 -0
  621. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/routing/test_routing.py +0 -0
  622. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/test_async_bridge.py +0 -0
  623. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/test_compiler_contracts.py +0 -0
  624. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/test_runner_contracts.py +0 -0
  625. {loom_kernel-0.7.0/tests/unit/etl → loom_kernel-0.9.0/tests/unit/core/tracing}/__init__.py +0 -0
  626. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/tracing/test_context.py +0 -0
  627. {loom_kernel-0.7.0/tests/unit/etl/backends → loom_kernel-0.9.0/tests/unit/core/uow}/__init__.py +0 -0
  628. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/uow/test_executor_uow.py +0 -0
  629. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/uow/test_sqlalchemy_uow.py +0 -0
  630. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/uow/test_uow_protocols.py +0 -0
  631. {loom_kernel-0.7.0/tests/unit/etl/backends/test_polars → loom_kernel-0.9.0/tests/unit/core/use_case}/__init__.py +0 -0
  632. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_compute.py +0 -0
  633. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_factory.py +0 -0
  634. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_field_ref.py +0 -0
  635. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_invoker.py +0 -0
  636. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_markers.py +0 -0
  637. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_rule.py +0 -0
  638. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/core/use_case/test_use_case.py +0 -0
  639. {loom_kernel-0.7.0/tests/unit/etl/backends/test_spark → loom_kernel-0.9.0/tests/unit/etl}/__init__.py +0 -0
  640. {loom_kernel-0.7.0/tests/unit/etl/checkpoint → loom_kernel-0.9.0/tests/unit/etl/backends}/__init__.py +0 -0
  641. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/_historify_contract.py +0 -0
  642. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_historify_common.py +0 -0
  643. {loom_kernel-0.7.0/tests/unit/etl/checkpoint/backends → loom_kernel-0.9.0/tests/unit/etl/backends/test_polars}/__init__.py +0 -0
  644. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_apply_schema.py +0 -0
  645. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_dtype.py +0 -0
  646. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_file_writer.py +0 -0
  647. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_historify_polars.py +0 -0
  648. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_predicate_pushdown.py +0 -0
  649. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_reader_columns.py +0 -0
  650. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_step_execution.py +0 -0
  651. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_upsert_writer.py +0 -0
  652. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_polars/test_writer_to_frame.py +0 -0
  653. {loom_kernel-0.7.0/tests/unit/etl/compiler → loom_kernel-0.9.0/tests/unit/etl/backends/test_spark}/__init__.py +0 -0
  654. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/conftest.py +0 -0
  655. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/test_dtype.py +0 -0
  656. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/test_historify_spark.py +0 -0
  657. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/test_spark_apply_schema.py +0 -0
  658. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/test_step_execution.py +0 -0
  659. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_spark/test_writer_to_frame.py +0 -0
  660. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/backends/test_write_policy_historify.py +0 -0
  661. {loom_kernel-0.7.0/tests/unit/etl/io → loom_kernel-0.9.0/tests/unit/etl/checkpoint}/__init__.py +0 -0
  662. {loom_kernel-0.7.0/tests/unit/etl/schema → loom_kernel-0.9.0/tests/unit/etl/checkpoint/backends}/__init__.py +0 -0
  663. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/checkpoint/backends/test_checkpoint_polars.py +0 -0
  664. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/checkpoint/test_checkpoint_paths.py +0 -0
  665. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/checkpoint/test_cleaners.py +0 -0
  666. {loom_kernel-0.7.0/tests/unit/etl/sql → loom_kernel-0.9.0/tests/unit/etl/compiler}/__init__.py +0 -0
  667. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_catalog_validator.py +0 -0
  668. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_compiler.py +0 -0
  669. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_compiler_catalog.py +0 -0
  670. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_compiler_upsert.py +0 -0
  671. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_errors.py +0 -0
  672. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_errors_additional_factories.py +0 -0
  673. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_errors_runtime_factories.py +0 -0
  674. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_historify_validator.py +0 -0
  675. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_param_exprs_validator.py +0 -0
  676. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_plan_traversal.py +0 -0
  677. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_step_validator.py +0 -0
  678. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_structural.py +0 -0
  679. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_temp_validator.py +0 -0
  680. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/compiler/test_upsert_validator.py +0 -0
  681. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/conftest.py +0 -0
  682. {loom_kernel-0.7.0/tests/unit/etl/storage → loom_kernel-0.9.0/tests/unit/etl/io}/__init__.py +0 -0
  683. {loom_kernel-0.7.0/tests/unit/etl/testing → loom_kernel-0.9.0/tests/unit/etl/io/sources}/__init__.py +0 -0
  684. {loom_kernel-0.7.0/tests/unit/prometheus → loom_kernel-0.9.0/tests/unit/etl/io/targets}/__init__.py +0 -0
  685. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_history_target.py +0 -0
  686. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_source_json.py +0 -0
  687. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_target.py +0 -0
  688. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_utils.py +0 -0
  689. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/io/test_variants.py +0 -0
  690. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/lineage/test_observer.py +0 -0
  691. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/lineage/test_records.py +0 -0
  692. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/lineage/test_store.py +0 -0
  693. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/pipeline/__init__.py +0 -0
  694. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/pipeline/test_pipeline_process.py +0 -0
  695. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/pipeline/test_proxy.py +0 -0
  696. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/pipeline/test_step.py +0 -0
  697. {loom_kernel-0.7.0/tests/unit/rest → loom_kernel-0.9.0/tests/unit/etl/schema}/__init__.py +0 -0
  698. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/schema/test_contract.py +0 -0
  699. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/schema/test_schema.py +0 -0
  700. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/schema/test_table.py +0 -0
  701. {loom_kernel-0.7.0/tests/unit/streaming/bytewax → loom_kernel-0.9.0/tests/unit/etl/sql}/__init__.py +0 -0
  702. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/sql/test_predicate.py +0 -0
  703. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/sql/test_predicate_dialect.py +0 -0
  704. {loom_kernel-0.7.0/tests/unit/streaming/compiler → loom_kernel-0.9.0/tests/unit/etl/storage}/__init__.py +0 -0
  705. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_io_protocols.py +0 -0
  706. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_observability_and_protocols.py +0 -0
  707. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_route_build.py +0 -0
  708. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/storage/test_schema_readers.py +0 -0
  709. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_config_loader.py +0 -0
  710. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_executor.py +0 -0
  711. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_format_registry.py +0 -0
  712. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_module_contracts.py +0 -0
  713. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_public_api_discovery.py +0 -0
  714. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_record_schema_coverage.py +0 -0
  715. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_runner_errors.py +0 -0
  716. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/test_spark_testing.py +0 -0
  717. {loom_kernel-0.7.0/tests/unit/streaming/contracts → loom_kernel-0.9.0/tests/unit/etl/testing}/__init__.py +0 -0
  718. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/testing/test_runners.py +0 -0
  719. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/testing/test_scenario_and_stubs.py +0 -0
  720. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/etl/testing/test_spark_helpers.py +0 -0
  721. {loom_kernel-0.7.0/tests/unit/streaming/nodes → loom_kernel-0.9.0/tests/unit/prometheus}/__init__.py +0 -0
  722. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/prometheus/test_adapter.py +0 -0
  723. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/prometheus/test_middleware.py +0 -0
  724. {loom_kernel-0.7.0/tests/unit/streaming/observability → loom_kernel-0.9.0/tests/unit/rest}/__init__.py +0 -0
  725. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_autocrud.py +0 -0
  726. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_fastapi_auto_logger.py +0 -0
  727. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_middleware.py +0 -0
  728. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_pydantic_adapter.py +0 -0
  729. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_response.py +0 -0
  730. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_rest_adapter.py +0 -0
  731. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_rest_compiler.py +0 -0
  732. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_rest_model.py +0 -0
  733. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/rest/test_router_runtime.py +0 -0
  734. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/__init__.py +0 -0
  735. {loom_kernel-0.7.0/tests/unit/streaming/support → loom_kernel-0.9.0/tests/unit/streaming/bytewax}/__init__.py +0 -0
  736. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/cases.py +0 -0
  737. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/conftest.py +0 -0
  738. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_adapter.py +0 -0
  739. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_batch_key.py +0 -0
  740. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_bytewax_dispatcher.py +0 -0
  741. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_collect_batch.py +0 -0
  742. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_dlq.py +0 -0
  743. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_error_boundary.py +0 -0
  744. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_operators.py +0 -0
  745. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_runtime_sink.py +0 -0
  746. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/bytewax/test_runtime_source.py +0 -0
  747. {loom_kernel-0.7.0/tests/unit/testing → loom_kernel-0.9.0/tests/unit/streaming/compiler}/__init__.py +0 -0
  748. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/cases.py +0 -0
  749. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_basics.py +0 -0
  750. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_config_bindings.py +0 -0
  751. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_multi_source.py +0 -0
  752. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_router.py +0 -0
  753. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_window.py +0 -0
  754. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/compiler/test_with.py +0 -0
  755. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/conftest.py +0 -0
  756. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/contracts/cases.py +0 -0
  757. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/contracts/test_boundary.py +0 -0
  758. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/contracts/test_message.py +0 -0
  759. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/contracts/test_multi_boundary.py +0 -0
  760. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/contracts/test_steps.py +0 -0
  761. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/__init__.py +0 -0
  762. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/batch.py +0 -0
  763. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/fork.py +0 -0
  764. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/router.py +0 -0
  765. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/shared.py +0 -0
  766. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/cases/simple.py +0 -0
  767. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/flows/test_flow_examples.py +0 -0
  768. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/__init__.py +0 -0
  769. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/cases.py +0 -0
  770. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/conftest.py +0 -0
  771. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/fakes.py +0 -0
  772. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_client.py +0 -0
  773. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_config.py +0 -0
  774. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_key_resolver.py +0 -0
  775. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_message.py +0 -0
  776. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_message_client.py +0 -0
  777. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_multi_wire.py +0 -0
  778. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_observability.py +0 -0
  779. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_settings.py +0 -0
  780. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/kafka/test_wire.py +0 -0
  781. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/nodes/conftest.py +0 -0
  782. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/nodes/test_broadcast.py +0 -0
  783. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/nodes/test_logging.py +0 -0
  784. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/cases.py +0 -0
  785. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/conftest.py +0 -0
  786. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/test_observability_runner.py +0 -0
  787. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/test_protocols.py +0 -0
  788. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/test_registry.py +0 -0
  789. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/observability/test_structlog.py +0 -0
  790. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/support/flow_cases.py +0 -0
  791. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/test_fork.py +0 -0
  792. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/test_otel_observability.py +0 -0
  793. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/test_routing.py +0 -0
  794. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/streaming/test_with.py +0 -0
  795. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/testing/test_golden.py +0 -0
  796. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/testing/test_http_harness.py +0 -0
  797. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/testing/test_in_memory.py +0 -0
  798. {loom_kernel-0.7.0 → loom_kernel-0.9.0}/tests/unit/testing/test_runner.py +0 -0
@@ -24,7 +24,8 @@ jobs:
24
24
  with:
25
25
  python-version: "3.11"
26
26
 
27
- - uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
27
+ - name: Install uv
28
+ run: pip install uv
28
29
 
29
30
  - name: Quality report (strict)
30
31
  uses: the-reacher-data/loom-actions/actions/python/quality-report@e731576f4f9cf4ec2b36fddfc895d328c856d29f # v1
@@ -28,7 +28,8 @@ jobs:
28
28
  with:
29
29
  python-version: "3.11"
30
30
 
31
- - uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
31
+ - name: Install uv
32
+ run: pip install uv
32
33
 
33
34
  - name: Configure uv environment path
34
35
  shell: bash
@@ -37,7 +37,8 @@ jobs:
37
37
  with:
38
38
  python-version: "3.11"
39
39
 
40
- - uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
40
+ - name: Install uv
41
+ run: pip install uv
41
42
 
42
43
  - name: Build docs (strict)
43
44
  shell: bash
@@ -37,7 +37,8 @@ jobs:
37
37
  with:
38
38
  python-version: "3.11"
39
39
 
40
- - uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
40
+ - name: Install uv
41
+ run: pip install uv
41
42
 
42
43
  - name: Configure uv environment path
43
44
  shell: bash
@@ -87,7 +88,7 @@ jobs:
87
88
  sed -i "0,/^version = \".*\"/s//version = \"${VERSION}\"/" pyproject.toml
88
89
  sed -i "/^\[tool.commitizen\]/,/^\[/ s/^version = \".*\"/version = \"${VERSION}\"/" pyproject.toml
89
90
 
90
- - name: Open version bump PR
91
+ - name: Create or merge version bump PR
91
92
  if: ${{ steps.version.outputs.deploy == 'true' }}
92
93
  env:
93
94
  VERSION: ${{ steps.version.outputs.version }}
@@ -99,22 +100,36 @@ jobs:
99
100
  git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
100
101
 
101
102
  BRANCH="docs/release-v${VERSION}"
102
- git checkout -B "${BRANCH}"
103
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
104
+ if git ls-remote --tags origin "refs/tags/v${VERSION}" | grep -q .; then
105
+ echo "Release tag v${VERSION} already exists; skipping version bump PR."
106
+ exit 0
107
+ fi
108
+
109
+ open_pr_count=$(gh pr list --head "${BRANCH}" --state open --json number --jq 'length')
110
+ all_pr_count=$(gh pr list --head "${BRANCH}" --state all --json number --jq 'length')
111
+
112
+ if [ "${all_pr_count}" -gt 0 ] && [ "${open_pr_count}" -eq 0 ]; then
113
+ echo "Release PR ${BRANCH} already exists in a closed state; skipping duplicate creation."
114
+ exit 0
110
115
  fi
111
116
 
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
117
+ if [ "${open_pr_count}" -eq 0 ]; then
118
+ git checkout -B "${BRANCH}"
119
+
120
+ if [ -f CHANGELOG_RELEASE.md ]; then
121
+ HEADER=$(head -1 CHANGELOG_RELEASE.md)
122
+ if ! grep -qF "${HEADER}" CHANGELOG.md; then
123
+ cat CHANGELOG_RELEASE.md CHANGELOG.md > CHANGELOG_MERGED.md
124
+ mv CHANGELOG_MERGED.md CHANGELOG.md
125
+ fi
126
+ fi
127
+
128
+ git add pyproject.toml CHANGELOG.md
129
+ git diff --staged --quiet && exit 0
130
+ git commit -m "chore(release): bump version to ${VERSION}"
131
+ git push origin "${BRANCH}" --force
116
132
 
117
- if ! gh pr list --head "${BRANCH}" --state open --json number --jq '.[0].number' | grep -qE '^[0-9]+$'; then
118
133
  gh pr create \
119
134
  --title "chore(release): bump version to ${VERSION}" \
120
135
  --body "Automated version bump and changelog update after release v${VERSION}." \
@@ -136,10 +151,13 @@ jobs:
136
151
  uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
137
152
  with:
138
153
  password: ${{ env.PYPI_API_TOKEN }}
154
+ skip-existing: true
139
155
 
140
156
  - name: Publish package to PyPI (trusted publisher)
141
157
  if: ${{ steps.version.outputs.deploy == 'true' && env.PYPI_API_TOKEN == '' }}
142
158
  uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
159
+ with:
160
+ skip-existing: true
143
161
 
144
162
  - name: Create and push tags
145
163
  if: ${{ steps.version.outputs.deploy == 'true' }}
@@ -31,3 +31,5 @@ docs/_build/
31
31
 
32
32
  # autosummary stubs — regenerated by Sphinx on every build
33
33
  docs/reference/api/generated/
34
+ .codegraph/
35
+ memory/
@@ -1,3 +1,212 @@
1
+ # 🚀 Release 0.9.0 ([#32](https://github.com/the-reacher-data/loom-py/pull/32)) ([`14072d1`](https://github.com/the-reacher-data/loom-py/commit/14072d1be9212116235f26d7a2590a4f0e622451))
2
+
3
+
4
+ ## ✨ Features
5
+ ### streaming
6
+ - **streaming:** add Mongo CDC source
7
+ - **streaming:** add MongoObjectId and MongoDBRef domain types<br>
8
+ > Replace opaque str/dict BSON normalization with structured domain types:
9
+ > MongoObjectId(id, created_at_ms) preserves ObjectId hex and creation
10
+ > timestamp extracted from the embedded 4-byte BSON timestamp field
11
+ > MongoDBRef(id, collection, database) models cross-collection references
12
+ > with explicit collection and optional database fields
13
+ > MongoCDCEvent.document_id widened to MongoObjectId | str | None to
14
+ > expose rich type when _id is an ObjectId
15
+ > _normalize_objectid and _normalize_dbref updated to produce the new types
16
+ > Guard clause added to _normalize_dbref for None identifier
17
+ > _message_key helper centralizes MongoObjectId → str key extraction
18
+ > MongoObjectId and MongoDBRef exported from loom.streaming public API
19
+ > Contract tests cover DBRef without database, integer id, None id error,
20
+ > and ObjectId without generation_time (created_at_ms=None)
21
+
22
+ - **streaming:** add Backend.CLICKHOUSE with native clickhouse-connect sink<br>
23
+ > Add _ClickHouseTablePartition as a standalone SinkPartition backed by
24
+ > clickhouse-connect (HTTP/2, no SQLAlchemy). Uses a column-oriented buffer
25
+ > layout matching clickhouse-connect's column_oriented=True path, avoiding
26
+ > the internal pivot() transposition for maximum insert throughput.
27
+ > Resolves the _json_serializer crash that occurred when inserting list[str]
28
+ > fields via the SQLAlchemy backend against ClickHouseDialect_asynch. With the
29
+ > native client, Array(String) and all CH-native types work without workarounds.
30
+
31
+ - **streaming:** add ExpandRoutes fan-out node and JsonStr semantic type<br>
32
+ > ExpandRoutes: expands one event once via PayloadExpander and routes each
33
+ > typed output list to its own independent Process (dict-based API, optional
34
+ > default route); wired in Bytewax via flat_map per route branch
35
+ > JsonStr: Annotated[str, _JsonMarker()] sentinel type for raw JSON fields;
36
+ > mapped to Text() in SQLAlchemy; passes through as str in ClickHouse/Delta
37
+ > ProcessNode union extended to include ExpandRoutes[Any]
38
+
39
+
40
+
41
+ ## 🐛 Fixes
42
+ ### streaming
43
+ - **streaming:** replace assert with explicit TypeError in _adapter.py<br>
44
+ > Bandit B101: assert statements are stripped when running with -O.
45
+ > Replaced both isinstance asserts with explicit TypeError raises to
46
+ > preserve the runtime invariant checks under all execution modes.
47
+
48
+ - **streaming:** age-based buffer flush never fired in IntoTable sink partitions<br>
49
+ > Two bugs prevented buffer_max_age_s from triggering a flush:
50
+ > 1. write_batch([]) returned immediately on empty epochs, so quiet periods
51
+ > never checked the age threshold.
52
+ > 2. _last_append_at was updated right before _should_flush(), making the
53
+ > elapsed-time expression always ≈0ms.
54
+ > Replace _last_append_at with _buffer_started_at (set when the buffer
55
+ > transitions from empty, reset after each flush) in both
56
+ > _SQLAlchemyTablePartition and _DeltaTablePartition. Empty epoch calls
57
+ > now check for an age-based flush before returning.
58
+
59
+ - **streaming:** wire ExpandRoutes runtime and ClickHouse HTTP URL resolution
60
+
61
+ ### compiler
62
+ - **compiler:** add Backend.CLICKHOUSE dispatch in build_plan storage sink resolver
63
+ - **compiler:** validate ExpandRoutes branches for terminal output detection
64
+
65
+
66
+
67
+
68
+ ## ♻️ Refactor
69
+ ### streaming
70
+ - **streaming:** improve Mongo CDC architecture compliance<br>
71
+ > Replace bare except Exception with specific OperationFailure catch
72
+ > Replace type(x).__name__ string dispatch with isinstance and lazy import
73
+ > Type watch_options as Mapping[str, object] to eliminate implicit Any
74
+ > Introduce _BSON_NORMALIZERS dispatch map in normalize_bson_value
75
+ > Define _ChangeStream and _DatabaseLike Protocols for PyMongo types
76
+ > Make FromMongoCDC generic with covariant MongoCDCPayloadT (PEP 696)
77
+ > Add needs_decode: ClassVar[bool] to compiled source types
78
+ > Replace isinstance type-switches with dispatch maps (_SOURCE_BUILDERS,
79
+ > _RUNTIME_SOURCE_BUILDERS) across compiler and bytewax runtime layers
80
+ > Declare typing_extensions>=4.12 as direct dependency
81
+ > Add contract tests for FromMongoCDC generic parametrization
82
+
83
+ - **streaming:** simplify source dispatch and pymongo error handling<br>
84
+ > Replace _RUNTIME_SOURCE_BUILDERS dispatch map with direct isinstance check in build_runtime_source
85
+ > Replace lazy _operation_failure_type() with module-level try/except import for OperationFailure
86
+ > Use explicit isinstance in _source_topic_or_none instead of getattr duck-typing
87
+ > Remove redundant empty-collections branch in _open_change_stream
88
+ > Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
89
+
90
+
91
+
92
+
93
+ ## ✅ Tests
94
+ ### streaming
95
+ - **streaming:** add unit tests for ExpandRoutes fan-out node
96
+
97
+
98
+
99
+
100
+
101
+ # 🚀 Release 0.8.0 ([#30](https://github.com/the-reacher-data/loom-py/pull/30)) ([`702b99e`](https://github.com/the-reacher-data/loom-py/commit/702b99ec75a4130f273322f8eb488637a2f98a14))
102
+
103
+
104
+ ## ✨ Features
105
+ ### streaming
106
+ - **streaming:** add IntoSink/SinkPartition protocols and Decompose node<br>
107
+ > Introduces the two-level contract that makes storage sinks extensible at
108
+ > the node level. Any frozen dataclass satisfying IntoSink is a first-class
109
+ > terminal node — no registration, no inheritance, no framework coupling.
110
+ > core/schema/: new shared module; SchemaMode promoted from ETL (ETL re-exports for backwards compat)
111
+ > nodes/_sink.py: SinkPartition (contravariant per-worker protocol) and IntoSink (runtime-checkable terminal protocol)
112
+ > nodes/_decompose.py: EntityDecomposer protocol and Decompose transformation node
113
+ > validate.py: _is_leaf_terminal() helper unifies all terminal checks; IntoSink recognised as terminal in shape and output validation; _node_output_shape refactored to dispatch map
114
+ > exports: IntoSink, SinkPartition, Decompose, EntityDecomposer in public API
115
+ > Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
116
+
117
+ - **streaming:** add IntoTable sink node and rename EntityDecomposer to PayloadExpander<br>
118
+ > IntoTable: frozen dataclass implementing IntoSink for SQLAlchemy and Delta backends
119
+ > Backend enum: SQLALCHEMY and DELTA variants
120
+ > _SQLAlchemyTablePartition: bulk-insert via engine.begin() per epoch batch
121
+ > _DeltaTablePartition: write via deltalake + polars with validated write mode
122
+ > Rename EntityDecomposer -> PayloadExpander, decompose() -> expand(), targets -> outputs
123
+ > Update both streaming.__init__ and streaming.nodes.__init__ public exports
124
+ > Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
125
+
126
+
127
+ ### streaming/compiler
128
+ - **streaming/compiler:** teach compiler to resolve IntoSink nodes<br>
129
+ > Add CompiledStorageSink to _plan: holds the IntoSink node and its
130
+ > pre-fetched streaming.sinks.<name> config section
131
+ > Add terminal_storage_sinks field to CompiledPlan (default empty dict
132
+ > keeps all existing tests green)
133
+ > Refactor _build_terminal_sinks and all branch builders to return
134
+ > (kafka_sinks, storage_sinks) tuple in a single walk — no duplicate
135
+ > traversal
136
+ > Add _build_storage_sink: resolves config by node.name or passes {}
137
+ > when name is empty (self-configured sinks)
138
+ > Add validate_storage_sinks phase: reports a clear error for every
139
+ > named IntoSink whose streaming.sinks.<name> section is absent
140
+ > Wire validate_storage_sinks into the compiler pipeline
141
+ > Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
142
+
143
+ - **streaming/compiler:** add Decompose shape and structural validation<br>
144
+ > Import Decompose in validate.py
145
+ > Add RECORD to _node_input_shape for Decompose — enforces that it
146
+ > receives individual events, not batches
147
+ > Add Decompose: StreamShape.RECORD to _FIXED_OUTPUT_SHAPES — its
148
+ > output feeds the Router as per-type records
149
+ > Add structural check in _validate_shape_sequence: Decompose must be
150
+ > immediately followed by a Router; clear error message when it is not
151
+ > Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
152
+
153
+
154
+ ### streaming/bytewax
155
+ - **streaming/bytewax:** wire IntoSink nodes to Bytewax output operators<br>
156
+ > Add handlers/storage.py: _StorageSinkPartition wraps loom SinkPartition,
157
+ > extracting payload from Message envelopes; _StorageDynamicSink calls
158
+ > node.build_partition(config, worker_index, worker_count) once per
159
+ > Bytewax worker at startup; _apply_into_sink registers the DynamicSink
160
+ > via bw_output for any IntoSink node found in the compiled plan
161
+ > Register IntoSink in _NODE_HANDLERS dispatch map (dispatcher.py) so
162
+ > _wire_process routes any IntoSink node to _apply_into_sink
163
+ > Add IntoSink pass-through in _execute_router_node (routing.py)
164
+ > consistent with the IntoTopic/Drain pattern for inline Router execution
165
+ > Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
166
+
167
+
168
+
169
+
170
+
171
+
172
+ ## ♻️ Refactor
173
+ ### streaming
174
+ - **streaming:** improve _SQLAlchemyTablePartition with typed columns and pool config<br>
175
+ > Extract _require_sa_url, _sa_engine_kwargs, _sa_type_for, _sa_table_from_struct,
176
+ > _structs_to_rows helpers for readability and single responsibility
177
+ > Map Python types to SA column types (_sa_type_for) with Optional unwrapping
178
+ > and collection → JSON fallback; mirrors _SCALAR_TYPE_MAP from introspection.py
179
+ > Mirror SessionManager pool defaults: pool_pre_ping, echo, pool_size,
180
+ > max_overflow, pool_timeout, pool_recycle, connect_args from config
181
+ > Replace msgspec.structs.asdict cast hack with direct call via _structs_to_rows
182
+ > Drop connection_string fallback — config contract is url only
183
+ > Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
184
+
185
+ - **streaming:** merge sink config from dsl and yaml
186
+ - **streaming:** move table sink into package
187
+ - **streaming:** resolve table sink config via context
188
+ - **streaming:** enforce typed table sink config
189
+
190
+
191
+
192
+ ## ✅ Tests
193
+ ### streaming
194
+ - **streaming:** add IntoTable SQLAlchemy integration tests against SQLite<br>
195
+ > Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
196
+
197
+ - **streaming:** cover resource manager session cache
198
+
199
+
200
+
201
+ ## 🔖 Other
202
+ - Fix Bytewax step flat_map tests
203
+ - Refactor streaming validation helpers<br>
204
+ > --------
205
+ > Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
206
+
207
+
208
+
209
+
1
210
  # 🚀 Release 0.7.0 ([#25](https://github.com/the-reacher-data/loom-py/pull/25)) ([`0d8941a`](https://github.com/the-reacher-data/loom-py/commit/0d8941a724ec768b162a07e756bac3d53157ec85))
2
211
 
3
212
 
@@ -0,0 +1,98 @@
1
+ # 🚀 Release 0.9.0 ([#32](https://github.com/the-reacher-data/loom-py/pull/32)) ([`14072d1`](https://github.com/the-reacher-data/loom-py/commit/14072d1be9212116235f26d7a2590a4f0e622451))
2
+
3
+
4
+ ## ✨ Features
5
+ ### streaming
6
+ - **streaming:** add Mongo CDC source
7
+ - **streaming:** add MongoObjectId and MongoDBRef domain types<br>
8
+ > Replace opaque str/dict BSON normalization with structured domain types:
9
+ > MongoObjectId(id, created_at_ms) preserves ObjectId hex and creation
10
+ > timestamp extracted from the embedded 4-byte BSON timestamp field
11
+ > MongoDBRef(id, collection, database) models cross-collection references
12
+ > with explicit collection and optional database fields
13
+ > MongoCDCEvent.document_id widened to MongoObjectId | str | None to
14
+ > expose rich type when _id is an ObjectId
15
+ > _normalize_objectid and _normalize_dbref updated to produce the new types
16
+ > Guard clause added to _normalize_dbref for None identifier
17
+ > _message_key helper centralizes MongoObjectId → str key extraction
18
+ > MongoObjectId and MongoDBRef exported from loom.streaming public API
19
+ > Contract tests cover DBRef without database, integer id, None id error,
20
+ > and ObjectId without generation_time (created_at_ms=None)
21
+
22
+ - **streaming:** add Backend.CLICKHOUSE with native clickhouse-connect sink<br>
23
+ > Add _ClickHouseTablePartition as a standalone SinkPartition backed by
24
+ > clickhouse-connect (HTTP/2, no SQLAlchemy). Uses a column-oriented buffer
25
+ > layout matching clickhouse-connect's column_oriented=True path, avoiding
26
+ > the internal pivot() transposition for maximum insert throughput.
27
+ > Resolves the _json_serializer crash that occurred when inserting list[str]
28
+ > fields via the SQLAlchemy backend against ClickHouseDialect_asynch. With the
29
+ > native client, Array(String) and all CH-native types work without workarounds.
30
+
31
+ - **streaming:** add ExpandRoutes fan-out node and JsonStr semantic type<br>
32
+ > ExpandRoutes: expands one event once via PayloadExpander and routes each
33
+ > typed output list to its own independent Process (dict-based API, optional
34
+ > default route); wired in Bytewax via flat_map per route branch
35
+ > JsonStr: Annotated[str, _JsonMarker()] sentinel type for raw JSON fields;
36
+ > mapped to Text() in SQLAlchemy; passes through as str in ClickHouse/Delta
37
+ > ProcessNode union extended to include ExpandRoutes[Any]
38
+
39
+
40
+
41
+ ## 🐛 Fixes
42
+ ### streaming
43
+ - **streaming:** replace assert with explicit TypeError in _adapter.py<br>
44
+ > Bandit B101: assert statements are stripped when running with -O.
45
+ > Replaced both isinstance asserts with explicit TypeError raises to
46
+ > preserve the runtime invariant checks under all execution modes.
47
+
48
+ - **streaming:** age-based buffer flush never fired in IntoTable sink partitions<br>
49
+ > Two bugs prevented buffer_max_age_s from triggering a flush:
50
+ > 1. write_batch([]) returned immediately on empty epochs, so quiet periods
51
+ > never checked the age threshold.
52
+ > 2. _last_append_at was updated right before _should_flush(), making the
53
+ > elapsed-time expression always ≈0ms.
54
+ > Replace _last_append_at with _buffer_started_at (set when the buffer
55
+ > transitions from empty, reset after each flush) in both
56
+ > _SQLAlchemyTablePartition and _DeltaTablePartition. Empty epoch calls
57
+ > now check for an age-based flush before returning.
58
+
59
+ - **streaming:** wire ExpandRoutes runtime and ClickHouse HTTP URL resolution
60
+
61
+ ### compiler
62
+ - **compiler:** add Backend.CLICKHOUSE dispatch in build_plan storage sink resolver
63
+ - **compiler:** validate ExpandRoutes branches for terminal output detection
64
+
65
+
66
+
67
+
68
+ ## ♻️ Refactor
69
+ ### streaming
70
+ - **streaming:** improve Mongo CDC architecture compliance<br>
71
+ > Replace bare except Exception with specific OperationFailure catch
72
+ > Replace type(x).__name__ string dispatch with isinstance and lazy import
73
+ > Type watch_options as Mapping[str, object] to eliminate implicit Any
74
+ > Introduce _BSON_NORMALIZERS dispatch map in normalize_bson_value
75
+ > Define _ChangeStream and _DatabaseLike Protocols for PyMongo types
76
+ > Make FromMongoCDC generic with covariant MongoCDCPayloadT (PEP 696)
77
+ > Add needs_decode: ClassVar[bool] to compiled source types
78
+ > Replace isinstance type-switches with dispatch maps (_SOURCE_BUILDERS,
79
+ > _RUNTIME_SOURCE_BUILDERS) across compiler and bytewax runtime layers
80
+ > Declare typing_extensions>=4.12 as direct dependency
81
+ > Add contract tests for FromMongoCDC generic parametrization
82
+
83
+ - **streaming:** simplify source dispatch and pymongo error handling<br>
84
+ > Replace _RUNTIME_SOURCE_BUILDERS dispatch map with direct isinstance check in build_runtime_source
85
+ > Replace lazy _operation_failure_type() with module-level try/except import for OperationFailure
86
+ > Use explicit isinstance in _source_topic_or_none instead of getattr duck-typing
87
+ > Remove redundant empty-collections branch in _open_change_stream
88
+ > Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
89
+
90
+
91
+
92
+
93
+ ## ✅ Tests
94
+ ### streaming
95
+ - **streaming:** add unit tests for ExpandRoutes fan-out node
96
+
97
+
98
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: loom-kernel
3
- Version: 0.7.0
3
+ Version: 0.9.0
4
4
  Summary: Loom Python project
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -9,6 +9,7 @@ Requires-Dist: msgspec<1.0,>=0.18
9
9
  Requires-Dist: omegaconf<3.0,>=2.3
10
10
  Requires-Dist: prometheus-client>=0.20
11
11
  Requires-Dist: structlog<26.0,>=24.4
12
+ Requires-Dist: typing-extensions>=4.12
12
13
  Provides-Extra: cache
13
14
  Requires-Dist: aiocache<1.0,>=0.12; extra == 'cache'
14
15
  Requires-Dist: omegaconf<3.0,>=2.3; extra == 'cache'
@@ -16,6 +17,8 @@ Provides-Extra: celery
16
17
  Requires-Dist: celery<6.0,>=5.3; extra == 'celery'
17
18
  Requires-Dist: kombu<6.0,>=5.3; extra == 'celery'
18
19
  Requires-Dist: redis<6.0,>=5.0; extra == 'celery'
20
+ Provides-Extra: clickhouse
21
+ Requires-Dist: clickhouse-connect<1.0,>=0.7; extra == 'clickhouse'
19
22
  Provides-Extra: config
20
23
  Requires-Dist: fsspec>=2024.2.0; extra == 'config'
21
24
  Requires-Dist: omegaconf<3.0,>=2.3; extra == 'config'
@@ -32,6 +35,7 @@ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2.0,>=1.20; extra == 'etl-
32
35
  Requires-Dist: opentelemetry-exporter-otlp-proto-http<2.0,>=1.20; extra == 'etl-polars'
33
36
  Requires-Dist: opentelemetry-sdk<2.0,>=1.20; extra == 'etl-polars'
34
37
  Requires-Dist: polars<2.0,>=1.0; extra == 'etl-polars'
38
+ Requires-Dist: pyarrow>=14.0; extra == 'etl-polars'
35
39
  Provides-Extra: etl-spark
36
40
  Requires-Dist: delta-spark<4.0,>=3.2; extra == 'etl-spark'
37
41
  Requires-Dist: findspark<3.0,>=2.0; extra == 'etl-spark'
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "loom-kernel"
3
- version = "0.7.0"
3
+ version = "0.9.0"
4
4
  description = "Loom Python project"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -10,6 +10,7 @@ dependencies = [
10
10
  "omegaconf>=2.3,<3.0",
11
11
  "prometheus-client>=0.20",
12
12
  "aiocache>=0.12,<1.0",
13
+ "typing_extensions>=4.12",
13
14
  ]
14
15
 
15
16
  [project.optional-dependencies]
@@ -24,6 +25,9 @@ rest = [
24
25
  sqlalchemy = [
25
26
  "sqlalchemy>=2.0,<3.0",
26
27
  ]
28
+ clickhouse = [
29
+ "clickhouse-connect>=0.7,<1.0",
30
+ ]
27
31
  config = [
28
32
  "omegaconf>=2.3,<3.0",
29
33
  "fsspec>=2024.2.0",
@@ -35,6 +39,7 @@ cache = [
35
39
  etl-polars = [
36
40
  "polars>=1.0,<2.0",
37
41
  "deltalake>=1.5,<2.0",
42
+ "pyarrow>=14.0",
38
43
  "fsspec>=2024.2.0",
39
44
  "opentelemetry-api>=1.20,<2.0",
40
45
  "opentelemetry-sdk>=1.20,<2.0",
@@ -110,6 +115,8 @@ dev = [
110
115
  "ruff>=0.9.0,<1.0",
111
116
  "sqlalchemy>=2.0,<3.0",
112
117
  "polars>=1.0,<2.0",
118
+ "clickhouse-connect>=0.7,<1.0",
119
+ "pyarrow>=14.0",
113
120
  "deltalake>=1.5,<2.0",
114
121
  "fsspec>=2024.2.0",
115
122
  "httpx>=0.28.1",
@@ -122,6 +129,7 @@ dev = [
122
129
  "findspark>=2.0.1",
123
130
  "confluent-kafka>=2.6,<3.0",
124
131
  "bytewax>=0.21",
132
+ "pymongo>=4.6,<5.0",
125
133
  "opentelemetry-api>=1.20,<2.0",
126
134
  "opentelemetry-sdk>=1.20,<2.0",
127
135
  "opentelemetry-exporter-otlp-proto-http>=1.20,<2.0",
@@ -172,6 +180,7 @@ include = [
172
180
  typeCheckingMode = "standard"
173
181
  reportMissingModuleSource = "none"
174
182
  reportMissingImports = "none"
183
+ reportPrivateImportUsage = "none"
175
184
  ignore = [
176
185
  "src/loom/etl/testing/spark.py",
177
186
  ]
@@ -193,9 +202,15 @@ module = [
193
202
  "findspark",
194
203
  "fsspec.*",
195
204
  "chispa.*",
205
+ ]
206
+ ignore_missing_imports = true
207
+
208
+ [[tool.mypy.overrides]]
209
+ module = [
196
210
  "pyarrow.*",
197
211
  ]
198
212
  ignore_missing_imports = true
213
+ follow_imports = "skip"
199
214
 
200
215
  [tool.pytest.ini_options]
201
216
  minversion = "8.0"
@@ -220,7 +235,7 @@ markers = [
220
235
 
221
236
  [tool.commitizen]
222
237
  name = "cz_conventional_commits"
223
- version = "0.7.0"
238
+ version = "0.9.0"
224
239
  tag_format = "v$version"
225
240
  version_files = [
226
241
  "pyproject.toml:project.version",
@@ -20,6 +20,7 @@ class ConfigKey(StrEnum):
20
20
  DATABASE = "database"
21
21
  CELERY = "celery"
22
22
  KAFKA = "kafka"
23
+ MONGO = "mongo"
23
24
  STORAGE = "storage"
24
25
  STREAMING = "streaming"
25
26
  STREAMING_RUNTIME = "streaming.runtime"
@@ -2,10 +2,18 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import warnings
5
6
  from typing import Any
7
+ from urllib.parse import urlparse
6
8
 
7
9
  from loom.core.model import LoomFrozenStruct
8
10
 
11
+ _LOCAL_HOSTS = {"127.0.0.1", "localhost", "::1"}
12
+
13
+
14
+ def _is_local_endpoint(endpoint: str) -> bool:
15
+ return (urlparse(endpoint).hostname or "") in _LOCAL_HOSTS
16
+
9
17
 
10
18
  class OtelConfig(LoomFrozenStruct, frozen=True):
11
19
  """OpenTelemetry SDK/exporter configuration.
@@ -29,7 +37,7 @@ class OtelConfig(LoomFrozenStruct, frozen=True):
29
37
  tracer_version: str = ""
30
38
  protocol: str = "http/protobuf"
31
39
  endpoint: str = ""
32
- insecure: bool = True
40
+ insecure: bool = False
33
41
  headers: dict[str, str] = {}
34
42
  resource_attributes: dict[str, str] = {}
35
43
  span_attributes: dict[str, str] = {}
@@ -46,6 +54,13 @@ class OtelConfig(LoomFrozenStruct, frozen=True):
46
54
  raise ValueError(
47
55
  "observability.otel_config.protocol must be either 'http/protobuf' or 'grpc'."
48
56
  )
57
+ if self.insecure and self.endpoint and not _is_local_endpoint(self.endpoint):
58
+ warnings.warn(
59
+ f"OtelConfig.insecure=True on non-local endpoint {self.endpoint!r}."
60
+ " Set insecure=False for production deployments.",
61
+ UserWarning,
62
+ stacklevel=2,
63
+ )
49
64
 
50
65
 
51
66
  __all__ = ["OtelConfig"]
@@ -23,6 +23,7 @@ from loom.core.model.types import (
23
23
  DateTime,
24
24
  Float,
25
25
  Integer,
26
+ JsonStr,
26
27
  Numeric,
27
28
  String,
28
29
  Text,
@@ -45,6 +46,7 @@ __all__ = [
45
46
  "Float",
46
47
  "Integer",
47
48
  "JSON",
49
+ "JsonStr",
48
50
  "Postgres",
49
51
  "ProjectionField",
50
52
  "LoomStructMeta",
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from typing import Annotated
4
+
3
5
  from loom.core.model.field import ColumnType
4
6
 
5
7
 
@@ -23,3 +25,12 @@ def DateTime(*, tz: bool = True) -> ColumnType:
23
25
 
24
26
  def Numeric(*, precision: int = 10, scale: int = 2) -> ColumnType:
25
27
  return ColumnType("Numeric", args=(precision, scale))
28
+
29
+
30
+ class _JsonMarker:
31
+ """Sentinel that marks a str field as containing serialized JSON."""
32
+
33
+ __slots__ = ()
34
+
35
+
36
+ JsonStr = Annotated[str, _JsonMarker()]
@@ -13,10 +13,19 @@ class PrometheusConfig(LoomFrozenStruct, frozen=True, kw_only=True):
13
13
  """Prometheus scrape endpoint configuration.
14
14
 
15
15
  Args:
16
- path: HTTP path where ``/metrics`` is served.
16
+ path: HTTP path where ``/metrics`` is served. Used by REST services
17
+ that mount the scrape endpoint on an existing FastAPI app.
18
+ port: Port for the standalone HTTP scrape server. Used by long-running
19
+ streaming processes that have no existing HTTP server.
20
+ ``None`` disables the standalone server (default).
21
+ bind_address: Network interface the standalone scrape server binds to.
22
+ Defaults to ``"127.0.0.1"`` (loopback only). Set to ``"0.0.0.0"``
23
+ only when the Prometheus scraper cannot reach the pod via loopback.
17
24
  """
18
25
 
19
26
  path: str = "/metrics"
27
+ port: int | None = None
28
+ bind_address: str = "127.0.0.1"
20
29
 
21
30
 
22
31
  class LogObservabilityConfig(LoomFrozenStruct, frozen=True, kw_only=True):