loom-kernel 0.3.0__tar.gz → 0.5.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 (737) hide show
  1. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/.github/workflows/ci-main.yml +2 -2
  2. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/.github/workflows/ci-pr.yml +2 -2
  3. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/.github/workflows/release.yml +15 -10
  4. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/.gitignore +2 -0
  5. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/.readthedocs.yaml +6 -0
  6. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/CHANGELOG.md +23 -41
  7. loom_kernel-0.5.0/CHANGELOG_RELEASE.md +25 -0
  8. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/PKG-INFO +72 -2
  9. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/README.md +62 -1
  10. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/conf.py +3 -1
  11. loom_kernel-0.5.0/docs/etl/examples.md +29 -0
  12. loom_kernel-0.5.0/docs/etl/testing.md +65 -0
  13. loom_kernel-0.5.0/docs/getting-started/etl.md +136 -0
  14. loom_kernel-0.3.0/docs/guides/quickstart.md → loom_kernel-0.5.0/docs/getting-started/rest.md +6 -5
  15. loom_kernel-0.5.0/docs/getting-started/streaming.md +97 -0
  16. loom_kernel-0.5.0/docs/guides/etl.md +559 -0
  17. loom_kernel-0.5.0/docs/guides/quickstart.md +7 -0
  18. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/index.rst +30 -12
  19. loom_kernel-0.5.0/docs/overview.md +122 -0
  20. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/reference/api/etl.rst +1 -0
  21. loom_kernel-0.5.0/docs/reference/api/streaming.rst +29 -0
  22. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/reference/index.rst +1 -0
  23. loom_kernel-0.5.0/docs/rest/autocrud.md +166 -0
  24. loom_kernel-0.5.0/docs/rest/celery.md +538 -0
  25. loom_kernel-0.5.0/docs/rest/examples.md +642 -0
  26. loom_kernel-0.5.0/docs/rest/testing.md +67 -0
  27. loom_kernel-0.5.0/docs/rest/use-case-dsl.md +477 -0
  28. loom_kernel-0.5.0/docs/streaming/bytewax.md +62 -0
  29. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/pyproject.toml +20 -2
  30. loom_kernel-0.5.0/src/loom/core/async_bridge.py +149 -0
  31. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/backend/core_model.py +2 -4
  32. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/config/__init__.py +11 -1
  33. loom_kernel-0.5.0/src/loom/core/config/configurable.py +78 -0
  34. loom_kernel-0.5.0/src/loom/core/config/observability.py +51 -0
  35. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/engine/__init__.py +1 -2
  36. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/engine/executor.py +2 -4
  37. loom_kernel-0.5.0/src/loom/core/expr/__init__.py +39 -0
  38. loom_kernel-0.5.0/src/loom/core/expr/eval.py +127 -0
  39. loom_kernel-0.5.0/src/loom/core/expr/nodes.py +132 -0
  40. loom_kernel-0.5.0/src/loom/core/expr/refs.py +106 -0
  41. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/logger/config.py +25 -0
  42. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/model/__init__.py +2 -1
  43. loom_kernel-0.5.0/src/loom/core/model/struct.py +38 -0
  44. loom_kernel-0.5.0/src/loom/core/observability.py +59 -0
  45. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/projection/loaders.py +0 -4
  46. loom_kernel-0.5.0/src/loom/core/routing/__init__.py +11 -0
  47. loom_kernel-0.5.0/src/loom/core/routing/ref.py +49 -0
  48. loom_kernel-0.5.0/src/loom/core/routing/resolver.py +63 -0
  49. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/rule.py +1 -2
  50. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/__init__.py +22 -0
  51. loom_kernel-0.5.0/src/loom/etl/backends/_historify/__init__.py +19 -0
  52. loom_kernel-0.5.0/src/loom/etl/backends/_historify/_common.py +43 -0
  53. loom_kernel-0.5.0/src/loom/etl/backends/_historify/_log.py +42 -0
  54. loom_kernel-0.5.0/src/loom/etl/backends/_historify/_ops.py +90 -0
  55. loom_kernel-0.5.0/src/loom/etl/backends/_historify/_snapshot.py +72 -0
  56. loom_kernel-0.5.0/src/loom/etl/backends/_historify/_transform.py +97 -0
  57. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/_write_policy.py +186 -19
  58. loom_kernel-0.5.0/src/loom/etl/backends/polars/_historify.py +192 -0
  59. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/polars/_writer.py +102 -0
  60. loom_kernel-0.5.0/src/loom/etl/backends/spark/_historify.py +227 -0
  61. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/spark/_writer.py +127 -18
  62. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/compiler/_validators.py +3 -0
  63. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/compiler/_validators_step.py +180 -1
  64. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/__init__.py +28 -1
  65. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/expr/_refs.py +9 -8
  66. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/source/_from.py +3 -2
  67. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/target/__init__.py +47 -6
  68. loom_kernel-0.5.0/src/loom/etl/declarative/target/_history/__init__.py +30 -0
  69. loom_kernel-0.5.0/src/loom/etl/declarative/target/_history/_builder.py +241 -0
  70. loom_kernel-0.5.0/src/loom/etl/declarative/target/_history/_enums.py +58 -0
  71. loom_kernel-0.5.0/src/loom/etl/declarative/target/_history/_errors.py +78 -0
  72. loom_kernel-0.5.0/src/loom/etl/declarative/target/_history/_report.py +27 -0
  73. loom_kernel-0.5.0/src/loom/etl/declarative/target/_history/_spec.py +69 -0
  74. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/target/_into.py +3 -2
  75. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/config.py +2 -41
  76. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/prometheus/__init__.py +2 -0
  77. loom_kernel-0.5.0/src/loom/prometheus/kafka.py +156 -0
  78. loom_kernel-0.5.0/src/loom/streaming/__init__.py +104 -0
  79. loom_kernel-0.5.0/src/loom/streaming/bytewax/__init__.py +27 -0
  80. loom_kernel-0.5.0/src/loom/streaming/bytewax/_adapter.py +342 -0
  81. loom_kernel-0.5.0/src/loom/streaming/bytewax/_commit_tracker.py +125 -0
  82. loom_kernel-0.5.0/src/loom/streaming/bytewax/_dlq.py +171 -0
  83. loom_kernel-0.5.0/src/loom/streaming/bytewax/_error_boundary.py +154 -0
  84. loom_kernel-0.5.0/src/loom/streaming/bytewax/_operators.py +365 -0
  85. loom_kernel-0.5.0/src/loom/streaming/bytewax/_output_wiring.py +203 -0
  86. loom_kernel-0.5.0/src/loom/streaming/bytewax/_resource_manager.py +68 -0
  87. loom_kernel-0.5.0/src/loom/streaming/bytewax/_runtime_io.py +489 -0
  88. loom_kernel-0.5.0/src/loom/streaming/bytewax/handlers/__init__.py +1 -0
  89. loom_kernel-0.5.0/src/loom/streaming/bytewax/handlers/_shared.py +355 -0
  90. loom_kernel-0.5.0/src/loom/streaming/bytewax/handlers/boundary.py +14 -0
  91. loom_kernel-0.5.0/src/loom/streaming/bytewax/handlers/dispatcher.py +82 -0
  92. loom_kernel-0.5.0/src/loom/streaming/bytewax/handlers/routing.py +224 -0
  93. loom_kernel-0.5.0/src/loom/streaming/bytewax/handlers/scopes.py +273 -0
  94. loom_kernel-0.5.0/src/loom/streaming/bytewax/handlers/shapes.py +118 -0
  95. loom_kernel-0.5.0/src/loom/streaming/bytewax/handlers/steps.py +219 -0
  96. loom_kernel-0.5.0/src/loom/streaming/bytewax/runner.py +322 -0
  97. loom_kernel-0.5.0/src/loom/streaming/compiler/__init__.py +23 -0
  98. loom_kernel-0.5.0/src/loom/streaming/compiler/_bindings.py +282 -0
  99. loom_kernel-0.5.0/src/loom/streaming/compiler/_compiler.py +53 -0
  100. loom_kernel-0.5.0/src/loom/streaming/compiler/_plan.py +94 -0
  101. loom_kernel-0.5.0/src/loom/streaming/compiler/phases/build_plan.py +276 -0
  102. loom_kernel-0.5.0/src/loom/streaming/compiler/phases/validate.py +432 -0
  103. loom_kernel-0.5.0/src/loom/streaming/core/__init__.py +17 -0
  104. loom_kernel-0.5.0/src/loom/streaming/core/_errors.py +133 -0
  105. loom_kernel-0.5.0/src/loom/streaming/core/_exceptions.py +27 -0
  106. loom_kernel-0.5.0/src/loom/streaming/core/_message.py +63 -0
  107. loom_kernel-0.5.0/src/loom/streaming/core/_typing.py +7 -0
  108. loom_kernel-0.5.0/src/loom/streaming/graph/__init__.py +5 -0
  109. loom_kernel-0.5.0/src/loom/streaming/graph/_flow.py +180 -0
  110. loom_kernel-0.5.0/src/loom/streaming/kafka/__init__.py +106 -0
  111. loom_kernel-0.5.0/src/loom/streaming/kafka/_codec.py +75 -0
  112. loom_kernel-0.5.0/src/loom/streaming/kafka/_config.py +289 -0
  113. loom_kernel-0.5.0/src/loom/streaming/kafka/_errors.py +39 -0
  114. loom_kernel-0.5.0/src/loom/streaming/kafka/_key_resolver.py +64 -0
  115. loom_kernel-0.5.0/src/loom/streaming/kafka/_message.py +152 -0
  116. loom_kernel-0.5.0/src/loom/streaming/kafka/_record.py +33 -0
  117. loom_kernel-0.5.0/src/loom/streaming/kafka/_wire.py +317 -0
  118. loom_kernel-0.5.0/src/loom/streaming/kafka/client/__init__.py +1 -0
  119. loom_kernel-0.5.0/src/loom/streaming/kafka/client/_consumer.py +161 -0
  120. loom_kernel-0.5.0/src/loom/streaming/kafka/client/_producer.py +165 -0
  121. loom_kernel-0.5.0/src/loom/streaming/kafka/client/_protocol.py +73 -0
  122. loom_kernel-0.5.0/src/loom/streaming/kafka/message/__init__.py +1 -0
  123. loom_kernel-0.5.0/src/loom/streaming/kafka/message/_consumer.py +119 -0
  124. loom_kernel-0.5.0/src/loom/streaming/kafka/message/_producer.py +173 -0
  125. loom_kernel-0.5.0/src/loom/streaming/kafka/message/_protocol.py +99 -0
  126. loom_kernel-0.5.0/src/loom/streaming/nodes/__init__.py +82 -0
  127. loom_kernel-0.5.0/src/loom/streaming/nodes/_boundary.py +160 -0
  128. loom_kernel-0.5.0/src/loom/streaming/nodes/_broadcast.py +97 -0
  129. loom_kernel-0.5.0/src/loom/streaming/nodes/_capabilities.py +12 -0
  130. loom_kernel-0.5.0/src/loom/streaming/nodes/_expr_eval.py +31 -0
  131. loom_kernel-0.5.0/src/loom/streaming/nodes/_fork.py +155 -0
  132. loom_kernel-0.5.0/src/loom/streaming/nodes/_helpers.py +26 -0
  133. loom_kernel-0.5.0/src/loom/streaming/nodes/_protocols.py +31 -0
  134. loom_kernel-0.5.0/src/loom/streaming/nodes/_router.py +139 -0
  135. loom_kernel-0.5.0/src/loom/streaming/nodes/_shape.py +117 -0
  136. loom_kernel-0.5.0/src/loom/streaming/nodes/_step.py +158 -0
  137. loom_kernel-0.5.0/src/loom/streaming/nodes/_with.py +289 -0
  138. loom_kernel-0.5.0/src/loom/streaming/nodes/refs.py +13 -0
  139. loom_kernel-0.5.0/src/loom/streaming/observability/__init__.py +29 -0
  140. loom_kernel-0.5.0/src/loom/streaming/observability/config.py +28 -0
  141. loom_kernel-0.5.0/src/loom/streaming/observability/factory.py +47 -0
  142. loom_kernel-0.5.0/src/loom/streaming/observability/observers/__init__.py +29 -0
  143. loom_kernel-0.5.0/src/loom/streaming/observability/observers/composite.py +125 -0
  144. loom_kernel-0.5.0/src/loom/streaming/observability/observers/noop.py +58 -0
  145. loom_kernel-0.5.0/src/loom/streaming/observability/observers/otel.py +232 -0
  146. loom_kernel-0.5.0/src/loom/streaming/observability/observers/protocol.py +174 -0
  147. loom_kernel-0.5.0/src/loom/streaming/observability/observers/structlog.py +158 -0
  148. loom_kernel-0.5.0/src/loom/streaming/testing.py +206 -0
  149. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/testing/runner.py +2 -1
  150. loom_kernel-0.5.0/tests/unit/core/config/test_configurable.py +40 -0
  151. loom_kernel-0.5.0/tests/unit/core/expr/test_expr.py +57 -0
  152. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/repository/sqlalchemy/test_loaders.py +2 -2
  153. loom_kernel-0.5.0/tests/unit/core/routing/test_routing.py +38 -0
  154. loom_kernel-0.5.0/tests/unit/core/test_async_bridge.py +112 -0
  155. loom_kernel-0.5.0/tests/unit/etl/__init__.py +0 -0
  156. loom_kernel-0.5.0/tests/unit/etl/backends/__init__.py +0 -0
  157. loom_kernel-0.5.0/tests/unit/etl/backends/_historify_contract.py +885 -0
  158. loom_kernel-0.5.0/tests/unit/etl/backends/test_historify_common.py +52 -0
  159. loom_kernel-0.5.0/tests/unit/etl/backends/test_polars/__init__.py +0 -0
  160. loom_kernel-0.5.0/tests/unit/etl/backends/test_polars/test_dtype.py +137 -0
  161. loom_kernel-0.5.0/tests/unit/etl/backends/test_polars/test_historify_polars.py +212 -0
  162. loom_kernel-0.5.0/tests/unit/etl/backends/test_spark/__init__.py +0 -0
  163. loom_kernel-0.5.0/tests/unit/etl/backends/test_spark/test_historify_spark.py +238 -0
  164. loom_kernel-0.5.0/tests/unit/etl/backends/test_write_policy_historify.py +283 -0
  165. loom_kernel-0.5.0/tests/unit/etl/checkpoint/__init__.py +0 -0
  166. loom_kernel-0.5.0/tests/unit/etl/checkpoint/backends/__init__.py +0 -0
  167. loom_kernel-0.5.0/tests/unit/etl/compiler/__init__.py +0 -0
  168. loom_kernel-0.5.0/tests/unit/etl/compiler/test_historify_validator.py +432 -0
  169. loom_kernel-0.5.0/tests/unit/etl/io/__init__.py +0 -0
  170. loom_kernel-0.5.0/tests/unit/etl/io/test_history_target.py +739 -0
  171. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/io/test_source.py +3 -1
  172. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/io/test_target.py +7 -1
  173. loom_kernel-0.5.0/tests/unit/etl/schema/__init__.py +0 -0
  174. loom_kernel-0.5.0/tests/unit/etl/sql/__init__.py +0 -0
  175. loom_kernel-0.5.0/tests/unit/etl/storage/__init__.py +0 -0
  176. loom_kernel-0.5.0/tests/unit/etl/storage/test_route_build.py +146 -0
  177. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/test_module_contracts.py +20 -50
  178. loom_kernel-0.5.0/tests/unit/etl/testing/__init__.py +0 -0
  179. loom_kernel-0.5.0/tests/unit/prometheus/__init__.py +0 -0
  180. loom_kernel-0.5.0/tests/unit/rest/__init__.py +0 -0
  181. loom_kernel-0.5.0/tests/unit/streaming/__init__.py +1 -0
  182. loom_kernel-0.5.0/tests/unit/streaming/bytewax/__init__.py +0 -0
  183. loom_kernel-0.5.0/tests/unit/streaming/bytewax/cases.py +160 -0
  184. loom_kernel-0.5.0/tests/unit/streaming/bytewax/conftest.py +94 -0
  185. loom_kernel-0.5.0/tests/unit/streaming/bytewax/test_adapter.py +290 -0
  186. loom_kernel-0.5.0/tests/unit/streaming/bytewax/test_batch_key.py +59 -0
  187. loom_kernel-0.5.0/tests/unit/streaming/bytewax/test_bytewax_dispatcher.py +1007 -0
  188. loom_kernel-0.5.0/tests/unit/streaming/bytewax/test_collect_batch.py +56 -0
  189. loom_kernel-0.5.0/tests/unit/streaming/bytewax/test_error_boundary.py +184 -0
  190. loom_kernel-0.5.0/tests/unit/streaming/bytewax/test_operators.py +169 -0
  191. loom_kernel-0.5.0/tests/unit/streaming/bytewax/test_runner.py +177 -0
  192. loom_kernel-0.5.0/tests/unit/streaming/bytewax/test_runtime_io.py +319 -0
  193. loom_kernel-0.5.0/tests/unit/streaming/bytewax/test_runtime_sink.py +140 -0
  194. loom_kernel-0.5.0/tests/unit/streaming/bytewax/test_runtime_source.py +97 -0
  195. loom_kernel-0.5.0/tests/unit/streaming/compiler/__init__.py +0 -0
  196. loom_kernel-0.5.0/tests/unit/streaming/compiler/cases.py +20 -0
  197. loom_kernel-0.5.0/tests/unit/streaming/compiler/test_async_walk.py +91 -0
  198. loom_kernel-0.5.0/tests/unit/streaming/compiler/test_basics.py +108 -0
  199. loom_kernel-0.5.0/tests/unit/streaming/compiler/test_config_bindings.py +370 -0
  200. loom_kernel-0.5.0/tests/unit/streaming/compiler/test_multi_source.py +77 -0
  201. loom_kernel-0.5.0/tests/unit/streaming/compiler/test_router.py +131 -0
  202. loom_kernel-0.5.0/tests/unit/streaming/compiler/test_window.py +52 -0
  203. loom_kernel-0.5.0/tests/unit/streaming/compiler/test_with.py +103 -0
  204. loom_kernel-0.5.0/tests/unit/streaming/conftest.py +153 -0
  205. loom_kernel-0.5.0/tests/unit/streaming/contracts/__init__.py +0 -0
  206. loom_kernel-0.5.0/tests/unit/streaming/contracts/cases.py +47 -0
  207. loom_kernel-0.5.0/tests/unit/streaming/contracts/test_boundary.py +60 -0
  208. loom_kernel-0.5.0/tests/unit/streaming/contracts/test_message.py +66 -0
  209. loom_kernel-0.5.0/tests/unit/streaming/contracts/test_multi_boundary.py +92 -0
  210. loom_kernel-0.5.0/tests/unit/streaming/contracts/test_steps.py +127 -0
  211. loom_kernel-0.5.0/tests/unit/streaming/flows/__init__.py +1 -0
  212. loom_kernel-0.5.0/tests/unit/streaming/flows/cases/__init__.py +81 -0
  213. loom_kernel-0.5.0/tests/unit/streaming/flows/cases/batch.py +140 -0
  214. loom_kernel-0.5.0/tests/unit/streaming/flows/cases/fork.py +212 -0
  215. loom_kernel-0.5.0/tests/unit/streaming/flows/cases/router.py +54 -0
  216. loom_kernel-0.5.0/tests/unit/streaming/flows/cases/shared.py +204 -0
  217. loom_kernel-0.5.0/tests/unit/streaming/flows/cases/simple.py +38 -0
  218. loom_kernel-0.5.0/tests/unit/streaming/flows/conftest.py +47 -0
  219. loom_kernel-0.5.0/tests/unit/streaming/flows/test_compiler_examples.py +94 -0
  220. loom_kernel-0.5.0/tests/unit/streaming/flows/test_flow_examples.py +205 -0
  221. loom_kernel-0.5.0/tests/unit/streaming/kafka/__init__.py +1 -0
  222. loom_kernel-0.5.0/tests/unit/streaming/kafka/cases.py +19 -0
  223. loom_kernel-0.5.0/tests/unit/streaming/kafka/conftest.py +138 -0
  224. loom_kernel-0.5.0/tests/unit/streaming/kafka/fakes.py +289 -0
  225. loom_kernel-0.5.0/tests/unit/streaming/kafka/test_client.py +333 -0
  226. loom_kernel-0.5.0/tests/unit/streaming/kafka/test_config.py +109 -0
  227. loom_kernel-0.5.0/tests/unit/streaming/kafka/test_key_resolver.py +28 -0
  228. loom_kernel-0.5.0/tests/unit/streaming/kafka/test_message.py +102 -0
  229. loom_kernel-0.5.0/tests/unit/streaming/kafka/test_message_client.py +394 -0
  230. loom_kernel-0.5.0/tests/unit/streaming/kafka/test_multi_wire.py +284 -0
  231. loom_kernel-0.5.0/tests/unit/streaming/kafka/test_observability.py +162 -0
  232. loom_kernel-0.5.0/tests/unit/streaming/kafka/test_settings.py +184 -0
  233. loom_kernel-0.5.0/tests/unit/streaming/kafka/test_wire.py +76 -0
  234. loom_kernel-0.5.0/tests/unit/streaming/nodes/__init__.py +0 -0
  235. loom_kernel-0.5.0/tests/unit/streaming/nodes/conftest.py +123 -0
  236. loom_kernel-0.5.0/tests/unit/streaming/nodes/test_broadcast.py +115 -0
  237. loom_kernel-0.5.0/tests/unit/streaming/nodes/test_logging.py +86 -0
  238. loom_kernel-0.5.0/tests/unit/streaming/observability/__init__.py +0 -0
  239. loom_kernel-0.5.0/tests/unit/streaming/observability/cases.py +139 -0
  240. loom_kernel-0.5.0/tests/unit/streaming/observability/conftest.py +30 -0
  241. loom_kernel-0.5.0/tests/unit/streaming/observability/test_observability_runner.py +87 -0
  242. loom_kernel-0.5.0/tests/unit/streaming/observability/test_protocols.py +78 -0
  243. loom_kernel-0.5.0/tests/unit/streaming/observability/test_registry.py +21 -0
  244. loom_kernel-0.5.0/tests/unit/streaming/observability/test_structlog.py +139 -0
  245. loom_kernel-0.5.0/tests/unit/streaming/support/__init__.py +0 -0
  246. loom_kernel-0.5.0/tests/unit/streaming/support/flow_cases.py +494 -0
  247. loom_kernel-0.5.0/tests/unit/streaming/test_fork.py +131 -0
  248. loom_kernel-0.5.0/tests/unit/streaming/test_otel_observability.py +216 -0
  249. loom_kernel-0.5.0/tests/unit/streaming/test_routing.py +145 -0
  250. loom_kernel-0.5.0/tests/unit/streaming/test_with.py +205 -0
  251. loom_kernel-0.5.0/tests/unit/testing/__init__.py +0 -0
  252. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/uv.lock +75 -2
  253. loom_kernel-0.3.0/CHANGELOG_RELEASE.md +0 -60
  254. loom_kernel-0.3.0/src/loom/core/model/struct.py +0 -14
  255. loom_kernel-0.3.0/tests/unit/etl/storage/test_route_build.py +0 -31
  256. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/.github/workflows/docs.yml +0 -0
  257. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/.pre-commit-config.yaml +0 -0
  258. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/LICENSE +0 -0
  259. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/Makefile +0 -0
  260. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/codecov.yml +0 -0
  261. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/_static/.gitkeep +0 -0
  262. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/_static/custom.css +0 -0
  263. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/_static/logo-transparent.png +0 -0
  264. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/_static/logo.svg +0 -0
  265. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/architecture/adr/README.md +0 -0
  266. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/architecture/clean-architecture.md +0 -0
  267. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/architecture/overview.md +0 -0
  268. /loom_kernel-0.3.0/docs/guides/etl.md → /loom_kernel-0.5.0/docs/etl/pipelines.md +0 -0
  269. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/examples-repo/index.md +0 -0
  270. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/guides/autocrud.md +0 -0
  271. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/guides/celery.md +0 -0
  272. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/guides/fake-repo-examples.md +0 -0
  273. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/guides/use-case-dsl.md +0 -0
  274. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/reference/api/core.rst +0 -0
  275. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/reference/api/repository.rst +0 -0
  276. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/reference/api/rest.rst +0 -0
  277. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/reference/api/testing.rst +0 -0
  278. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/docs/requirements.txt +0 -0
  279. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/sonar-project.properties +0 -0
  280. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/__init__.py +0 -0
  281. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/celery/__init__.py +0 -0
  282. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/celery/auto.py +0 -0
  283. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/celery/bootstrap.py +0 -0
  284. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/celery/config.py +0 -0
  285. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/celery/constants.py +0 -0
  286. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/celery/event_loop.py +0 -0
  287. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/celery/runner.py +0 -0
  288. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/celery/service.py +0 -0
  289. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/backend/__init__.py +0 -0
  290. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/backend/protocol.py +0 -0
  291. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/backend/sqlalchemy.py +0 -0
  292. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/bootstrap/__init__.py +0 -0
  293. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
  294. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/bootstrap/kernel.py +0 -0
  295. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/__init__.py +0 -0
  296. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/abc/__init__.py +0 -0
  297. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/abc/backend.py +0 -0
  298. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/abc/config.py +0 -0
  299. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/abc/dependency.py +0 -0
  300. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/codec.py +0 -0
  301. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/decorators.py +0 -0
  302. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/dependency.py +0 -0
  303. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/gateway.py +0 -0
  304. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/keys.py +0 -0
  305. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/repository.py +0 -0
  306. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/cache/serializer.py +0 -0
  307. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/command/__init__.py +0 -0
  308. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/command/adapter.py +0 -0
  309. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/command/base.py +0 -0
  310. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/command/field.py +0 -0
  311. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/command/introspection.py +0 -0
  312. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/config/errors.py +0 -0
  313. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/config/keys.py +0 -0
  314. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/config/loader.py +0 -0
  315. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/config/model.py +0 -0
  316. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/config/resolver.py +0 -0
  317. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/contracts/__init__.py +0 -0
  318. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/contracts/manifest.py +0 -0
  319. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/di/__init__.py +0 -0
  320. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/di/container.py +0 -0
  321. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/di/scope.py +0 -0
  322. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/discovery/__init__.py +0 -0
  323. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/discovery/_utils.py +0 -0
  324. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/discovery/base.py +0 -0
  325. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/discovery/interfaces.py +0 -0
  326. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/discovery/manifest.py +0 -0
  327. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/discovery/modules.py +0 -0
  328. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/engine/compilable.py +0 -0
  329. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/engine/compiler.py +0 -0
  330. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/engine/events.py +0 -0
  331. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/engine/metrics.py +0 -0
  332. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/engine/plan.py +0 -0
  333. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/errors/__init__.py +0 -0
  334. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/errors/codes.py +0 -0
  335. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/errors/errors.py +0 -0
  336. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/job/__init__.py +0 -0
  337. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/job/callback.py +0 -0
  338. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/job/context.py +0 -0
  339. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/job/handle.py +0 -0
  340. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/job/job.py +0 -0
  341. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/job/service.py +0 -0
  342. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/logger/__init__.py +0 -0
  343. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/logger/abc.py +0 -0
  344. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/logger/registry.py +0 -0
  345. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/logger/structlogger.py +0 -0
  346. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/model/base.py +0 -0
  347. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/model/enums.py +0 -0
  348. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/model/field.py +0 -0
  349. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/model/introspection.py +0 -0
  350. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/model/projection.py +0 -0
  351. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/model/relation.py +0 -0
  352. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/model/timestamped.py +0 -0
  353. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/model/types.py +0 -0
  354. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/model/types_postgres.py +0 -0
  355. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/projection/__init__.py +0 -0
  356. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/projection/runtime.py +0 -0
  357. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/__init__.py +0 -0
  358. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/abc/__init__.py +0 -0
  359. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/abc/query.py +0 -0
  360. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/abc/repo_for.py +0 -0
  361. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/abc/repository.py +0 -0
  362. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/mutation.py +0 -0
  363. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/registration.py +0 -0
  364. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/registry.py +0 -0
  365. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
  366. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
  367. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
  368. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
  369. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
  370. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
  371. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
  372. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
  373. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
  374. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
  375. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
  376. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
  377. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
  378. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
  379. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
  380. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
  381. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
  382. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
  383. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
  384. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
  385. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/response/__init__.py +0 -0
  386. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/response/base.py +0 -0
  387. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/tracing/__init__.py +0 -0
  388. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/tracing/context.py +0 -0
  389. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/transport/__init__.py +0 -0
  390. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/transport/adapter.py +0 -0
  391. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/uow/__init__.py +0 -0
  392. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/uow/abc.py +0 -0
  393. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/uow/context.py +0 -0
  394. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/__init__.py +0 -0
  395. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/_predicates.py +0 -0
  396. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/compute.py +0 -0
  397. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/constants.py +0 -0
  398. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/factory.py +0 -0
  399. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/field_ref.py +0 -0
  400. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/invoker.py +0 -0
  401. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/keys.py +0 -0
  402. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/markers.py +0 -0
  403. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/registry.py +0 -0
  404. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/core/use_case/use_case.py +0 -0
  405. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/__init__.py +0 -0
  406. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/_format_registry.py +0 -0
  407. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/_merge.py +0 -0
  408. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/_predicate.py +0 -0
  409. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
  410. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
  411. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
  412. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/polars/__init__.py +0 -0
  413. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
  414. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
  415. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
  416. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/polars/_reader.py +0 -0
  417. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/polars/_schema.py +0 -0
  418. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
  419. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/polars/provider.py +0 -0
  420. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/spark/__init__.py +0 -0
  421. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
  422. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/spark/_reader.py +0 -0
  423. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/spark/_schema.py +0 -0
  424. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
  425. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/backends/spark/provider.py +0 -0
  426. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/checkpoint/__init__.py +0 -0
  427. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
  428. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
  429. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
  430. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/checkpoint/_paths.py +0 -0
  431. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/checkpoint/_scope.py +0 -0
  432. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/checkpoint/_store.py +0 -0
  433. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/compiler/__init__.py +0 -0
  434. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/compiler/_binding.py +0 -0
  435. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/compiler/_compiler.py +0 -0
  436. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/compiler/_errors.py +0 -0
  437. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/compiler/_plan.py +0 -0
  438. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
  439. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/_format.py +0 -0
  440. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/_read_options.py +0 -0
  441. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/_utils.py +0 -0
  442. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/_write_options.py +0 -0
  443. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
  444. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/expr/_params.py +0 -0
  445. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
  446. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
  447. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/source/__init__.py +0 -0
  448. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/source/_specs.py +0 -0
  449. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/target/_file.py +0 -0
  450. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
  451. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/target/_table.py +0 -0
  452. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/declarative/target/_temp.py +0 -0
  453. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/executor/__init__.py +0 -0
  454. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/executor/_dispatcher.py +0 -0
  455. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/executor/_executor.py +0 -0
  456. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/__init__.py +0 -0
  457. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/factory.py +0 -0
  458. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/observers/__init__.py +0 -0
  459. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/observers/_labels.py +0 -0
  460. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/observers/composite.py +0 -0
  461. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/observers/noop.py +0 -0
  462. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/observers/otel.py +0 -0
  463. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/observers/protocol.py +0 -0
  464. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/observers/structlog.py +0 -0
  465. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/recording/__init__.py +0 -0
  466. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/recording/_recorder.py +0 -0
  467. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/records.py +0 -0
  468. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/sinks/__init__.py +0 -0
  469. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/sinks/_protocol.py +0 -0
  470. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/sinks/_table.py +0 -0
  471. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/observability/sinks/_writer.py +0 -0
  472. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/pipeline/__init__.py +0 -0
  473. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/pipeline/_generics.py +0 -0
  474. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/pipeline/_params.py +0 -0
  475. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
  476. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/pipeline/_process.py +0 -0
  477. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/pipeline/_sql.py +0 -0
  478. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/pipeline/_step.py +0 -0
  479. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
  480. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/runner/__init__.py +0 -0
  481. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/runner/_providers.py +0 -0
  482. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/runner/_wiring.py +0 -0
  483. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/runner/config_loader.py +0 -0
  484. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/runner/core.py +0 -0
  485. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/runner/errors.py +0 -0
  486. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/runner/filtering.py +0 -0
  487. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/runtime/__init__.py +0 -0
  488. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/runtime/contracts.py +0 -0
  489. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/schema/__init__.py +0 -0
  490. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/schema/_contract.py +0 -0
  491. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/schema/_schema.py +0 -0
  492. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/storage/__init__.py +0 -0
  493. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/storage/_config.py +0 -0
  494. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/storage/_file_locator.py +0 -0
  495. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/storage/_locator.py +0 -0
  496. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/storage/routing.py +0 -0
  497. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/testing/__init__.py +0 -0
  498. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/testing/_result.py +0 -0
  499. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/testing/_runners.py +0 -0
  500. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/testing/_scenario.py +0 -0
  501. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/testing/_stubs.py +0 -0
  502. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/etl/testing/spark.py +0 -0
  503. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/prometheus/adapter.py +0 -0
  504. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/prometheus/middleware.py +0 -0
  505. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/__init__.py +0 -0
  506. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/adapter.py +0 -0
  507. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/autocrud.py +0 -0
  508. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/compiler.py +0 -0
  509. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/constants.py +0 -0
  510. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/errors.py +0 -0
  511. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/fastapi/__init__.py +0 -0
  512. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/fastapi/app.py +0 -0
  513. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/fastapi/auto.py +0 -0
  514. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/fastapi/openapi.py +0 -0
  515. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/fastapi/response.py +0 -0
  516. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
  517. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/middleware.py +0 -0
  518. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/model.py +0 -0
  519. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/rest/rest_adapter.py +0 -0
  520. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/testing/__init__.py +0 -0
  521. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/testing/golden.py +0 -0
  522. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/testing/http_harness.py +0 -0
  523. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/testing/in_memory.py +0 -0
  524. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/src/loom/testing/repository_harness.py +0 -0
  525. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/__init__.py +0 -0
  526. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/conftest.py +0 -0
  527. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/golden/__init__.py +0 -0
  528. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/golden/baselines/.gitkeep +0 -0
  529. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/golden/outputs/.gitkeep +0 -0
  530. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/golden/plans/.gitkeep +0 -0
  531. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/helpers/__init__.py +0 -0
  532. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/__init__.py +0 -0
  533. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/celery_bootstrap/__init__.py +0 -0
  534. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/celery_bootstrap/config/conf.celery.integration.yaml +0 -0
  535. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/celery_bootstrap/test_auto_create_app_integration.py +0 -0
  536. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/celery_bootstrap/test_bootstrap_worker.py +0 -0
  537. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/conftest.py +0 -0
  538. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/core/__init__.py +0 -0
  539. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/core/repository/__init__.py +0 -0
  540. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/core/repository/sqlalchemy/__init__.py +0 -0
  541. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/core/repository/sqlalchemy/conftest.py +0 -0
  542. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/core/repository/sqlalchemy/test_cache_integration.py +0 -0
  543. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/core/repository/sqlalchemy/test_repository_integration.py +0 -0
  544. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/core/rest/__init__.py +0 -0
  545. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/core/rest/test_auto_interface_integration.py +0 -0
  546. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/core/rest/test_fastapi_app_integration.py +0 -0
  547. {loom_kernel-0.3.0/tests/integration/fake_repo → loom_kernel-0.5.0/tests/integration/core/use_case}/__init__.py +0 -0
  548. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/core/use_case/test_custom_repository_integration.py +0 -0
  549. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/core/use_case/test_use_case_crud_integration.py +0 -0
  550. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/etl/__init__.py +0 -0
  551. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/etl/test_runner_integration.py +0 -0
  552. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/etl/test_runtime_contracts.py +0 -0
  553. {loom_kernel-0.3.0/tests/integration/fake_repo/product/category → loom_kernel-0.5.0/tests/integration/fake_repo}/__init__.py +0 -0
  554. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/config/__init__.py +0 -0
  555. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/config/conf.interfaces.yaml +0 -0
  556. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/config/conf.manifest.yaml +0 -0
  557. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/config/conf.modules.yaml +0 -0
  558. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/config/conf.yaml +0 -0
  559. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/main.py +0 -0
  560. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/manifest.py +0 -0
  561. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/__init__.py +0 -0
  562. {loom_kernel-0.3.0/tests/integration/fake_repo/product/review → loom_kernel-0.5.0/tests/integration/fake_repo/product/category}/__init__.py +0 -0
  563. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/category/model.py +0 -0
  564. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/category/schemas.py +0 -0
  565. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/interface.py +0 -0
  566. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/jobs.py +0 -0
  567. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/model.py +0 -0
  568. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/relations.py +0 -0
  569. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/repository.py +0 -0
  570. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/repository_contract.py +0 -0
  571. {loom_kernel-0.3.0/tests/unit/celery_bootstrap → loom_kernel-0.5.0/tests/integration/fake_repo/product/review}/__init__.py +0 -0
  572. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/review/model.py +0 -0
  573. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/review/schemas.py +0 -0
  574. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/schemas.py +0 -0
  575. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/fake_repo/product/use_cases.py +0 -0
  576. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/support/__init__.py +0 -0
  577. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/integration/support/logical_repo_fixtures.py +0 -0
  578. {loom_kernel-0.3.0/tests/unit/celery_jobs → loom_kernel-0.5.0/tests/unit}/__init__.py +0 -0
  579. {loom_kernel-0.3.0/tests/unit/core/backend → loom_kernel-0.5.0/tests/unit/celery_bootstrap}/__init__.py +0 -0
  580. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/celery_bootstrap/test_bootstrap.py +0 -0
  581. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/celery_bootstrap/test_event_loop.py +0 -0
  582. {loom_kernel-0.3.0/tests/unit/core/bootstrap → loom_kernel-0.5.0/tests/unit/celery_jobs}/__init__.py +0 -0
  583. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/celery_jobs/test_auto.py +0 -0
  584. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/celery_jobs/test_celery_service.py +0 -0
  585. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/celery_jobs/test_config.py +0 -0
  586. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/celery_jobs/test_runner.py +0 -0
  587. {loom_kernel-0.3.0/tests/unit/core/command → loom_kernel-0.5.0/tests/unit/core}/__init__.py +0 -0
  588. {loom_kernel-0.3.0/tests/unit/core/config → loom_kernel-0.5.0/tests/unit/core/backend}/__init__.py +0 -0
  589. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/backend/test_backend_compiler.py +0 -0
  590. {loom_kernel-0.3.0/tests/unit/core/di → loom_kernel-0.5.0/tests/unit/core/bootstrap}/__init__.py +0 -0
  591. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/bootstrap/test_bootstrap.py +0 -0
  592. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/bootstrap/test_bootstrap_metrics.py +0 -0
  593. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/bootstrap/test_kernel.py +0 -0
  594. {loom_kernel-0.3.0/tests/unit/core/engine → loom_kernel-0.5.0/tests/unit/core/cache}/__init__.py +0 -0
  595. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/cache/test_cached_repository.py +0 -0
  596. {loom_kernel-0.3.0/tests/unit/core/errors → loom_kernel-0.5.0/tests/unit/core/command}/__init__.py +0 -0
  597. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/command/test_command_base.py +0 -0
  598. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/command/test_command_field.py +0 -0
  599. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/command/test_command_patch.py +0 -0
  600. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/command/test_introspection.py +0 -0
  601. {loom_kernel-0.3.0/tests/unit/core/job → loom_kernel-0.5.0/tests/unit/core/config}/__init__.py +0 -0
  602. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/config/test_config.py +0 -0
  603. {loom_kernel-0.3.0/tests/unit/core/model → loom_kernel-0.5.0/tests/unit/core/di}/__init__.py +0 -0
  604. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/di/test_container.py +0 -0
  605. {loom_kernel-0.3.0/tests/unit/core/tracing → loom_kernel-0.5.0/tests/unit/core/discovery}/__init__.py +0 -0
  606. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/discovery/test_manifest.py +0 -0
  607. {loom_kernel-0.3.0/tests/unit/core/uow → loom_kernel-0.5.0/tests/unit/core/engine}/__init__.py +0 -0
  608. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/engine/test_compiler.py +0 -0
  609. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/engine/test_executor.py +0 -0
  610. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/engine/test_executor_trace.py +0 -0
  611. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/engine/test_executor_uow.py +0 -0
  612. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/engine/test_metrics.py +0 -0
  613. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/engine/test_plan.py +0 -0
  614. {loom_kernel-0.3.0/tests/unit/core/use_case → loom_kernel-0.5.0/tests/unit/core/errors}/__init__.py +0 -0
  615. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/errors/test_errors.py +0 -0
  616. {loom_kernel-0.3.0/tests/unit/etl → loom_kernel-0.5.0/tests/unit/core/expr}/__init__.py +0 -0
  617. {loom_kernel-0.3.0/tests/unit/etl/backends/test_polars → loom_kernel-0.5.0/tests/unit/core/job}/__init__.py +0 -0
  618. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/job/conftest.py +0 -0
  619. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/job/test_callback.py +0 -0
  620. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/job/test_context.py +0 -0
  621. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/job/test_handle.py +0 -0
  622. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/job/test_inline_service.py +0 -0
  623. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/job/test_job.py +0 -0
  624. {loom_kernel-0.3.0/tests/unit/etl/backends/test_spark → loom_kernel-0.5.0/tests/unit/core/logger}/__init__.py +0 -0
  625. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/logger/test_registry.py +0 -0
  626. {loom_kernel-0.3.0/tests/unit/etl/checkpoint → loom_kernel-0.5.0/tests/unit/core/model}/__init__.py +0 -0
  627. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/model/test_model.py +0 -0
  628. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/model/test_struct.py +0 -0
  629. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/model/test_timestamped.py +0 -0
  630. {loom_kernel-0.3.0/tests/unit/etl/compiler → loom_kernel-0.5.0/tests/unit/core/projection}/__init__.py +0 -0
  631. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/projection/test_runtime.py +0 -0
  632. {loom_kernel-0.3.0/tests/unit/etl/io → loom_kernel-0.5.0/tests/unit/core/repository}/__init__.py +0 -0
  633. {loom_kernel-0.3.0/tests/unit/etl/schema → loom_kernel-0.5.0/tests/unit/core/repository/abc}/__init__.py +0 -0
  634. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/repository/abc/conftest.py +0 -0
  635. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/repository/abc/test_query.py +0 -0
  636. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/repository/abc/test_repository_contract.py +0 -0
  637. {loom_kernel-0.3.0/tests/unit/etl/sql → loom_kernel-0.5.0/tests/unit/core/repository/sqlalchemy}/__init__.py +0 -0
  638. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/repository/sqlalchemy/conftest.py +0 -0
  639. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/repository/sqlalchemy/test_repository.py +0 -0
  640. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/repository/sqlalchemy/test_transactional.py +0 -0
  641. {loom_kernel-0.3.0/tests/unit/etl/storage → loom_kernel-0.5.0/tests/unit/core/routing}/__init__.py +0 -0
  642. {loom_kernel-0.3.0/tests/unit/prometheus → loom_kernel-0.5.0/tests/unit/core/tracing}/__init__.py +0 -0
  643. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/tracing/test_context.py +0 -0
  644. {loom_kernel-0.3.0/tests/unit/rest → loom_kernel-0.5.0/tests/unit/core/uow}/__init__.py +0 -0
  645. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/uow/test_executor_uow.py +0 -0
  646. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/uow/test_sqlalchemy_uow.py +0 -0
  647. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/uow/test_uow_protocols.py +0 -0
  648. {loom_kernel-0.3.0/tests/unit/testing → loom_kernel-0.5.0/tests/unit/core/use_case}/__init__.py +0 -0
  649. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/use_case/test_compute.py +0 -0
  650. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/use_case/test_factory.py +0 -0
  651. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/use_case/test_field_ref.py +0 -0
  652. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/use_case/test_invoker.py +0 -0
  653. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/use_case/test_markers.py +0 -0
  654. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/use_case/test_rule.py +0 -0
  655. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/core/use_case/test_use_case.py +0 -0
  656. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_polars/conftest.py +0 -0
  657. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_polars/test_apply_schema.py +0 -0
  658. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_polars/test_backend.py +0 -0
  659. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_polars/test_file_writer.py +0 -0
  660. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_polars/test_predicate_pushdown.py +0 -0
  661. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_polars/test_reader_columns.py +0 -0
  662. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_polars/test_reader_json_columns.py +0 -0
  663. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_polars/test_step_execution.py +0 -0
  664. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_polars/test_upsert_writer.py +0 -0
  665. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_polars/test_writer_to_frame.py +0 -0
  666. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_spark/conftest.py +0 -0
  667. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_spark/test_dtype.py +0 -0
  668. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_spark/test_spark_apply_schema.py +0 -0
  669. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_spark/test_step_execution.py +0 -0
  670. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/backends/test_spark/test_writer_to_frame.py +0 -0
  671. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/checkpoint/backends/test_checkpoint_polars.py +0 -0
  672. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/checkpoint/test_checkpoint_paths.py +0 -0
  673. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/checkpoint/test_cleaners.py +0 -0
  674. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/checkpoint/test_store.py +0 -0
  675. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_catalog_validator.py +0 -0
  676. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_compiler.py +0 -0
  677. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_compiler_catalog.py +0 -0
  678. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_compiler_upsert.py +0 -0
  679. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_errors.py +0 -0
  680. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_errors_additional_factories.py +0 -0
  681. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_errors_runtime_factories.py +0 -0
  682. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_param_exprs_validator.py +0 -0
  683. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_plan_traversal.py +0 -0
  684. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_step_validator.py +0 -0
  685. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_structural.py +0 -0
  686. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_temp_validator.py +0 -0
  687. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/compiler/test_upsert_validator.py +0 -0
  688. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/conftest.py +0 -0
  689. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/io/test_source_json.py +0 -0
  690. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/io/test_source_options.py +0 -0
  691. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/io/test_utils.py +0 -0
  692. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/io/test_variants.py +0 -0
  693. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/pipeline/__init__.py +0 -0
  694. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/pipeline/test_pipeline_process.py +0 -0
  695. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/pipeline/test_proxy.py +0 -0
  696. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/pipeline/test_step.py +0 -0
  697. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/schema/test_contract.py +0 -0
  698. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/schema/test_schema.py +0 -0
  699. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/schema/test_table.py +0 -0
  700. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/sql/test_merge.py +0 -0
  701. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/sql/test_predicate.py +0 -0
  702. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/sql/test_predicate_dialect.py +0 -0
  703. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/sql/test_sql_runtime.py +0 -0
  704. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/storage/test_backend_factory.py +0 -0
  705. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/storage/test_io_protocols.py +0 -0
  706. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/storage/test_locator.py +0 -0
  707. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/storage/test_observability_and_protocols.py +0 -0
  708. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/storage/test_schema_readers.py +0 -0
  709. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/storage/test_storage_config.py +0 -0
  710. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/test_config_loader.py +0 -0
  711. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/test_executor.py +0 -0
  712. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/test_format_registry.py +0 -0
  713. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/test_observer.py +0 -0
  714. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/test_observer_internals.py +0 -0
  715. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/test_public_api_discovery.py +0 -0
  716. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/test_record_schema_coverage.py +0 -0
  717. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/test_runner.py +0 -0
  718. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/test_runner_errors.py +0 -0
  719. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/test_spark_testing.py +0 -0
  720. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/testing/test_runners.py +0 -0
  721. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/testing/test_scenario_and_stubs.py +0 -0
  722. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/etl/testing/test_spark_helpers.py +0 -0
  723. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/prometheus/test_adapter.py +0 -0
  724. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/prometheus/test_middleware.py +0 -0
  725. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/rest/test_autocrud.py +0 -0
  726. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/rest/test_fastapi_auto_logger.py +0 -0
  727. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/rest/test_middleware.py +0 -0
  728. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/rest/test_pydantic_adapter.py +0 -0
  729. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/rest/test_response.py +0 -0
  730. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/rest/test_rest_adapter.py +0 -0
  731. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/rest/test_rest_compiler.py +0 -0
  732. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/rest/test_rest_model.py +0 -0
  733. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/rest/test_router_runtime.py +0 -0
  734. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/testing/test_golden.py +0 -0
  735. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/testing/test_http_harness.py +0 -0
  736. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/testing/test_in_memory.py +0 -0
  737. {loom_kernel-0.3.0 → loom_kernel-0.5.0}/tests/unit/testing/test_runner.py +0 -0
