rhizodat 0.1.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 (296) hide show
  1. rhizodat-0.1.0/.env.test +6 -0
  2. rhizodat-0.1.0/.github/ISSUE_TEMPLATE/feedback.yml +39 -0
  3. rhizodat-0.1.0/.github/workflows/ci.yml +118 -0
  4. rhizodat-0.1.0/.github/workflows/docs.yml +41 -0
  5. rhizodat-0.1.0/.github/workflows/release.yml +113 -0
  6. rhizodat-0.1.0/.gitignore +210 -0
  7. rhizodat-0.1.0/CHANGELOG.md +40 -0
  8. rhizodat-0.1.0/Cargo.lock +4968 -0
  9. rhizodat-0.1.0/Cargo.toml +18 -0
  10. rhizodat-0.1.0/LICENSE +201 -0
  11. rhizodat-0.1.0/PKG-INFO +74 -0
  12. rhizodat-0.1.0/README.md +36 -0
  13. rhizodat-0.1.0/compose.yaml +119 -0
  14. rhizodat-0.1.0/conformance/README.md +28 -0
  15. rhizodat-0.1.0/conformance/crash_matrix.json +711 -0
  16. rhizodat-0.1.0/conformance/dsn.json +446 -0
  17. rhizodat-0.1.0/conformance/gid.json +80 -0
  18. rhizodat-0.1.0/conformance/hlc.json +296 -0
  19. rhizodat-0.1.0/conformance/journal.json +207 -0
  20. rhizodat-0.1.0/conformance/migrations.json +213 -0
  21. rhizodat-0.1.0/conformance/postgres_schema.json +30 -0
  22. rhizodat-0.1.0/conformance/rows.json +369 -0
  23. rhizodat-0.1.0/conformance/staged_files.json +81 -0
  24. rhizodat-0.1.0/conformance/uuid7.json +253 -0
  25. rhizodat-0.1.0/crates/rhizodat-clickhouse/Cargo.toml +25 -0
  26. rhizodat-0.1.0/crates/rhizodat-clickhouse/src/lib.rs +777 -0
  27. rhizodat-0.1.0/crates/rhizodat-clickhouse/src/parts.rs +737 -0
  28. rhizodat-0.1.0/crates/rhizodat-clickhouse/tests/clickhouse.rs +679 -0
  29. rhizodat-0.1.0/crates/rhizodat-clickhouse/tests/parts.rs +355 -0
  30. rhizodat-0.1.0/crates/rhizodat-conformance/Cargo.toml +23 -0
  31. rhizodat-0.1.0/crates/rhizodat-conformance/src/lib.rs +4 -0
  32. rhizodat-0.1.0/crates/rhizodat-conformance/tests/conformance.rs +665 -0
  33. rhizodat-0.1.0/crates/rhizodat-core/Cargo.toml +31 -0
  34. rhizodat-0.1.0/crates/rhizodat-core/src/adapter.rs +225 -0
  35. rhizodat-0.1.0/crates/rhizodat-core/src/clock.rs +278 -0
  36. rhizodat-0.1.0/crates/rhizodat-core/src/coordinator.rs +550 -0
  37. rhizodat-0.1.0/crates/rhizodat-core/src/dsn.rs +480 -0
  38. rhizodat-0.1.0/crates/rhizodat-core/src/gid.rs +49 -0
  39. rhizodat-0.1.0/crates/rhizodat-core/src/identity.rs +202 -0
  40. rhizodat-0.1.0/crates/rhizodat-core/src/journal.rs +627 -0
  41. rhizodat-0.1.0/crates/rhizodat-core/src/lib.rs +23 -0
  42. rhizodat-0.1.0/crates/rhizodat-core/src/migrations.rs +374 -0
  43. rhizodat-0.1.0/crates/rhizodat-core/src/recovery.rs +213 -0
  44. rhizodat-0.1.0/crates/rhizodat-core/src/retry.rs +120 -0
  45. rhizodat-0.1.0/crates/rhizodat-core/src/rows.rs +408 -0
  46. rhizodat-0.1.0/crates/rhizodat-core/src/staged.rs +187 -0
  47. rhizodat-0.1.0/crates/rhizodat-core/src/store.rs +123 -0
  48. rhizodat-0.1.0/crates/rhizodat-core/src/timer.rs +60 -0
  49. rhizodat-0.1.0/crates/rhizodat-core/tests/adapter.rs +128 -0
  50. rhizodat-0.1.0/crates/rhizodat-core/tests/coordinator.rs +653 -0
  51. rhizodat-0.1.0/crates/rhizodat-core/tests/fakes/mod.rs +575 -0
  52. rhizodat-0.1.0/crates/rhizodat-core/tests/recovery.rs +472 -0
  53. rhizodat-0.1.0/crates/rhizodat-drevo/Cargo.toml +32 -0
  54. rhizodat-0.1.0/crates/rhizodat-drevo/src/bolt.rs +192 -0
  55. rhizodat-0.1.0/crates/rhizodat-drevo/src/embedded.rs +223 -0
  56. rhizodat-0.1.0/crates/rhizodat-drevo/src/lib.rs +978 -0
  57. rhizodat-0.1.0/crates/rhizodat-drevo/src/parts.rs +693 -0
  58. rhizodat-0.1.0/crates/rhizodat-drevo/tests/drevo.rs +1038 -0
  59. rhizodat-0.1.0/crates/rhizodat-iceberg/Cargo.toml +36 -0
  60. rhizodat-0.1.0/crates/rhizodat-iceberg/src/erase.rs +610 -0
  61. rhizodat-0.1.0/crates/rhizodat-iceberg/src/filter.rs +533 -0
  62. rhizodat-0.1.0/crates/rhizodat-iceberg/src/lib.rs +1131 -0
  63. rhizodat-0.1.0/crates/rhizodat-iceberg/src/parts.rs +869 -0
  64. rhizodat-0.1.0/crates/rhizodat-iceberg/tests/iceberg.rs +1458 -0
  65. rhizodat-0.1.0/crates/rhizodat-postgres/Cargo.toml +24 -0
  66. rhizodat-0.1.0/crates/rhizodat-postgres/src/lib.rs +1164 -0
  67. rhizodat-0.1.0/crates/rhizodat-postgres/src/parts.rs +705 -0
  68. rhizodat-0.1.0/crates/rhizodat-postgres/src/query.rs +315 -0
  69. rhizodat-0.1.0/crates/rhizodat-postgres/tests/parts.rs +402 -0
  70. rhizodat-0.1.0/crates/rhizodat-postgres/tests/postgres.rs +1002 -0
  71. rhizodat-0.1.0/crates/rhizodat-py/Cargo.toml +47 -0
  72. rhizodat-0.1.0/crates/rhizodat-py/build.rs +5 -0
  73. rhizodat-0.1.0/crates/rhizodat-py/pyproject.toml +13 -0
  74. rhizodat-0.1.0/crates/rhizodat-py/src/clickhouse.rs +466 -0
  75. rhizodat-0.1.0/crates/rhizodat-py/src/coordinator.rs +523 -0
  76. rhizodat-0.1.0/crates/rhizodat-py/src/drevo.rs +501 -0
  77. rhizodat-0.1.0/crates/rhizodat-py/src/iceberg.rs +511 -0
  78. rhizodat-0.1.0/crates/rhizodat-py/src/lib.rs +435 -0
  79. rhizodat-0.1.0/crates/rhizodat-py/src/migrations.rs +88 -0
  80. rhizodat-0.1.0/crates/rhizodat-py/src/native.rs +281 -0
  81. rhizodat-0.1.0/crates/rhizodat-py/src/postgres.rs +510 -0
  82. rhizodat-0.1.0/crates/rhizodat-py/src/recovery.rs +112 -0
  83. rhizodat-0.1.0/crates/rhizodat-py/src/result.rs +64 -0
  84. rhizodat-0.1.0/crates/rhizodat-py/src/rows.rs +142 -0
  85. rhizodat-0.1.0/docs/adapters/contracts.md +204 -0
  86. rhizodat-0.1.0/docs/adapters/index.md +266 -0
  87. rhizodat-0.1.0/docs/adapters/stores.md +109 -0
  88. rhizodat-0.1.0/docs/concepts/identity.md +60 -0
  89. rhizodat-0.1.0/docs/concepts/principles.md +20 -0
  90. rhizodat-0.1.0/docs/concepts/stores.md +66 -0
  91. rhizodat-0.1.0/docs/concepts/time.md +46 -0
  92. rhizodat-0.1.0/docs/concepts/transactions.md +222 -0
  93. rhizodat-0.1.0/docs/development/index.md +167 -0
  94. rhizodat-0.1.0/docs/development/package.md +31 -0
  95. rhizodat-0.1.0/docs/examples.md +43 -0
  96. rhizodat-0.1.0/docs/getting-started.md +38 -0
  97. rhizodat-0.1.0/docs/guide/api.md +55 -0
  98. rhizodat-0.1.0/docs/guide/embeddings.md +101 -0
  99. rhizodat-0.1.0/docs/guide/imports.md +107 -0
  100. rhizodat-0.1.0/docs/guide/mcp.md +79 -0
  101. rhizodat-0.1.0/docs/guide/migrations.md +91 -0
  102. rhizodat-0.1.0/docs/guide/ontology.md +46 -0
  103. rhizodat-0.1.0/docs/guide/repository.md +65 -0
  104. rhizodat-0.1.0/docs/index.md +38 -0
  105. rhizodat-0.1.0/docs/plan.md +466 -0
  106. rhizodat-0.1.0/docs/reference/adapter.md +11 -0
  107. rhizodat-0.1.0/docs/reference/embed.md +5 -0
  108. rhizodat-0.1.0/docs/reference/ingest.md +13 -0
  109. rhizodat-0.1.0/docs/reference/migrations.md +5 -0
  110. rhizodat-0.1.0/docs/reference/repository.md +6 -0
  111. rhizodat-0.1.0/docs/reference/rhizodat.md +25 -0
  112. rhizodat-0.1.0/docs/reference/testing.md +7 -0
  113. rhizodat-0.1.0/examples/_stores.py +13 -0
  114. rhizodat-0.1.0/examples/bitemporal.py +42 -0
  115. rhizodat-0.1.0/examples/import_csv.py +41 -0
  116. rhizodat-0.1.0/examples/migrate.py +18 -0
  117. rhizodat-0.1.0/examples/migrations/0001_tasks.toml +13 -0
  118. rhizodat-0.1.0/examples/migrations/0002_points.toml +5 -0
  119. rhizodat-0.1.0/examples/quickstart.py +36 -0
  120. rhizodat-0.1.0/examples/transactions.py +34 -0
  121. rhizodat-0.1.0/mkdocs.yml +85 -0
  122. rhizodat-0.1.0/plugins/rhizodat-ontology/README.md +22 -0
  123. rhizodat-0.1.0/plugins/rhizodat-ontology/pyproject.toml +22 -0
  124. rhizodat-0.1.0/plugins/rhizodat-ontology/src/rhizodat_ontology/__init__.py +214 -0
  125. rhizodat-0.1.0/plugins/rhizodat-ontology/src/rhizodat_ontology/cli.py +73 -0
  126. rhizodat-0.1.0/plugins/rhizodat-ontology/tests/test_propose.py +215 -0
  127. rhizodat-0.1.0/pyproject.toml +132 -0
  128. rhizodat-0.1.0/src/rhizodat/__init__.py +37 -0
  129. rhizodat-0.1.0/src/rhizodat/adapters/__init__.py +1 -0
  130. rhizodat-0.1.0/src/rhizodat/adapters/clickhouse.py +683 -0
  131. rhizodat-0.1.0/src/rhizodat/adapters/drevo.py +970 -0
  132. rhizodat-0.1.0/src/rhizodat/adapters/iceberg.py +759 -0
  133. rhizodat-0.1.0/src/rhizodat/adapters/iceberg_schema.py +198 -0
  134. rhizodat-0.1.0/src/rhizodat/adapters/postgres.py +859 -0
  135. rhizodat-0.1.0/src/rhizodat/api.py +449 -0
  136. rhizodat-0.1.0/src/rhizodat/check.py +424 -0
  137. rhizodat-0.1.0/src/rhizodat/core/__init__.py +1 -0
  138. rhizodat-0.1.0/src/rhizodat/core/adapter.py +350 -0
  139. rhizodat-0.1.0/src/rhizodat/core/clock.py +126 -0
  140. rhizodat-0.1.0/src/rhizodat/core/coordinator.py +526 -0
  141. rhizodat-0.1.0/src/rhizodat/core/dsn.py +169 -0
  142. rhizodat-0.1.0/src/rhizodat/core/errors.py +80 -0
  143. rhizodat-0.1.0/src/rhizodat/core/identity.py +87 -0
  144. rhizodat-0.1.0/src/rhizodat/core/journal.py +478 -0
  145. rhizodat-0.1.0/src/rhizodat/core/mapping.py +330 -0
  146. rhizodat-0.1.0/src/rhizodat/core/native.py +29 -0
  147. rhizodat-0.1.0/src/rhizodat/core/native_parts.py +137 -0
  148. rhizodat-0.1.0/src/rhizodat/core/native_result.py +41 -0
  149. rhizodat-0.1.0/src/rhizodat/core/native_uow.py +227 -0
  150. rhizodat-0.1.0/src/rhizodat/core/parts.py +196 -0
  151. rhizodat-0.1.0/src/rhizodat/core/repository.py +566 -0
  152. rhizodat-0.1.0/src/rhizodat/core/result.py +122 -0
  153. rhizodat-0.1.0/src/rhizodat/core/retry.py +32 -0
  154. rhizodat-0.1.0/src/rhizodat/core/rows.py +146 -0
  155. rhizodat-0.1.0/src/rhizodat/core/staged.py +102 -0
  156. rhizodat-0.1.0/src/rhizodat/core/unit_of_work.py +119 -0
  157. rhizodat-0.1.0/src/rhizodat/core/vectors.py +108 -0
  158. rhizodat-0.1.0/src/rhizodat/embed/__init__.py +171 -0
  159. rhizodat-0.1.0/src/rhizodat/embed/cli.py +119 -0
  160. rhizodat-0.1.0/src/rhizodat/ingest/__init__.py +40 -0
  161. rhizodat-0.1.0/src/rhizodat/ingest/cli.py +247 -0
  162. rhizodat-0.1.0/src/rhizodat/ingest/graph.py +168 -0
  163. rhizodat-0.1.0/src/rhizodat/ingest/importer.py +250 -0
  164. rhizodat-0.1.0/src/rhizodat/ingest/relate.py +233 -0
  165. rhizodat-0.1.0/src/rhizodat/ingest/relate_cli.py +108 -0
  166. rhizodat-0.1.0/src/rhizodat/ingest/schema.py +89 -0
  167. rhizodat-0.1.0/src/rhizodat/ingest/sources.py +392 -0
  168. rhizodat-0.1.0/src/rhizodat/mcp/__init__.py +16 -0
  169. rhizodat-0.1.0/src/rhizodat/mcp/__main__.py +5 -0
  170. rhizodat-0.1.0/src/rhizodat/mcp/config.py +76 -0
  171. rhizodat-0.1.0/src/rhizodat/mcp/entities.py +268 -0
  172. rhizodat-0.1.0/src/rhizodat/mcp/server.py +184 -0
  173. rhizodat-0.1.0/src/rhizodat/mcp/tools.py +307 -0
  174. rhizodat-0.1.0/src/rhizodat/migrations/__init__.py +29 -0
  175. rhizodat-0.1.0/src/rhizodat/migrations/cli.py +101 -0
  176. rhizodat-0.1.0/src/rhizodat/migrations/format.py +289 -0
  177. rhizodat-0.1.0/src/rhizodat/migrations/runner.py +170 -0
  178. rhizodat-0.1.0/src/rhizodat/py.typed +0 -0
  179. rhizodat-0.1.0/src/rhizodat/testing/__init__.py +1 -0
  180. rhizodat-0.1.0/src/rhizodat/testing/contract.py +486 -0
  181. rhizodat-0.1.0/src/rhizodat/testing/memory.py +227 -0
  182. rhizodat-0.1.0/src/rhizodat/testing/parts.py +376 -0
  183. rhizodat-0.1.0/tests/adapters/test_clickhouse.py +358 -0
  184. rhizodat-0.1.0/tests/adapters/test_clickhouse_parts.py +94 -0
  185. rhizodat-0.1.0/tests/adapters/test_drevo.py +205 -0
  186. rhizodat-0.1.0/tests/adapters/test_drevo_parts.py +166 -0
  187. rhizodat-0.1.0/tests/adapters/test_graph_loads.py +166 -0
  188. rhizodat-0.1.0/tests/adapters/test_iceberg.py +460 -0
  189. rhizodat-0.1.0/tests/adapters/test_iceberg_parts.py +212 -0
  190. rhizodat-0.1.0/tests/adapters/test_loads.py +244 -0
  191. rhizodat-0.1.0/tests/adapters/test_migration_steps.py +217 -0
  192. rhizodat-0.1.0/tests/adapters/test_postgres.py +387 -0
  193. rhizodat-0.1.0/tests/adapters/test_postgres_parts.py +97 -0
  194. rhizodat-0.1.0/tests/adapters/test_vector_store.py +112 -0
  195. rhizodat-0.1.0/tests/conformance/test_native_vectors.py +200 -0
  196. rhizodat-0.1.0/tests/conformance/test_vectors.py +470 -0
  197. rhizodat-0.1.0/tests/conftest.py +167 -0
  198. rhizodat-0.1.0/tests/contract/test_clickhouse_contract.py +56 -0
  199. rhizodat-0.1.0/tests/contract/test_contract_kit.py +103 -0
  200. rhizodat-0.1.0/tests/contract/test_drevo_contract.py +71 -0
  201. rhizodat-0.1.0/tests/contract/test_iceberg_contract.py +66 -0
  202. rhizodat-0.1.0/tests/contract/test_parts_contracts.py +56 -0
  203. rhizodat-0.1.0/tests/contract/test_postgres_contract.py +52 -0
  204. rhizodat-0.1.0/tests/core/test_adapter.py +268 -0
  205. rhizodat-0.1.0/tests/core/test_clock.py +196 -0
  206. rhizodat-0.1.0/tests/core/test_coordinator.py +594 -0
  207. rhizodat-0.1.0/tests/core/test_dsn.py +204 -0
  208. rhizodat-0.1.0/tests/core/test_entity_vectors.py +257 -0
  209. rhizodat-0.1.0/tests/core/test_errors.py +69 -0
  210. rhizodat-0.1.0/tests/core/test_identity.py +107 -0
  211. rhizodat-0.1.0/tests/core/test_journal.py +439 -0
  212. rhizodat-0.1.0/tests/core/test_mapping.py +322 -0
  213. rhizodat-0.1.0/tests/core/test_mapping_string_annotations.py +44 -0
  214. rhizodat-0.1.0/tests/core/test_native.py +36 -0
  215. rhizodat-0.1.0/tests/core/test_native_clickhouse.py +191 -0
  216. rhizodat-0.1.0/tests/core/test_native_coordinator.py +264 -0
  217. rhizodat-0.1.0/tests/core/test_native_drevo.py +244 -0
  218. rhizodat-0.1.0/tests/core/test_native_execute.py +354 -0
  219. rhizodat-0.1.0/tests/core/test_native_facade.py +450 -0
  220. rhizodat-0.1.0/tests/core/test_native_iceberg.py +287 -0
  221. rhizodat-0.1.0/tests/core/test_native_iceberg_erase.py +128 -0
  222. rhizodat-0.1.0/tests/core/test_native_migrations.py +283 -0
  223. rhizodat-0.1.0/tests/core/test_native_parts.py +329 -0
  224. rhizodat-0.1.0/tests/core/test_native_parts_clickhouse.py +258 -0
  225. rhizodat-0.1.0/tests/core/test_native_parts_drevo.py +312 -0
  226. rhizodat-0.1.0/tests/core/test_native_parts_iceberg.py +259 -0
  227. rhizodat-0.1.0/tests/core/test_native_postgres.py +288 -0
  228. rhizodat-0.1.0/tests/core/test_native_recovery.py +323 -0
  229. rhizodat-0.1.0/tests/core/test_native_result.py +92 -0
  230. rhizodat-0.1.0/tests/core/test_recovery.py +362 -0
  231. rhizodat-0.1.0/tests/core/test_repository.py +449 -0
  232. rhizodat-0.1.0/tests/core/test_repository_valid_time.py +215 -0
  233. rhizodat-0.1.0/tests/core/test_result.py +105 -0
  234. rhizodat-0.1.0/tests/core/test_rows.py +110 -0
  235. rhizodat-0.1.0/tests/core/test_unit_of_work.py +567 -0
  236. rhizodat-0.1.0/tests/drevo_parts.py +25 -0
  237. rhizodat-0.1.0/tests/embed/test_embed_nodes.py +154 -0
  238. rhizodat-0.1.0/tests/embed/test_embedders.py +62 -0
  239. rhizodat-0.1.0/tests/embedders_fixture.py +19 -0
  240. rhizodat-0.1.0/tests/fakes.py +255 -0
  241. rhizodat-0.1.0/tests/iceberg_parts.py +39 -0
  242. rhizodat-0.1.0/tests/ingest/test_import.py +228 -0
  243. rhizodat-0.1.0/tests/ingest/test_import_cli.py +110 -0
  244. rhizodat-0.1.0/tests/ingest/test_infer.py +222 -0
  245. rhizodat-0.1.0/tests/ingest/test_rdf.py +150 -0
  246. rhizodat-0.1.0/tests/ingest/test_relate.py +161 -0
  247. rhizodat-0.1.0/tests/ingest/test_sources_edges.py +146 -0
  248. rhizodat-0.1.0/tests/integration/test_distribution.py +49 -0
  249. rhizodat-0.1.0/tests/integration/test_drevo_journal.py +135 -0
  250. rhizodat-0.1.0/tests/integration/test_dsn_config.py +79 -0
  251. rhizodat-0.1.0/tests/integration/test_entity_vectors_stores.py +158 -0
  252. rhizodat-0.1.0/tests/integration/test_graph_import.py +117 -0
  253. rhizodat-0.1.0/tests/integration/test_identity_and_time.py +114 -0
  254. rhizodat-0.1.0/tests/integration/test_import_stores.py +222 -0
  255. rhizodat-0.1.0/tests/integration/test_journal_processes.py +95 -0
  256. rhizodat-0.1.0/tests/integration/test_mapping_scenarios.py +204 -0
  257. rhizodat-0.1.0/tests/integration/test_meta_transactions.py +129 -0
  258. rhizodat-0.1.0/tests/integration/test_migrations_stores.py +215 -0
  259. rhizodat-0.1.0/tests/integration/test_network_faults.py +202 -0
  260. rhizodat-0.1.0/tests/integration/test_plugin_adapter.py +74 -0
  261. rhizodat-0.1.0/tests/integration/test_postgres_clickhouse_meta_transactions.py +203 -0
  262. rhizodat-0.1.0/tests/integration/test_postgres_drevo_meta_transactions.py +216 -0
  263. rhizodat-0.1.0/tests/integration/test_postgres_iceberg_meta_transactions.py +247 -0
  264. rhizodat-0.1.0/tests/integration/test_postgres_meta_transactions.py +214 -0
  265. rhizodat-0.1.0/tests/integration/test_relate_graph.py +104 -0
  266. rhizodat-0.1.0/tests/integration/test_repository_postgres.py +240 -0
  267. rhizodat-0.1.0/tests/integration/test_repository_postgres_clickhouse.py +218 -0
  268. rhizodat-0.1.0/tests/integration/test_repository_postgres_drevo.py +211 -0
  269. rhizodat-0.1.0/tests/integration/test_repository_postgres_iceberg.py +225 -0
  270. rhizodat-0.1.0/tests/integration/test_store_full.py +101 -0
  271. rhizodat-0.1.0/tests/integration/test_transactional_postgres.py +83 -0
  272. rhizodat-0.1.0/tests/integration/test_valid_time_stores.py +129 -0
  273. rhizodat-0.1.0/tests/mcp_server/test_entity_tools.py +267 -0
  274. rhizodat-0.1.0/tests/mcp_server/test_entity_values.py +96 -0
  275. rhizodat-0.1.0/tests/mcp_server/test_server.py +274 -0
  276. rhizodat-0.1.0/tests/mcp_server/test_server_lifecycle.py +147 -0
  277. rhizodat-0.1.0/tests/mcp_server/test_tools.py +222 -0
  278. rhizodat-0.1.0/tests/mcp_tracker.py +41 -0
  279. rhizodat-0.1.0/tests/migrations/test_cli.py +99 -0
  280. rhizodat-0.1.0/tests/migrations/test_format.py +190 -0
  281. rhizodat-0.1.0/tests/migrations/test_runner.py +262 -0
  282. rhizodat-0.1.0/tests/no_skips.py +26 -0
  283. rhizodat-0.1.0/tests/scenarios/test_bug_tracker.py +315 -0
  284. rhizodat-0.1.0/tests/scenarios/test_cbt_journal.py +358 -0
  285. rhizodat-0.1.0/tests/scenarios/test_erp.py +325 -0
  286. rhizodat-0.1.0/tests/scenarios/test_story_editor.py +358 -0
  287. rhizodat-0.1.0/tests/scenarios/test_task_manager.py +296 -0
  288. rhizodat-0.1.0/tests/stores.py +65 -0
  289. rhizodat-0.1.0/tests/test_adapter_check.py +214 -0
  290. rhizodat-0.1.0/tests/test_examples.py +75 -0
  291. rhizodat-0.1.0/tests/test_no_skips.py +38 -0
  292. rhizodat-0.1.0/tests/test_package.py +102 -0
  293. rhizodat-0.1.0/tests/test_stores.py +82 -0
  294. rhizodat-0.1.0/tests/test_toxiproxy.py +43 -0
  295. rhizodat-0.1.0/tests/toxiproxy.py +85 -0
  296. rhizodat-0.1.0/uv.lock +2867 -0