@@ -88,7 +88,7 @@ jobs:
88
88
  uv export --frozen --only-group dev --no-hashes --no-emit-project \
89
89
  -o "$MANIFEST_DIR/requirements-dev.txt"
90
90
 
91
- for extra in rest sqlalchemy config cache pyspark prometheus celery; do
91
+ for extra in rest sqlalchemy config cache pyspark prometheus celery streaming; do
92
92
  uv export --frozen --no-default-groups --no-dev --extra "$extra" \
93
93
  --no-hashes --no-emit-project \
94
94
  -o "$MANIFEST_DIR/requirements-extra-${extra}.txt"
@@ -103,7 +103,7 @@ jobs:
103
103
  --file="$MANIFEST_DIR/requirements-dev.txt" --package-manager=pip \
104
104
  --project-name="loom-py/dev" --target-reference="${GITHUB_REF_NAME:-master}"
105
105
 
106
- for extra in rest sqlalchemy config cache pyspark prometheus celery; do
106
+ for extra in rest sqlalchemy config cache pyspark prometheus celery streaming; do
107
107
  python -m pip install -r "$MANIFEST_DIR/requirements-extra-${extra}.txt"
108
108
  snyk monitor --skip-unresolved \
109
109
  --file="$MANIFEST_DIR/requirements-extra-${extra}.txt" \
@@ -142,7 +142,7 @@ jobs:
142
142
  uv export --frozen --only-group dev --no-hashes --no-emit-project \
143
143
  -o "$MANIFEST_DIR/requirements-dev.txt"
144
144
 
145
- for extra in rest sqlalchemy config cache pyspark prometheus celery; do
145
+ for extra in rest sqlalchemy config cache pyspark prometheus celery streaming; do
146
146
  uv export --frozen --no-default-groups --no-dev --extra "$extra" \
147
147
  --no-hashes --no-emit-project \
148
148
  -o "$MANIFEST_DIR/requirements-extra-${extra}.txt"
@@ -162,7 +162,7 @@ jobs:
162
162
  --package-manager=pip \
163
163
  --project-name="loom-py/dev"
164
164
 
165
- for extra in rest sqlalchemy config cache pyspark prometheus celery; do
165
+ for extra in rest sqlalchemy config cache pyspark prometheus celery streaming; do
166
166
  python -m pip install -r "$MANIFEST_DIR/requirements-extra-${extra}.txt"
167
167
  snyk test --severity-threshold=high \
168
168
  --skip-unresolved \
@@ -99,23 +99,28 @@ jobs:
99
99
  git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
100
100
 
101
101
  BRANCH="docs/release-v${VERSION}"