@@ -0,0 +1,6 @@
1
+ # DSNs of the stores in compose.yaml. A variable set in the environment overrides its line.
2
+ RHIZODAT_TEST_PG_DSN=postgresql://postgres:rhizodat@127.0.0.1:55440/rhizodat
3
+ RHIZODAT_TEST_DREVO_BOLT=drevo+bolt://127.0.0.1:57687
4
+ RHIZODAT_TEST_CLICKHOUSE_DSN=clickhouse://rhizodat:rhizodat@127.0.0.1:58123/rhizodat
5
+ RHIZODAT_TEST_ICEBERG_REST_DSN=iceberg+rest://127.0.0.1:58181/?s3.endpoint=http://127.0.0.1:59000&s3.access-key-id=rhizodat&s3.secret-access-key=rhizodat-secret&s3.region=us-east-1&s3.path-style-access=true
6
+ RHIZODAT_TEST_TOXIPROXY=http://127.0.0.1:58474
@@ -0,0 +1,39 @@
1
+ name: Feedback on the proof of concept
2
+ description: You tried rhizodat 0.1.0a1 — what worked, what did not, what is missing for you.
3
+ title: "Feedback: "
4
+ labels: ["feedback"]
5
+ body:
6
+ - type: input
7
+ id: version
8
+ attributes:
9
+ label: Version and install
10
+ description: "`pip show rhizodat rhizodat-native`, or the commit."
11
+ placeholder: "rhizodat 0.1.0a1, rhizodat-native 0.1.0a1, Python 3.13, macOS"
12
+ validations:
13
+ required: true
14
+ - type: dropdown
15
+ id: stores
16
+ attributes:
17
+ label: Stores you used
18
+ multiple: true
19
+ options: [PostgreSQL, ClickHouse, drevo, Iceberg]
20
+ - type: textarea
21
+ id: scenario
22
+ attributes:
23
+ label: What you tried to build
24
+ description: The use case in a few lines — the data model and the writes/reads.
25
+ validations:
26
+ required: true
27
+ - type: textarea
28
+ id: worked
29
+ attributes:
30
+ label: What worked
31
+ - type: textarea
32
+ id: failed
33
+ attributes:
34
+ label: What did not work, or was confusing
35
+ description: Error text in a code block, please; the shortest script that shows it is ideal.
36
+ - type: textarea
37
+ id: missing
38
+ attributes:
39
+ label: What is missing before you would use it
@@ -0,0 +1,118 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ jobs:
16
+ lint:
17
+ runs-on: ubuntu-latest
18
+ timeout-minutes: 10
19
+ steps:
20
+ - uses: actions/checkout@v5
21
+ - uses: astral-sh/setup-uv@v6
22
+ with:
23
+ python-version: "3.12"
24
+ - run: uv lock --check
25
+ - run: uv sync --locked
26
+ - run: uv run ruff check .
27
+ - run: uv run ruff format --check .
28
+ - run: uv run mypy
29
+
30
+ docs:
31
+ # The documentation site builds with no broken link, anchor or API reference.
32
+ runs-on: ubuntu-latest
33
+ timeout-minutes: 10
34
+ steps:
35
+ - uses: actions/checkout@v5
36
+ - uses: astral-sh/setup-uv@v6
37
+ with:
38
+ python-version: "3.12"
39
+ - run: uv sync --locked --group docs
40
+ - run: uv run --group docs mkdocs build --strict
41
+
42
+ rust:
43
+ # rhizodat-core: the same conformance vectors as the Python reference.
44
+ runs-on: ubuntu-latest
45
+ timeout-minutes: 15
46
+ strategy:
47
+ fail-fast: false
48
+ matrix:
49
+ toolchain: [stable, "1.94"]
50
+ steps:
51
+ - uses: actions/checkout@v5
52
+ - run: rustup toolchain install ${{ matrix.toolchain }} --profile minimal --component clippy,rustfmt
53
+ - run: rustup default ${{ matrix.toolchain }}
54
+ - uses: Swatinem/rust-cache@v2
55
+ # The adapter crates' tests run against the compose PostgreSQL, drevo, ClickHouse and
56
+ # Iceberg REST catalog; the exported DSNs make a store that is down fail the run
57
+ # instead of skipping.
58
+ - name: Start PostgreSQL, drevo, ClickHouse and the Iceberg REST catalog
59
+ run: |
60
+ docker compose --profile clickhouse --profile iceberg up -d --wait postgres drevo clickhouse iceberg-rest
61
+ grep -E '^RHIZODAT_TEST_(PG_DSN|DREVO_BOLT|CLICKHOUSE_DSN|ICEBERG_REST_DSN)=' .env.test >> "$GITHUB_ENV"
62
+ - if: matrix.toolchain == 'stable'
63
+ run: cargo fmt --check
64
+ - if: matrix.toolchain == 'stable'
65
+ run: cargo clippy --locked --all-targets --all-features -- -D warnings
66
+ # --all-features includes embedded drevo (rhizodat-drevo/embedded), built from the
67
+ # pinned drevo commit.
68
+ - run: cargo test --locked --all-features
69
+
70
+ test:
71
+ runs-on: ${{ matrix.os }}
72
+ timeout-minutes: 15
73
+ strategy:
74
+ fail-fast: false
75
+ matrix:
76
+ os: [ubuntu-latest]
77
+ python: ["3.12", "3.13", "3.14"]
78
+ include:
79
+ - os: macos-latest
80
+ python: "3.12"
81
+ steps:
82
+ - uses: actions/checkout@v5
83
+ - uses: astral-sh/setup-uv@v6
84
+ with:
85
+ python-version: ${{ matrix.python }}
86
+ # The stores from compose.yaml. Exporting .env.test makes the DSNs explicit, so a
87
+ # store that is down fails the run instead of skipping its tests. macOS runners have
88
+ # no Docker: there the store-backed tests skip.
89
+ - name: Start the test stores
90
+ if: runner.os == 'Linux'
91
+ run: |
92
+ docker compose --profile clickhouse --profile iceberg --profile faults up -d --wait
93
+ grep -v '^#' .env.test >> "$GITHUB_ENV"
94
+ - run: uv sync --locked
95
+ - run: uv run pytest
96
+
97
+ drevo-embedded:
98
+ # The full suite with every store and embedded drevo, where nothing may skip: a skip
99
+ # here means a test silently stopped running. drevo-py is not on PyPI yet: it is
100
+ # built from the pinned commit (Rust), cached by uv.
101
+ runs-on: ubuntu-latest
102
+ timeout-minutes: 30
103
+ env:
104
+ RHIZODAT_TEST_NO_SKIPS: "1"
105
+ steps:
106
+ - uses: actions/checkout@v5
107
+ - uses: astral-sh/setup-uv@v6
108
+ with:
109
+ python-version: "3.13"
110
+ enable-cache: true
111
+ - name: Start the test stores
112
+ run: |
113
+ docker compose --profile clickhouse --profile iceberg --profile faults up -d --wait
114
+ grep -v '^#' .env.test >> "$GITHUB_ENV"
115
+ # native: the Rust core's Python module (crates/rhizodat-py), so its vectors run here.
116
+ - run: uv sync --locked --group drevo --group native
117
+ # Coverage of src/rhizodat with branches; below 92 % the job fails.
118
+ - run: uv run --group drevo --group native pytest --cov --cov-report=term-missing:skip-covered
@@ -0,0 +1,41 @@
1
+ name: Docs
2
+
3
+ # Publishes the documentation site to GitHub Pages on every push to main.
4
+ on:
5
+ push:
6
+ branches: [main]
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+ pages: write
12
+ id-token: write
13
+
14
+ concurrency:
15
+ group: pages
16
+ cancel-in-progress: false
17
+
18
+ jobs:
19
+ build:
20
+ runs-on: ubuntu-latest
21
+ timeout-minutes: 10
22
+ steps:
23
+ - uses: actions/checkout@v5
24
+ - uses: astral-sh/setup-uv@v6
25
+ with:
26
+ python-version: "3.12"
27
+ - run: uv sync --locked --group docs
28
+ - run: uv run --group docs mkdocs build --strict
29
+ - uses: actions/upload-pages-artifact@v3
30
+ with:
31
+ path: site
32
+
33
+ deploy:
34
+ needs: build
35
+ runs-on: ubuntu-latest
36
+ environment:
37
+ name: github-pages
38
+ url: ${{ steps.deployment.outputs.page_url }}
39
+ steps:
40
+ - id: deployment
41
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,113 @@
1
+ name: Release
2
+
3
+ # A tag `vX.Y.Z` (or a pre-release like `v0.1.0a1`) builds the `rhizodat` package and
4
+ # the `rhizodat-native` wheels (abi3, one per platform), attaches them to a GitHub
5
+ # release and publishes both to PyPI through trusted publishing (the `pypi`
6
+ # environment; PyPI must list this workflow as the publisher of both projects).
7
+ on:
8
+ push:
9
+ tags: ["v*"]
10
+ workflow_dispatch:
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ package:
17
+ # rhizodat (pure Python: sdist + wheel) and the rhizodat-native sdist.
18
+ runs-on: ubuntu-latest
19
+ timeout-minutes: 10
20
+ steps:
21
+ - uses: actions/checkout@v5
22
+ - uses: astral-sh/setup-uv@v6
23
+ with:
24
+ python-version: "3.12"
25
+ - run: uv build --out-dir dist
26
+ - run: uvx maturin sdist --manifest-path crates/rhizodat-py/Cargo.toml --out dist
27
+ - name: The tag is the package version
28
+ if: github.ref_type == 'tag'
29
+ run: |
30
+ version=$(python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')
31
+ test "v$version" = "${{ github.ref_name }}" || { echo "tag ${{ github.ref_name }} != v$version"; exit 1; }
32
+ - uses: actions/upload-artifact@v4
33
+ with:
34
+ name: package
35
+ path: dist/*
36
+
37
+ native:
38
+ # rhizodat-native wheels: abi3 (one wheel serves every CPython >= 3.12).
39
+ runs-on: ${{ matrix.os }}
40
+ timeout-minutes: 45
41
+ strategy:
42
+ fail-fast: false
43
+ matrix:
44
+ include:
45
+ - os: ubuntu-latest
46
+ target: x86_64
47
+ - os: ubuntu-24.04-arm
48
+ target: aarch64
49
+ - os: macos-latest
50
+ target: aarch64
51
+ - os: macos-15-intel
52
+ target: x86_64
53
+ steps:
54
+ - uses: actions/checkout@v5
55
+ - uses: actions/setup-python@v5
56
+ with:
57
+ python-version: "3.12"
58
+ - uses: PyO3/maturin-action@v1
59
+ with:
60
+ target: ${{ matrix.target }}
61
+ manylinux: auto
62
+ working-directory: crates/rhizodat-py
63
+ args: --release --locked --out ../../dist --interpreter python3.12
64
+ sccache: true
65
+ - name: The wheel imports from a clean environment
66
+ run: |
67
+ python -m venv smoke
68
+ smoke/bin/pip install --no-index --find-links dist rhizodat-native
69
+ smoke/bin/python -c "import rhizodat_native as n; print(n.__version__, n.new_id())"
70
+ - uses: actions/upload-artifact@v4
71
+ with:
72
+ name: native-${{ matrix.os }}-${{ matrix.target }}
73
+ path: dist/*.whl
74
+
75
+ github-release:
76
+ needs: [package, native]
77
+ if: github.ref_type == 'tag'
78
+ runs-on: ubuntu-latest
79
+ timeout-minutes: 10
80
+ permissions:
81
+ contents: write
82
+ steps:
83
+ - uses: actions/download-artifact@v4
84
+ with:
85
+ path: dist
86
+ merge-multiple: true
87
+ - name: Create the release with the distributions attached
88
+ env:
89
+ GH_TOKEN: ${{ github.token }}
90
+ TAG: ${{ github.ref_name }}
91
+ run: |
92
+ flags=(--generate-notes)
93
+ case "$TAG" in *a*|*b*|*rc*) flags+=(--prerelease);; esac
94
+ gh release create "$TAG" --repo "$GITHUB_REPOSITORY" "${flags[@]}" dist/*
95
+
96
+ pypi:
97
+ needs: [package, native]
98
+ if: github.ref_type == 'tag'
99
+ runs-on: ubuntu-latest
100
+ timeout-minutes: 10
101
+ environment:
102
+ name: pypi
103
+ url: https://pypi.org/project/rhizodat/
104
+ permissions:
105
+ id-token: write
106
+ steps:
107
+ - uses: actions/download-artifact@v4
108
+ with:
109
+ path: dist
110
+ merge-multiple: true
111
+ - uses: pypa/gh-action-pypi-publish@release/v1
112
+ with:
113
+ packages-dir: dist
@@ -0,0 +1,210 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+ #poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ #pdm.lock
116
+ #pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ #pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # SageMath parsed files
135
+ *.sage.py
136
+
137
+ # Environments
138
+ .env
139
+ .envrc
140
+ .venv
141
+ env/
142
+ venv/
143
+ ENV/
144
+ env.bak/
145
+ venv.bak/
146
+
147
+ # Spyder project settings
148
+ .spyderproject
149
+ .spyproject
150
+
151
+ # Rope project settings
152
+ .ropeproject
153
+
154
+ # mkdocs documentation
155
+ /site
156
+
157
+ # mypy
158
+ .mypy_cache/
159
+ .dmypy.json
160
+ dmypy.json
161
+
162
+ # Pyre type checker
163
+ .pyre/
164
+
165
+ # pytype static type analyzer
166
+ .pytype/
167
+
168
+ # Cython debug symbols
169
+ cython_debug/
170
+
171
+ # PyCharm
172
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
173
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
174
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
175
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
176
+ #.idea/
177
+
178
+ # Abstra
179
+ # Abstra is an AI-powered process automation framework.
180
+ # Ignore directories containing user credentials, local state, and settings.
181
+ # Learn more at https://abstra.io/docs
182
+ .abstra/
183
+
184
+ # Visual Studio Code
185
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
188
+ # you could uncomment the following to ignore the entire vscode folder
189
+ # .vscode/
190
+
191
+ # Ruff stuff:
192
+ .ruff_cache/
193
+
194
+ # PyPI configuration file
195
+ .pypirc
196
+
197
+ # Cursor
198
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
199
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
200
+ # refer to https://docs.cursor.com/context/ignore-files
201
+ .cursorignore
202
+ .cursorindexingignore
203
+
204
+ # Marimo
205
+ marimo/_static/
206
+ marimo/_lsp/
207
+ __marimo__/
208
+
209
+ # mkdocs build output
210
+ /site/
@@ -0,0 +1,40 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — the MVP
4
+
5
+ The v0.1 roadmap is complete. Since 0.1.0a1:
6
+
7
+ - **Five end-to-end scenarios** in `tests/scenarios/` (a CBT journal, a bug
8
+ tracker, an ERP with valid time, an IT task manager, a story editor), each run
9
+ on the Python facade and on the native facade and closed with the same data
10
+ worked from both in turn. They are the reference for how an application uses
11
+ the package.
12
+ - **The shipped stores and their limits**: one documentation page per store and
13
+ per facade with every known limit (`docs/adapters/stores.md`).
14
+ - Packaging: `rhizodat[native]` pins the Rust core to the package version;
15
+ the `Release` workflow builds the wheels for Linux and macOS on x86_64 and
16
+ arm64 from a `v*` tag.
17
+
18
+ ## 0.1.0a1 — proof of concept
19
+
20
+ The first public pre-release. One API over PostgreSQL, ClickHouse,
21
+ [drevo](https://github.com/ice1x/drevo) and Apache Iceberg:
22
+
23
+ - **Meta-transactions**: a Unit of Work across several stores commits atomically
24
+ (two-phase commit where the store has it, journaled one-phase application
25
+ after the decision where it does not), with retries and crash recovery.
26
+ - **Bitemporal repositories**: every version of an entity is kept, with
27
+ transaction time and valid time; reads `as_of` / `known_at`, history.
28
+ - **Entities over several stores**: an entity's parts may live in different
29
+ stores and are written in one meta-transaction.
30
+ - **Migrations**: one TOML format for every store, the history in the journal.
31
+ - **Imports**: files into stores with schema inference (`rhizodat import`).
32
+ - **An MCP server** (`rhizodat-mcp`) and an adapter contract kit
33
+ (`rhizodat[testing]`) for adapter authors.
34
+ - **The core in Rust**, opt-in: `pip install 'rhizodat[native]'` adds
35
+ `rhizodat_native`, whose stores, journal, coordinator and recovery run the
36
+ same protocol with no Python on the path; the Python package stays the
37
+ executable specification, and both pass one conformance suite.
38
+
39
+ Known limits are listed per adapter in the documentation. Feedback on this
40
+ release: open an issue with the "Feedback on the proof of concept" template.