102
- git checkout -b "${BRANCH}"
102
+ git checkout -B "${BRANCH}"
103
103
 
104
104
  if [ -f CHANGELOG_RELEASE.md ]; then
105
- cat CHANGELOG_RELEASE.md CHANGELOG.md > CHANGELOG_MERGED.md
106
- mv CHANGELOG_MERGED.md CHANGELOG.md
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
107
110
  fi
108
111
 
109
112
  git add pyproject.toml CHANGELOG.md
110
113
  git diff --staged --quiet && exit 0
111
114
  git commit -m "chore(release): bump version to ${VERSION}"
112
- git push origin "${BRANCH}"
113
-
114
- gh pr create \
115
- --title "chore(release): bump version to ${VERSION}" \
116
- --body "Automated version bump and changelog update after release v${VERSION}." \
117
- --base master \
118
- --head "${BRANCH}"
115
+ git push origin "${BRANCH}" --force
116
+
117
+ if ! gh pr list --head "${BRANCH}" --state open --json number --jq '.[0].number' | grep -qE '^[0-9]+$'; then
118
+ gh pr create \
119
+ --title "chore(release): bump version to ${VERSION}" \
120
+ --body "Automated version bump and changelog update after release v${VERSION}." \
121
+ --base master \
122
+ --head "${BRANCH}"
123
+ fi
119
124
 
120
125
  gh pr merge "${BRANCH}" --squash --auto --delete-branch
121
126
 
@@ -16,9 +16,11 @@ wheels/
16
16
  coverage.xml
17
17
  htmlcov/
18
18
  .vscode/
19
+ .pi/
19
20
  docs/__pycache__/
20
21
  .claude/
21
22
  .claude.md
23
+ CLAUDE.md
22
24
  AGENTS.md
23
25
 
24
26
  # Internal discussion docs (not part of distributable source)
@@ -13,3 +13,9 @@ python:
13
13
  - requirements: docs/requirements.txt
14
14
  - method: pip
15
15
  path: .
16
+ extra_requirements:
17
+ - rest
18
+ - sqlalchemy
19
+ - cache
20
+ - config
21
+ - prometheus
@@ -1,58 +1,42 @@
1
- # 🚀 Release 0.3.0 ([#14](https://github.com/the-reacher-data/loom-py/pull/14)) ([`ef414c5`](https://github.com/the-reacher-data/loom-py/commit/ef414c5bfd303296af450840318dfbe9d301e5d1))
1
+ # 🚀 Release 0.5.0 ([#20](https://github.com/the-reacher-data/loom-py/pull/20)) ([`70f7cf8`](https://github.com/the-reacher-data/loom-py/commit/70f7cf85275fcc1f590e06f980dfac91cad50893))
2
2
 
3
3
 
4
4
  ## ✨ Features
5
+ ### core
6
+ - **core:** add shared expression routing primitives
7
+
8
+ ### streaming
9
+ - **streaming:** add process DSL and routing
10
+ - **streaming:** add kafka transport and observability
11
+ - **streaming:** allow task resource kwargs
12
+ - **streaming:** add scoped dependency nodes
13
+ - **streaming:** make tasks configurable
14
+
5
15
  ### config
6
- - **config:** add cloud URI support and pluggable resolver extension point<br>
7
- > Add fsspec as a hard dependency of loom[config]
8
- > load_config() now accepts s3://, gs://, abfss://, r2:// URIs via fsspec
9
- > Add ConfigResolver protocol for pluggable ${prefix:key} resolution at
10
- > parse time (enables SSM, Key Vault, etc. without baking secrets into images)
11
- > Resolver registration is idempotent; resolvers are evaluated at job startup
12
- > so secret rotation takes effect on the next run
13
- > Migrate loom.etl.runner.config_loader to use core load_config, removing
14
- > the parallel OmegaConf implementation
15
- > ETL _load_yaml inherits cloud URI and resolver support transparently
16
+ - **config:** add declarative config bindings
16
17
 
17
18
 
18
- ### etl
19
- - **etl:** add FileLocator with explicit alias API for file routes<br>
20
- > Introduces `FileLocator` protocol and `MappingFileLocator` so that
21
- > `FromFile.alias("name")` / `IntoFile.alias("name")` specs resolve at
22
- > runtime through `storage.files` config rather than hard-coded URIs.
23
- > `FileLocation` / `FileLocator` / `MappingFileLocator` in `storage/_file_locator.py`
24
- > `StorageConfig.to_file_locator()` returns `MappingFileLocator | None`
25
- > (None when `files` is empty — no conditional needed at call sites)
26
- > `FromFile.alias()` / `IntoFile.alias()` classmethods set `is_alias=True`
27
- > on the emitted spec
28
- > `is_alias: bool` added to `FileSourceSpec` and `FileSpec`
29
- > Polars and Spark backends resolve aliases via injected `file_locator`
30
- > Both providers wired: `file_locator = config.to_file_locator()`
31
- > Full test coverage across io, storage, and backend layers
32
19
 
33
20
 
34
21
 
35
- ## 🐛 Fixes
36
- ### observability
37
- - **observability:** honor missing table policy for record store writers
38
22
 
39
23
 
40
- ## 📖 Documentation
24
+
25
+
26
+
27
+
28
+ # 🚀 Release 0.4.0 ([#18](https://github.com/the-reacher-data/loom-py/pull/18)) ([`09e5aa3`](https://github.com/the-reacher-data/loom-py/commit/09e5aa340f88e0488daca2bf10320aad7aebbe1d))
29
+
30
+
31
+ ## ✨ Features
41
32
  ### etl
42
- - **etl:** keep only user guide and drop refactor docs
43
- - **etl:** expand ETL documentation and update directory table<br>
44
- > Add dummy-loom-etl companion repo link in README and etl guide
45
- > Expand README subpaths table with loom.etl and loom.core.config entries
46
- > Add FileLocator/alias API, cloud config URI, and ConfigResolver sections to etl guide
47
- > Add loom.etl.backends (polars + spark) to etl.rst API reference
48
- > Add loom.core.config to core.rst API reference
33
+ - **etl:** add IntoHistory builder and SCD Type 2 domain contracts
34
+
35
+
49
36
 
50
37
 
51
38
 
52
39
 
53
- ## ♻️ Refactor
54
- ### stepsql
55
- - **stepsql:** delegate SQL execution to backend readers
56
40
 
57
41
 
58
42
 
@@ -118,8 +102,6 @@
118
102
 
119
103
 
120
104
 
121
-
122
-
123
105
  # 🚀 Release 0.2.1 ([#12](https://github.com/the-reacher-data/loom-py/pull/12)) ([`87f7d1f`](https://github.com/the-reacher-data/loom-py/commit/87f7d1f1eb1ccde71d0aca1c5584b83317e30707))
124
106
 
125
107
  ## ✨ Features
@@ -0,0 +1,25 @@
1
+ # 🚀 Release 0.5.0 ([#20](https://github.com/the-reacher-data/loom-py/pull/20)) ([`70f7cf8`](https://github.com/the-reacher-data/loom-py/commit/70f7cf85275fcc1f590e06f980dfac91cad50893))
2
+
3
+
4
+ ## ✨ Features
5
+ ### core
6
+ - **core:** add shared expression routing primitives
7
+
8
+ ### streaming
9
+ - **streaming:** add process DSL and routing
10
+ - **streaming:** add kafka transport and observability
11
+ - **streaming:** allow task resource kwargs
12
+ - **streaming:** add scoped dependency nodes
13
+ - **streaming:** make tasks configurable
14
+
15
+ ### config
16
+ - **config:** add declarative config bindings
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: loom-kernel
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: Loom Python project
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -54,6 +54,15 @@ Requires-Dist: uvicorn<1.0,>=0.30; extra == 'rest'
54
54
  Requires-Dist: uvloop<1.0,>=0.21; (sys_platform != 'win32') and extra == 'rest'
55
55
  Provides-Extra: sqlalchemy
56
56
  Requires-Dist: sqlalchemy<3.0,>=2.0; extra == 'sqlalchemy'
57
+ Provides-Extra: streaming
58
+ Requires-Dist: anyio<5.0,>=4.0; extra == 'streaming'
59
+ Requires-Dist: bytewax>=0.21; extra == 'streaming'
60
+ Requires-Dist: confluent-kafka<3.0,>=2.6; extra == 'streaming'
61
+ Requires-Dist: opentelemetry-api<2.0,>=1.27; extra == 'streaming'
62
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2.0,>=1.27; extra == 'streaming'
63
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http<2.0,>=1.27; extra == 'streaming'
64
+ Requires-Dist: opentelemetry-sdk<2.0,>=1.27; extra == 'streaming'
65
+ Requires-Dist: uvloop<1.0,>=0.21; (sys_platform != 'win32') and extra == 'streaming'
57
66
  Description-Content-Type: text/markdown
58
67
 
59
68
  <p align="center">
@@ -78,7 +87,8 @@ Framework-agnostic Python toolkit to build backend applications with:
78
87
  - repositories decoupled from infrastructure
79
88
  - REST/FastAPI adapters with OpenAPI generation
80
89
  - background jobs and Celery workers, first-class
81
- - testing utilities for business workflows
90
+ - **declarative ETL** — compile-time-validated pipelines for Polars and Spark
91
+ - testing utilities for business workflows and ETL steps
82
92
 
83
93
  ## Purpose
84
94
 
@@ -452,6 +462,66 @@ For deeper references, review the integration examples under
452
462
  For a runnable full-stack sample with all patterns combined, check the companion repository
453
463
  [`dummy-loom`](https://github.com/the-reacher-data/dummy-loom).
454
464
 
465
+ ## ETL quick start
466
+
467
+ Install a backend:
468
+
469
+ ```bash
470
+ pip install "loom-kernel[etl-polars]"
471
+ # or
472
+ pip install "loom-kernel[etl-spark]"
473
+ ```
474
+
475
+ Declare a pipeline — sources, targets, and transformation logic are explicit and compile-time validated:
476
+
477
+ ```python
478
+ from datetime import date
479
+ import polars as pl
480
+ from loom.etl import ETLParams, ETLStep, ETLProcess, ETLPipeline, ETLRunner, FromTable, IntoTable
481
+
482
+ class DailyParams(ETLParams):
483
+ run_date: date
484
+
485
+ class CleanOrders(ETLStep[DailyParams]):
486
+ orders = FromTable("raw.orders").columns("id", "amount", "run_date")
487
+ target = IntoTable("staging.orders").replace()
488
+
489
+ def execute(self, params: DailyParams, *, orders: pl.LazyFrame) -> pl.LazyFrame:
490
+ return orders.filter(pl.col("amount") > 0)
491
+
492
+ class DailyProcess(ETLProcess[DailyParams]):
493
+ steps = [CleanOrders]
494
+
495
+ class DailyPipeline(ETLPipeline[DailyParams]):
496
+ processes = [DailyProcess]
497
+
498
+ runner = ETLRunner.from_yaml("config/etl.yaml")
499
+ runner.run(DailyPipeline, DailyParams(run_date=date.today()))
500
+ ```
501
+
502
+ Write modes — `replace`, `append`, `replace_partition`, `replace_partitions`, `replace_where`, `upsert` — are declared on the target, validated at compile time. Partition predicates use the `params` proxy so no values are hard-coded:
503
+
504
+ ```python
505
+ from loom.etl import params
506
+
507
+ target = IntoTable("staging.orders").replace_partition(
508
+ year=params.run_date.year,
509
+ month=params.run_date.month,
510
+ )
511
+ ```
512
+
513
+ File aliases decouple paths from pipelines — declare once in YAML, reference by name:
514
+
515
+ ```python
516
+ events = FromFile.alias("events_raw", format=Format.CSV)
517
+ target = IntoFile.alias("exports_daily", format=Format.PARQUET)
518
+ ```
519
+
520
+ For a full Polars + Spark + Delta Lake example see [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl).
521
+ For the complete API reference and write-mode guide see the [ETL docs](https://loom-py.readthedocs.io/en/latest/guides/etl.html).
522
+
523
+ ---
524
+
455
525
  ## Performance
456
526
 
457
527
  `loom-kernel` adds zero measurable overhead at the concurrency levels typical of
@@ -20,7 +20,8 @@ Framework-agnostic Python toolkit to build backend applications with:
20
20
  - repositories decoupled from infrastructure
21
21
  - REST/FastAPI adapters with OpenAPI generation
22
22
  - background jobs and Celery workers, first-class
23
- - testing utilities for business workflows
23
+ - **declarative ETL** — compile-time-validated pipelines for Polars and Spark
24
+ - testing utilities for business workflows and ETL steps
24
25
 
25
26
  ## Purpose
26
27
 
@@ -394,6 +395,66 @@ For deeper references, review the integration examples under
394
395
  For a runnable full-stack sample with all patterns combined, check the companion repository
395
396
  [`dummy-loom`](https://github.com/the-reacher-data/dummy-loom).
396
397
 
398
+ ## ETL quick start
399
+
400
+ Install a backend:
401
+
402
+ ```bash
403
+ pip install "loom-kernel[etl-polars]"
404
+ # or
405
+ pip install "loom-kernel[etl-spark]"
406
+ ```
407
+
408
+ Declare a pipeline — sources, targets, and transformation logic are explicit and compile-time validated:
409
+
410
+ ```python
411
+ from datetime import date
412
+ import polars as pl
413
+ from loom.etl import ETLParams, ETLStep, ETLProcess, ETLPipeline, ETLRunner, FromTable, IntoTable
414
+
415
+ class DailyParams(ETLParams):
416
+ run_date: date
417
+
418
+ class CleanOrders(ETLStep[DailyParams]):
419
+ orders = FromTable("raw.orders").columns("id", "amount", "run_date")
420
+ target = IntoTable("staging.orders").replace()
421
+
422
+ def execute(self, params: DailyParams, *, orders: pl.LazyFrame) -> pl.LazyFrame:
423
+ return orders.filter(pl.col("amount") > 0)
424
+
425
+ class DailyProcess(ETLProcess[DailyParams]):
426
+ steps = [CleanOrders]
427
+
428
+ class DailyPipeline(ETLPipeline[DailyParams]):
429
+ processes = [DailyProcess]
430
+
431
+ runner = ETLRunner.from_yaml("config/etl.yaml")
432
+ runner.run(DailyPipeline, DailyParams(run_date=date.today()))
433
+ ```
434
+
435
+ Write modes — `replace`, `append`, `replace_partition`, `replace_partitions`, `replace_where`, `upsert` — are declared on the target, validated at compile time. Partition predicates use the `params` proxy so no values are hard-coded:
436
+
437
+ ```python
438
+ from loom.etl import params
439
+
440
+ target = IntoTable("staging.orders").replace_partition(
441
+ year=params.run_date.year,
442
+ month=params.run_date.month,
443
+ )
444
+ ```
445
+
446
+ File aliases decouple paths from pipelines — declare once in YAML, reference by name:
447
+
448
+ ```python
449
+ events = FromFile.alias("events_raw", format=Format.CSV)
450
+ target = IntoFile.alias("exports_daily", format=Format.PARQUET)
451
+ ```
452
+
453
+ For a full Polars + Spark + Delta Lake example see [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl).
454
+ For the complete API reference and write-mode guide see the [ETL docs](https://loom-py.readthedocs.io/en/latest/guides/etl.html).
455
+
456
+ ---
457
+
397
458
  ## Performance
398
459
 
399
460
  `loom-kernel` adds zero measurable overhead at the concurrency levels typical of
@@ -29,7 +29,7 @@ extensions = [
29
29
  ]
30
30
 
31
31
  templates_path = ["_templates"]
32
- exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
32
+ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "guides", "architecture", "examples-repo"]
33
33
 
34
34
  html_theme = "furo"
35
35
  html_static_path = ["_static"]
@@ -69,6 +69,8 @@ def _skip_duplicate_reexports(
69
69
  ("loom.core.errors", "RuleViolations"),
70
70
  ("loom.core.use_case", "RuleViolation"),
71
71
  ("loom.core.use_case", "RuleViolations"),
72
+ ("loom.etl.observability", "OtelConfig"),
73
+ ("loom.testing", "CompilationError"),
72
74
  ("loom.rest.model", "PaginationMode"),
73
75
  }
74
76
  if (current_module, name) in duplicated_reexports:
@@ -0,0 +1,29 @@
1
+ # ETL Examples
2
+
3
+ The companion repository [`dummy-loom-etl`](https://github.com/the-reacher-data/dummy-loom-etl)
4
+ contains runnable end-to-end examples of `loom.etl` with both Polars and Spark
5
+ backends.
6
+
7
+ ## What it covers
8
+
9
+ - Polars and Spark pipeline declarations
10
+ - Delta Lake read/write modes (`replace`, `upsert`, `replace_partitions`)
11
+ - Cloud storage configuration (S3, GCS, Azure) via `fsspec`
12
+ - File aliases with `FromFile.alias` / `IntoFile.alias`
13
+ - Observability and run sinks
14
+ - Integration tests with `PolarsStepRunner` and `SparkTestSession`
15
+
16
+ ## Quick start
17
+
18
+ ```bash
19
+ git clone https://github.com/the-reacher-data/dummy-loom-etl
20
+ cd dummy-loom-etl
21
+ make test # run Polars and Spark test suites
22
+ make run # run the sample pipeline locally
23
+ ```
24
+
25
+ ## Next steps
26
+
27
+ - [ETL pipelines guide](pipelines.md)
28
+ - [ETL testing guide](testing.md)
29
+ - [API reference](../reference/api/etl)
@@ -0,0 +1,65 @@
1
+ # ETL Testing
2
+
3
+ `loom.etl.testing` provides in-memory harnesses for testing `ETLStep`
4
+ subclasses without spinning up a real catalog or writing to Delta Lake.
5
+
6
+ ## Test a single step with Polars
7
+
8
+ `PolarsStepRunner` seeds source tables as plain Python tuples, runs one step,
9
+ and returns a `StepResult` for assertions.
10
+
11
+ ```python
12
+ from loom.etl.testing import PolarsStepRunner
13
+
14
+ def test_clean_orders():
15
+ runner = PolarsStepRunner()
16
+ runner.seed("raw.orders", [(1, 10.0), (2, -5.0)], ["id", "amount"])
17
+ result = runner.run(CleanOrdersStep, NoParams())
18
+
19
+ result.assert_count(1)
20
+ result.assert_schema({"id": "Int64", "amount": "Float64"})
21
+ ```
22
+
23
+ `StepResult` methods: `assert_schema`, `assert_count`, `assert_not_empty`,
24
+ `show`, `to_polars`.
25
+
26
+ ## Reusable seed datasets with `ETLScenario`
27
+
28
+ `ETLScenario` stores seed data as plain tuples so the same dataset can be used
29
+ with any backend runner.
30
+
31
+ ```python
32
+ from loom.etl.testing import ETLScenario
33
+
34
+ ORDERS = (
35
+ ETLScenario()
36
+ .with_table("raw.orders", [(1, 10.0), (2, 20.0)], ["id", "amount"])
37
+ )
38
+
39
+ def test_double_amount(loom_polars_runner):
40
+ ORDERS.apply(loom_polars_runner)
41
+ result = loom_polars_runner.run(DoubleAmountStep, NoParams())
42
+ result.assert_count(2)
43
+ ```
44
+
45
+ Pytest fixtures auto-registered: `loom_polars_runner`, `loom_spark_runner`.
46
+
47
+ ## Spark integration tests
48
+
49
+ Use `SparkTestSession` for a real PySpark + Delta session:
50
+
51
+ ```python
52
+ from loom.etl.testing.spark import SparkTestSession
53
+
54
+ with SparkTestSession.start() as spark:
55
+ runner = SparkStepRunner(spark)
56
+ runner.seed("raw.orders", [(1, 10.0)], ["id", "amount"])
57
+ result = runner.run(CleanOrdersStep, NoParams())
58
+ result.assert_count(1)
59
+ ```
60
+
61
+ ## Compile-time stubs
62
+
63
+ - `StubCatalog` — in-memory catalog.
64
+ - `StubSourceReader` / `StubTargetWriter` — in-memory I/O.
65
+ - `StubRunObserver` — records pipeline lifecycle events.
@@ -0,0 +1,136 @@
1
+ # ETL Quickstart
2
+
3
+ `loom.etl` is a declarative ETL subsystem with compile-time validation,
4
+ backend-agnostic declarations, and a single runtime entrypoint (`ETLRunner`).
5
+
6
+ ## Install
7
+
8
+ Choose one backend:
9
+
10
+ ```bash
11
+ pip install "loom-kernel[etl-polars]"
12
+ # or
13
+ pip install "loom-kernel[etl-spark]"
14
+ ```
15
+
16
+ ## Minimal pipeline
17
+
18
+ ```python
19
+ from datetime import date
20
+
21
+ import polars as pl
22
+ from loom.etl import (
23
+ ETLParams,
24
+ ETLStep,
25
+ ETLProcess,
26
+ ETLPipeline,
27
+ ETLRunner,
28
+ FromTable,
29
+ IntoTable,
30
+ )
31
+
32
+
33
+ class DailyParams(ETLParams):
34
+ run_date: date
35
+
36
+
37
+ class CleanOrders(ETLStep[DailyParams]):
38
+ orders = FromTable("raw.orders").columns("id", "amount", "run_date")
39
+ target = IntoTable("staging.orders").replace()
40
+
41
+ def execute(self, params: DailyParams, *, orders: pl.LazyFrame) -> pl.LazyFrame:
42
+ return orders.filter(pl.col("amount") > 0)
43
+
44
+
45
+ class DailyProcess(ETLProcess[DailyParams]):
46
+ steps = [CleanOrders]
47
+
48
+
49
+ class DailyPipeline(ETLPipeline[DailyParams]):
50
+ processes = [DailyProcess]
51
+
52
+
53
+ runner = ETLRunner.from_dict(
54
+ storage={
55
+ "engine": "polars",
56
+ "defaults": {"table_path": {"uri": "/var/lib/loom/lake"}},
57
+ }
58
+ )
59
+ runner.run(DailyPipeline, DailyParams(run_date=date(2026, 3, 30)))
60
+ ```
61
+
62
+ ## Basic write modes
63
+
64
+ Every `IntoTable` target declares exactly one write mode by chaining a method.
65
+
66
+ | Mode | What it does | Example |
67
+ |------|--------------|---------|
68
+ | `append` | Add rows to the table | `IntoTable("staging.orders").append()` |
69
+ | `replace` | Full overwrite | `IntoTable("staging.orders").replace()` |
70
+ | `replace_partitions` | Overwrite only partitions present in the batch | `IntoTable("staging.orders").replace_partitions("year", "month")` |
71
+ | `replace_partition` | Overwrite a single known partition | `IntoTable("staging.orders").replace_partition(year=params.run_date.year)` |
72
+ | `replace_where` | Overwrite rows matching a predicate | `IntoTable("staging.orders").replace_where(col("date") == params.run_date)` |
73
+ | `upsert` | Merge on key columns | `IntoTable("staging.orders").upsert(keys=("order_id",))` |
74
+
75
+ See the [ETL pipelines guide](../etl/pipelines.md) for the full write-mode reference.
76
+
77
+ ## YAML config
78
+
79
+ ```yaml
80
+ storage:
81
+ engine: polars
82
+ defaults:
83
+ table_path:
84
+ uri: s3://my-lake
85
+ storage_options:
86
+ AWS_REGION: ${oc.env:AWS_REGION}
87
+ AWS_ACCESS_KEY_ID: ${oc.env:AWS_ACCESS_KEY_ID}
88
+ AWS_SECRET_ACCESS_KEY: ${oc.env:AWS_SECRET_ACCESS_KEY}
89
+
90
+ tmp_root: /var/lib/loom/lake/_tmp
91
+
92
+ observability:
93
+ log: true
94
+ slow_step_threshold_ms: 30000
95
+ run_sink:
96
+ root: /var/lib/loom/lake/_runs
97
+ ```
98
+
99
+ ```python
100
+ from loom.etl import ETLRunner
101
+
102
+ runner = ETLRunner.from_yaml("config/etl.yaml")
103
+ ```
104
+
105
+ ## File aliases
106
+
107
+ Hard-coding file paths couples logic to infrastructure. Use aliases instead:
108
+
109
+ ```yaml
110
+ storage:
111
+ engine: polars
112
+ files:
113
+ - name: events_raw
114
+ path:
115
+ uri: s3://raw-bucket/events/
116
+ storage_options:
117
+ AWS_REGION: eu-west-1
118
+ ```
119
+
120
+ ```python
121
+ from loom.etl import ETLStep, FromFile, IntoFile, Format
122
+
123
+ class LoadEvents(ETLStep[DailyParams]):
124
+ events = FromFile.alias("events_raw", format=Format.CSV)
125
+ target = IntoFile.alias("exports_daily", format=Format.PARQUET)
126
+
127
+ def execute(self, params: DailyParams, *, events: pl.LazyFrame) -> pl.LazyFrame:
128
+ return events
129
+ ```
130
+
131
+ ## Next steps
132
+
133
+ - [ETL pipelines guide](../etl/pipelines.md) — full write modes, Spark runtime, cloud config, and pluggable resolvers
134
+ - [ETL testing guide](../etl/testing.md) — in-memory runners, scenarios, and stubs
135
+ - [ETL examples](../etl/examples.md) — companion repository with runnable Polars and Spark pipelines
136
+ - [API reference](../reference/api/etl)
@@ -1,4 +1,4 @@
1
- # Quickstart
1
+ # REST Quickstart
2
2
 
3
3
  `loom-kernel` lets you define business behavior in typed use cases and expose it
4
4
  through REST interfaces — with full auto-CRUD, background jobs, and Celery workers.
@@ -416,8 +416,9 @@ Computes run in declaration order — later computes can reference fields set by
416
416
 
417
417
  ## Next steps
418
418
 
419
- - [Auto-CRUD guide](autocrud.md) — full options reference for `auto = True` and `build_auto_routes()`
420
- - [Use-case DSL](use-case-dsl.md) — rules, computes, predicates
421
- - [Celery worker](celery.md) — job definitions, dispatch, callbacks, worker bootstrap
422
- - [Examples repo](../examples-repo/index.md) — full walkthrough of the `dummy-loom` companion app
419
+ - [Auto-CRUD guide](../rest/autocrud.md) — full options reference for `auto = True` and `build_auto_routes()`
420
+ - [Use-case DSL](../rest/use-case-dsl.md) — rules, computes, predicates
421
+ - [Celery worker](../rest/celery.md) — job definitions, dispatch, callbacks, worker bootstrap
422
+ - [Examples repo](../rest/examples.md) — full walkthrough of the `dummy-loom` companion app
423
+ - [REST testing guide](../rest/testing.md) — unit and integration testing utilities
423
424
  - [API reference](../reference/index.rst)