nucliadb 2.46.1.post382__py3-none-any.whl → 6.2.1.post2777__py3-none-any.whl

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 (431) hide show
  1. migrations/0002_rollover_shards.py +1 -2
  2. migrations/0003_allfields_key.py +2 -37
  3. migrations/0004_rollover_shards.py +1 -2
  4. migrations/0005_rollover_shards.py +1 -2
  5. migrations/0006_rollover_shards.py +2 -4
  6. migrations/0008_cleanup_leftover_rollover_metadata.py +1 -2
  7. migrations/0009_upgrade_relations_and_texts_to_v2.py +5 -4
  8. migrations/0010_fix_corrupt_indexes.py +11 -12
  9. migrations/0011_materialize_labelset_ids.py +2 -18
  10. migrations/0012_rollover_shards.py +6 -12
  11. migrations/0013_rollover_shards.py +2 -4
  12. migrations/0014_rollover_shards.py +5 -7
  13. migrations/0015_targeted_rollover.py +6 -12
  14. migrations/0016_upgrade_to_paragraphs_v2.py +27 -32
  15. migrations/0017_multiple_writable_shards.py +3 -6
  16. migrations/0018_purge_orphan_kbslugs.py +59 -0
  17. migrations/0019_upgrade_to_paragraphs_v3.py +66 -0
  18. migrations/0020_drain_nodes_from_cluster.py +83 -0
  19. nucliadb/standalone/tests/unit/test_run.py → migrations/0021_overwrite_vectorsets_key.py +17 -18
  20. nucliadb/tests/unit/test_openapi.py → migrations/0022_fix_paragraph_deletion_bug.py +16 -11
  21. migrations/0023_backfill_pg_catalog.py +80 -0
  22. migrations/0025_assign_models_to_kbs_v2.py +113 -0
  23. migrations/0026_fix_high_cardinality_content_types.py +61 -0
  24. migrations/0027_rollover_texts3.py +73 -0
  25. nucliadb/ingest/fields/date.py → migrations/pg/0001_bootstrap.py +10 -12
  26. migrations/pg/0002_catalog.py +42 -0
  27. nucliadb/ingest/tests/unit/test_settings.py → migrations/pg/0003_catalog_kbid_index.py +5 -3
  28. nucliadb/common/cluster/base.py +41 -24
  29. nucliadb/common/cluster/discovery/base.py +6 -14
  30. nucliadb/common/cluster/discovery/k8s.py +9 -19
  31. nucliadb/common/cluster/discovery/manual.py +1 -3
  32. nucliadb/common/cluster/discovery/single.py +1 -2
  33. nucliadb/common/cluster/discovery/utils.py +1 -3
  34. nucliadb/common/cluster/grpc_node_dummy.py +11 -16
  35. nucliadb/common/cluster/index_node.py +10 -19
  36. nucliadb/common/cluster/manager.py +223 -102
  37. nucliadb/common/cluster/rebalance.py +42 -37
  38. nucliadb/common/cluster/rollover.py +377 -204
  39. nucliadb/common/cluster/settings.py +16 -9
  40. nucliadb/common/cluster/standalone/grpc_node_binding.py +24 -76
  41. nucliadb/common/cluster/standalone/index_node.py +4 -11
  42. nucliadb/common/cluster/standalone/service.py +2 -6
  43. nucliadb/common/cluster/standalone/utils.py +9 -6
  44. nucliadb/common/cluster/utils.py +43 -29
  45. nucliadb/common/constants.py +20 -0
  46. nucliadb/common/context/__init__.py +6 -4
  47. nucliadb/common/context/fastapi.py +8 -5
  48. nucliadb/{tests/knowledgeboxes/__init__.py → common/counters.py} +8 -2
  49. nucliadb/common/datamanagers/__init__.py +24 -5
  50. nucliadb/common/datamanagers/atomic.py +102 -0
  51. nucliadb/common/datamanagers/cluster.py +5 -5
  52. nucliadb/common/datamanagers/entities.py +6 -16
  53. nucliadb/common/datamanagers/fields.py +84 -0
  54. nucliadb/common/datamanagers/kb.py +101 -24
  55. nucliadb/common/datamanagers/labels.py +26 -56
  56. nucliadb/common/datamanagers/processing.py +2 -6
  57. nucliadb/common/datamanagers/resources.py +214 -117
  58. nucliadb/common/datamanagers/rollover.py +77 -16
  59. nucliadb/{ingest/orm → common/datamanagers}/synonyms.py +16 -28
  60. nucliadb/common/datamanagers/utils.py +19 -11
  61. nucliadb/common/datamanagers/vectorsets.py +110 -0
  62. nucliadb/common/external_index_providers/base.py +257 -0
  63. nucliadb/{ingest/tests/unit/test_cache.py → common/external_index_providers/exceptions.py} +9 -8
  64. nucliadb/common/external_index_providers/manager.py +101 -0
  65. nucliadb/common/external_index_providers/pinecone.py +933 -0
  66. nucliadb/common/external_index_providers/settings.py +52 -0
  67. nucliadb/common/http_clients/auth.py +3 -6
  68. nucliadb/common/http_clients/processing.py +6 -11
  69. nucliadb/common/http_clients/utils.py +1 -3
  70. nucliadb/common/ids.py +240 -0
  71. nucliadb/common/locking.py +43 -13
  72. nucliadb/common/maindb/driver.py +11 -35
  73. nucliadb/common/maindb/exceptions.py +6 -6
  74. nucliadb/common/maindb/local.py +22 -9
  75. nucliadb/common/maindb/pg.py +206 -111
  76. nucliadb/common/maindb/utils.py +13 -44
  77. nucliadb/common/models_utils/from_proto.py +479 -0
  78. nucliadb/common/models_utils/to_proto.py +60 -0
  79. nucliadb/common/nidx.py +260 -0
  80. nucliadb/export_import/datamanager.py +25 -19
  81. nucliadb/export_import/exceptions.py +8 -0
  82. nucliadb/export_import/exporter.py +20 -7
  83. nucliadb/export_import/importer.py +6 -11
  84. nucliadb/export_import/models.py +5 -5
  85. nucliadb/export_import/tasks.py +4 -4
  86. nucliadb/export_import/utils.py +94 -54
  87. nucliadb/health.py +1 -3
  88. nucliadb/ingest/app.py +15 -11
  89. nucliadb/ingest/consumer/auditing.py +30 -147
  90. nucliadb/ingest/consumer/consumer.py +96 -52
  91. nucliadb/ingest/consumer/materializer.py +10 -12
  92. nucliadb/ingest/consumer/pull.py +12 -27
  93. nucliadb/ingest/consumer/service.py +20 -19
  94. nucliadb/ingest/consumer/shard_creator.py +7 -14
  95. nucliadb/ingest/consumer/utils.py +1 -3
  96. nucliadb/ingest/fields/base.py +139 -188
  97. nucliadb/ingest/fields/conversation.py +18 -5
  98. nucliadb/ingest/fields/exceptions.py +1 -4
  99. nucliadb/ingest/fields/file.py +7 -25
  100. nucliadb/ingest/fields/link.py +11 -16
  101. nucliadb/ingest/fields/text.py +9 -4
  102. nucliadb/ingest/orm/brain.py +255 -262
  103. nucliadb/ingest/orm/broker_message.py +181 -0
  104. nucliadb/ingest/orm/entities.py +36 -51
  105. nucliadb/ingest/orm/exceptions.py +12 -0
  106. nucliadb/ingest/orm/knowledgebox.py +334 -278
  107. nucliadb/ingest/orm/processor/__init__.py +2 -697
  108. nucliadb/ingest/orm/processor/auditing.py +117 -0
  109. nucliadb/ingest/orm/processor/data_augmentation.py +164 -0
  110. nucliadb/ingest/orm/processor/pgcatalog.py +84 -0
  111. nucliadb/ingest/orm/processor/processor.py +752 -0
  112. nucliadb/ingest/orm/processor/sequence_manager.py +1 -1
  113. nucliadb/ingest/orm/resource.py +280 -520
  114. nucliadb/ingest/orm/utils.py +25 -31
  115. nucliadb/ingest/partitions.py +3 -9
  116. nucliadb/ingest/processing.py +76 -81
  117. nucliadb/ingest/py.typed +0 -0
  118. nucliadb/ingest/serialize.py +37 -173
  119. nucliadb/ingest/service/__init__.py +1 -3
  120. nucliadb/ingest/service/writer.py +186 -577
  121. nucliadb/ingest/settings.py +13 -22
  122. nucliadb/ingest/utils.py +3 -6
  123. nucliadb/learning_proxy.py +264 -51
  124. nucliadb/metrics_exporter.py +30 -19
  125. nucliadb/middleware/__init__.py +1 -3
  126. nucliadb/migrator/command.py +1 -3
  127. nucliadb/migrator/datamanager.py +13 -13
  128. nucliadb/migrator/migrator.py +57 -37
  129. nucliadb/migrator/settings.py +2 -1
  130. nucliadb/migrator/utils.py +18 -10
  131. nucliadb/purge/__init__.py +139 -33
  132. nucliadb/purge/orphan_shards.py +7 -13
  133. nucliadb/reader/__init__.py +1 -3
  134. nucliadb/reader/api/models.py +3 -14
  135. nucliadb/reader/api/v1/__init__.py +0 -1
  136. nucliadb/reader/api/v1/download.py +27 -94
  137. nucliadb/reader/api/v1/export_import.py +4 -4
  138. nucliadb/reader/api/v1/knowledgebox.py +13 -13
  139. nucliadb/reader/api/v1/learning_config.py +8 -12
  140. nucliadb/reader/api/v1/resource.py +67 -93
  141. nucliadb/reader/api/v1/services.py +70 -125
  142. nucliadb/reader/app.py +16 -46
  143. nucliadb/reader/lifecycle.py +18 -4
  144. nucliadb/reader/py.typed +0 -0
  145. nucliadb/reader/reader/notifications.py +10 -31
  146. nucliadb/search/__init__.py +1 -3
  147. nucliadb/search/api/v1/__init__.py +2 -2
  148. nucliadb/search/api/v1/ask.py +112 -0
  149. nucliadb/search/api/v1/catalog.py +184 -0
  150. nucliadb/search/api/v1/feedback.py +17 -25
  151. nucliadb/search/api/v1/find.py +41 -41
  152. nucliadb/search/api/v1/knowledgebox.py +90 -62
  153. nucliadb/search/api/v1/predict_proxy.py +2 -2
  154. nucliadb/search/api/v1/resource/ask.py +66 -117
  155. nucliadb/search/api/v1/resource/search.py +51 -72
  156. nucliadb/search/api/v1/router.py +1 -0
  157. nucliadb/search/api/v1/search.py +50 -197
  158. nucliadb/search/api/v1/suggest.py +40 -54
  159. nucliadb/search/api/v1/summarize.py +9 -5
  160. nucliadb/search/api/v1/utils.py +2 -1
  161. nucliadb/search/app.py +16 -48
  162. nucliadb/search/lifecycle.py +10 -3
  163. nucliadb/search/predict.py +176 -188
  164. nucliadb/search/py.typed +0 -0
  165. nucliadb/search/requesters/utils.py +41 -63
  166. nucliadb/search/search/cache.py +149 -20
  167. nucliadb/search/search/chat/ask.py +918 -0
  168. nucliadb/search/{tests/unit/test_run.py → search/chat/exceptions.py} +14 -13
  169. nucliadb/search/search/chat/images.py +41 -17
  170. nucliadb/search/search/chat/prompt.py +851 -282
  171. nucliadb/search/search/chat/query.py +274 -267
  172. nucliadb/{writer/resource/slug.py → search/search/cut.py} +8 -6
  173. nucliadb/search/search/fetch.py +43 -36
  174. nucliadb/search/search/filters.py +9 -15
  175. nucliadb/search/search/find.py +214 -54
  176. nucliadb/search/search/find_merge.py +408 -391
  177. nucliadb/search/search/hydrator.py +191 -0
  178. nucliadb/search/search/merge.py +198 -234
  179. nucliadb/search/search/metrics.py +73 -2
  180. nucliadb/search/search/paragraphs.py +64 -106
  181. nucliadb/search/search/pgcatalog.py +233 -0
  182. nucliadb/search/search/predict_proxy.py +1 -1
  183. nucliadb/search/search/query.py +386 -257
  184. nucliadb/search/search/query_parser/exceptions.py +22 -0
  185. nucliadb/search/search/query_parser/models.py +101 -0
  186. nucliadb/search/search/query_parser/parser.py +183 -0
  187. nucliadb/search/search/rank_fusion.py +204 -0
  188. nucliadb/search/search/rerankers.py +270 -0
  189. nucliadb/search/search/shards.py +4 -38
  190. nucliadb/search/search/summarize.py +14 -18
  191. nucliadb/search/search/utils.py +27 -4
  192. nucliadb/search/settings.py +15 -1
  193. nucliadb/standalone/api_router.py +4 -10
  194. nucliadb/standalone/app.py +17 -14
  195. nucliadb/standalone/auth.py +7 -21
  196. nucliadb/standalone/config.py +9 -12
  197. nucliadb/standalone/introspect.py +5 -5
  198. nucliadb/standalone/lifecycle.py +26 -25
  199. nucliadb/standalone/migrations.py +58 -0
  200. nucliadb/standalone/purge.py +9 -8
  201. nucliadb/standalone/py.typed +0 -0
  202. nucliadb/standalone/run.py +25 -18
  203. nucliadb/standalone/settings.py +10 -14
  204. nucliadb/standalone/versions.py +15 -5
  205. nucliadb/tasks/consumer.py +8 -12
  206. nucliadb/tasks/producer.py +7 -6
  207. nucliadb/tests/config.py +53 -0
  208. nucliadb/train/__init__.py +1 -3
  209. nucliadb/train/api/utils.py +1 -2
  210. nucliadb/train/api/v1/shards.py +2 -2
  211. nucliadb/train/api/v1/trainset.py +4 -6
  212. nucliadb/train/app.py +14 -47
  213. nucliadb/train/generator.py +10 -19
  214. nucliadb/train/generators/field_classifier.py +7 -19
  215. nucliadb/train/generators/field_streaming.py +156 -0
  216. nucliadb/train/generators/image_classifier.py +12 -18
  217. nucliadb/train/generators/paragraph_classifier.py +5 -9
  218. nucliadb/train/generators/paragraph_streaming.py +6 -9
  219. nucliadb/train/generators/question_answer_streaming.py +19 -20
  220. nucliadb/train/generators/sentence_classifier.py +9 -15
  221. nucliadb/train/generators/token_classifier.py +45 -36
  222. nucliadb/train/generators/utils.py +14 -18
  223. nucliadb/train/lifecycle.py +7 -3
  224. nucliadb/train/nodes.py +23 -32
  225. nucliadb/train/py.typed +0 -0
  226. nucliadb/train/servicer.py +13 -21
  227. nucliadb/train/settings.py +2 -6
  228. nucliadb/train/types.py +13 -10
  229. nucliadb/train/upload.py +3 -6
  230. nucliadb/train/uploader.py +20 -25
  231. nucliadb/train/utils.py +1 -1
  232. nucliadb/writer/__init__.py +1 -3
  233. nucliadb/writer/api/constants.py +0 -5
  234. nucliadb/{ingest/fields/keywordset.py → writer/api/utils.py} +13 -10
  235. nucliadb/writer/api/v1/export_import.py +102 -49
  236. nucliadb/writer/api/v1/field.py +196 -620
  237. nucliadb/writer/api/v1/knowledgebox.py +221 -71
  238. nucliadb/writer/api/v1/learning_config.py +2 -2
  239. nucliadb/writer/api/v1/resource.py +114 -216
  240. nucliadb/writer/api/v1/services.py +64 -132
  241. nucliadb/writer/api/v1/slug.py +61 -0
  242. nucliadb/writer/api/v1/transaction.py +67 -0
  243. nucliadb/writer/api/v1/upload.py +184 -215
  244. nucliadb/writer/app.py +11 -61
  245. nucliadb/writer/back_pressure.py +62 -43
  246. nucliadb/writer/exceptions.py +0 -4
  247. nucliadb/writer/lifecycle.py +21 -15
  248. nucliadb/writer/py.typed +0 -0
  249. nucliadb/writer/resource/audit.py +2 -1
  250. nucliadb/writer/resource/basic.py +48 -62
  251. nucliadb/writer/resource/field.py +45 -135
  252. nucliadb/writer/resource/origin.py +1 -2
  253. nucliadb/writer/settings.py +14 -5
  254. nucliadb/writer/tus/__init__.py +17 -15
  255. nucliadb/writer/tus/azure.py +111 -0
  256. nucliadb/writer/tus/dm.py +17 -5
  257. nucliadb/writer/tus/exceptions.py +1 -3
  258. nucliadb/writer/tus/gcs.py +56 -84
  259. nucliadb/writer/tus/local.py +21 -37
  260. nucliadb/writer/tus/s3.py +28 -68
  261. nucliadb/writer/tus/storage.py +5 -56
  262. nucliadb/writer/vectorsets.py +125 -0
  263. nucliadb-6.2.1.post2777.dist-info/METADATA +148 -0
  264. nucliadb-6.2.1.post2777.dist-info/RECORD +343 -0
  265. {nucliadb-2.46.1.post382.dist-info → nucliadb-6.2.1.post2777.dist-info}/WHEEL +1 -1
  266. nucliadb/common/maindb/redis.py +0 -194
  267. nucliadb/common/maindb/tikv.py +0 -412
  268. nucliadb/ingest/fields/layout.py +0 -58
  269. nucliadb/ingest/tests/conftest.py +0 -30
  270. nucliadb/ingest/tests/fixtures.py +0 -771
  271. nucliadb/ingest/tests/integration/consumer/__init__.py +0 -18
  272. nucliadb/ingest/tests/integration/consumer/test_auditing.py +0 -80
  273. nucliadb/ingest/tests/integration/consumer/test_materializer.py +0 -89
  274. nucliadb/ingest/tests/integration/consumer/test_pull.py +0 -144
  275. nucliadb/ingest/tests/integration/consumer/test_service.py +0 -81
  276. nucliadb/ingest/tests/integration/consumer/test_shard_creator.py +0 -68
  277. nucliadb/ingest/tests/integration/ingest/test_ingest.py +0 -691
  278. nucliadb/ingest/tests/integration/ingest/test_processing_engine.py +0 -95
  279. nucliadb/ingest/tests/integration/ingest/test_relations.py +0 -272
  280. nucliadb/ingest/tests/unit/consumer/__init__.py +0 -18
  281. nucliadb/ingest/tests/unit/consumer/test_auditing.py +0 -140
  282. nucliadb/ingest/tests/unit/consumer/test_consumer.py +0 -69
  283. nucliadb/ingest/tests/unit/consumer/test_pull.py +0 -60
  284. nucliadb/ingest/tests/unit/consumer/test_shard_creator.py +0 -139
  285. nucliadb/ingest/tests/unit/consumer/test_utils.py +0 -67
  286. nucliadb/ingest/tests/unit/orm/__init__.py +0 -19
  287. nucliadb/ingest/tests/unit/orm/test_brain.py +0 -247
  288. nucliadb/ingest/tests/unit/orm/test_processor.py +0 -131
  289. nucliadb/ingest/tests/unit/orm/test_resource.py +0 -275
  290. nucliadb/ingest/tests/unit/test_partitions.py +0 -40
  291. nucliadb/ingest/tests/unit/test_processing.py +0 -171
  292. nucliadb/middleware/transaction.py +0 -117
  293. nucliadb/reader/api/v1/learning_collector.py +0 -63
  294. nucliadb/reader/tests/__init__.py +0 -19
  295. nucliadb/reader/tests/conftest.py +0 -31
  296. nucliadb/reader/tests/fixtures.py +0 -136
  297. nucliadb/reader/tests/test_list_resources.py +0 -75
  298. nucliadb/reader/tests/test_reader_file_download.py +0 -273
  299. nucliadb/reader/tests/test_reader_resource.py +0 -379
  300. nucliadb/reader/tests/test_reader_resource_field.py +0 -219
  301. nucliadb/search/api/v1/chat.py +0 -258
  302. nucliadb/search/api/v1/resource/chat.py +0 -94
  303. nucliadb/search/tests/__init__.py +0 -19
  304. nucliadb/search/tests/conftest.py +0 -33
  305. nucliadb/search/tests/fixtures.py +0 -199
  306. nucliadb/search/tests/node.py +0 -465
  307. nucliadb/search/tests/unit/__init__.py +0 -18
  308. nucliadb/search/tests/unit/api/__init__.py +0 -19
  309. nucliadb/search/tests/unit/api/v1/__init__.py +0 -19
  310. nucliadb/search/tests/unit/api/v1/resource/__init__.py +0 -19
  311. nucliadb/search/tests/unit/api/v1/resource/test_ask.py +0 -67
  312. nucliadb/search/tests/unit/api/v1/resource/test_chat.py +0 -97
  313. nucliadb/search/tests/unit/api/v1/test_chat.py +0 -96
  314. nucliadb/search/tests/unit/api/v1/test_predict_proxy.py +0 -98
  315. nucliadb/search/tests/unit/api/v1/test_summarize.py +0 -93
  316. nucliadb/search/tests/unit/search/__init__.py +0 -18
  317. nucliadb/search/tests/unit/search/requesters/__init__.py +0 -18
  318. nucliadb/search/tests/unit/search/requesters/test_utils.py +0 -210
  319. nucliadb/search/tests/unit/search/search/__init__.py +0 -19
  320. nucliadb/search/tests/unit/search/search/test_shards.py +0 -45
  321. nucliadb/search/tests/unit/search/search/test_utils.py +0 -82
  322. nucliadb/search/tests/unit/search/test_chat_prompt.py +0 -266
  323. nucliadb/search/tests/unit/search/test_fetch.py +0 -108
  324. nucliadb/search/tests/unit/search/test_filters.py +0 -125
  325. nucliadb/search/tests/unit/search/test_paragraphs.py +0 -157
  326. nucliadb/search/tests/unit/search/test_predict_proxy.py +0 -106
  327. nucliadb/search/tests/unit/search/test_query.py +0 -201
  328. nucliadb/search/tests/unit/test_app.py +0 -79
  329. nucliadb/search/tests/unit/test_find_merge.py +0 -112
  330. nucliadb/search/tests/unit/test_merge.py +0 -34
  331. nucliadb/search/tests/unit/test_predict.py +0 -584
  332. nucliadb/standalone/tests/__init__.py +0 -19
  333. nucliadb/standalone/tests/conftest.py +0 -33
  334. nucliadb/standalone/tests/fixtures.py +0 -38
  335. nucliadb/standalone/tests/unit/__init__.py +0 -18
  336. nucliadb/standalone/tests/unit/test_api_router.py +0 -61
  337. nucliadb/standalone/tests/unit/test_auth.py +0 -169
  338. nucliadb/standalone/tests/unit/test_introspect.py +0 -35
  339. nucliadb/standalone/tests/unit/test_versions.py +0 -68
  340. nucliadb/tests/benchmarks/__init__.py +0 -19
  341. nucliadb/tests/benchmarks/test_search.py +0 -99
  342. nucliadb/tests/conftest.py +0 -32
  343. nucliadb/tests/fixtures.py +0 -736
  344. nucliadb/tests/knowledgeboxes/philosophy_books.py +0 -203
  345. nucliadb/tests/knowledgeboxes/ten_dummy_resources.py +0 -109
  346. nucliadb/tests/migrations/__init__.py +0 -19
  347. nucliadb/tests/migrations/test_migration_0017.py +0 -80
  348. nucliadb/tests/tikv.py +0 -240
  349. nucliadb/tests/unit/__init__.py +0 -19
  350. nucliadb/tests/unit/common/__init__.py +0 -19
  351. nucliadb/tests/unit/common/cluster/__init__.py +0 -19
  352. nucliadb/tests/unit/common/cluster/discovery/__init__.py +0 -19
  353. nucliadb/tests/unit/common/cluster/discovery/test_k8s.py +0 -170
  354. nucliadb/tests/unit/common/cluster/standalone/__init__.py +0 -18
  355. nucliadb/tests/unit/common/cluster/standalone/test_service.py +0 -113
  356. nucliadb/tests/unit/common/cluster/standalone/test_utils.py +0 -59
  357. nucliadb/tests/unit/common/cluster/test_cluster.py +0 -399
  358. nucliadb/tests/unit/common/cluster/test_kb_shard_manager.py +0 -178
  359. nucliadb/tests/unit/common/cluster/test_rollover.py +0 -279
  360. nucliadb/tests/unit/common/maindb/__init__.py +0 -18
  361. nucliadb/tests/unit/common/maindb/test_driver.py +0 -127
  362. nucliadb/tests/unit/common/maindb/test_tikv.py +0 -53
  363. nucliadb/tests/unit/common/maindb/test_utils.py +0 -81
  364. nucliadb/tests/unit/common/test_context.py +0 -36
  365. nucliadb/tests/unit/export_import/__init__.py +0 -19
  366. nucliadb/tests/unit/export_import/test_datamanager.py +0 -37
  367. nucliadb/tests/unit/export_import/test_utils.py +0 -294
  368. nucliadb/tests/unit/migrator/__init__.py +0 -19
  369. nucliadb/tests/unit/migrator/test_migrator.py +0 -87
  370. nucliadb/tests/unit/tasks/__init__.py +0 -19
  371. nucliadb/tests/unit/tasks/conftest.py +0 -42
  372. nucliadb/tests/unit/tasks/test_consumer.py +0 -93
  373. nucliadb/tests/unit/tasks/test_producer.py +0 -95
  374. nucliadb/tests/unit/tasks/test_tasks.py +0 -60
  375. nucliadb/tests/unit/test_field_ids.py +0 -49
  376. nucliadb/tests/unit/test_health.py +0 -84
  377. nucliadb/tests/unit/test_kb_slugs.py +0 -54
  378. nucliadb/tests/unit/test_learning_proxy.py +0 -252
  379. nucliadb/tests/unit/test_metrics_exporter.py +0 -77
  380. nucliadb/tests/unit/test_purge.py +0 -138
  381. nucliadb/tests/utils/__init__.py +0 -74
  382. nucliadb/tests/utils/aiohttp_session.py +0 -44
  383. nucliadb/tests/utils/broker_messages/__init__.py +0 -167
  384. nucliadb/tests/utils/broker_messages/fields.py +0 -181
  385. nucliadb/tests/utils/broker_messages/helpers.py +0 -33
  386. nucliadb/tests/utils/entities.py +0 -78
  387. nucliadb/train/api/v1/check.py +0 -60
  388. nucliadb/train/tests/__init__.py +0 -19
  389. nucliadb/train/tests/conftest.py +0 -29
  390. nucliadb/train/tests/fixtures.py +0 -342
  391. nucliadb/train/tests/test_field_classification.py +0 -122
  392. nucliadb/train/tests/test_get_entities.py +0 -80
  393. nucliadb/train/tests/test_get_info.py +0 -51
  394. nucliadb/train/tests/test_get_ontology.py +0 -34
  395. nucliadb/train/tests/test_get_ontology_count.py +0 -63
  396. nucliadb/train/tests/test_image_classification.py +0 -222
  397. nucliadb/train/tests/test_list_fields.py +0 -39
  398. nucliadb/train/tests/test_list_paragraphs.py +0 -73
  399. nucliadb/train/tests/test_list_resources.py +0 -39
  400. nucliadb/train/tests/test_list_sentences.py +0 -71
  401. nucliadb/train/tests/test_paragraph_classification.py +0 -123
  402. nucliadb/train/tests/test_paragraph_streaming.py +0 -118
  403. nucliadb/train/tests/test_question_answer_streaming.py +0 -239
  404. nucliadb/train/tests/test_sentence_classification.py +0 -143
  405. nucliadb/train/tests/test_token_classification.py +0 -136
  406. nucliadb/train/tests/utils.py +0 -108
  407. nucliadb/writer/layouts/__init__.py +0 -51
  408. nucliadb/writer/layouts/v1.py +0 -59
  409. nucliadb/writer/resource/vectors.py +0 -120
  410. nucliadb/writer/tests/__init__.py +0 -19
  411. nucliadb/writer/tests/conftest.py +0 -31
  412. nucliadb/writer/tests/fixtures.py +0 -192
  413. nucliadb/writer/tests/test_fields.py +0 -486
  414. nucliadb/writer/tests/test_files.py +0 -743
  415. nucliadb/writer/tests/test_knowledgebox.py +0 -49
  416. nucliadb/writer/tests/test_reprocess_file_field.py +0 -139
  417. nucliadb/writer/tests/test_resources.py +0 -546
  418. nucliadb/writer/tests/test_service.py +0 -137
  419. nucliadb/writer/tests/test_tus.py +0 -203
  420. nucliadb/writer/tests/utils.py +0 -35
  421. nucliadb/writer/tus/pg.py +0 -125
  422. nucliadb-2.46.1.post382.dist-info/METADATA +0 -134
  423. nucliadb-2.46.1.post382.dist-info/RECORD +0 -451
  424. {nucliadb/ingest/tests → migrations/pg}/__init__.py +0 -0
  425. /nucliadb/{ingest/tests/integration → common/external_index_providers}/__init__.py +0 -0
  426. /nucliadb/{ingest/tests/integration/ingest → common/models_utils}/__init__.py +0 -0
  427. /nucliadb/{ingest/tests/unit → search/search/query_parser}/__init__.py +0 -0
  428. /nucliadb/{ingest/tests → tests}/vectors.py +0 -0
  429. {nucliadb-2.46.1.post382.dist-info → nucliadb-6.2.1.post2777.dist-info}/entry_points.txt +0 -0
  430. {nucliadb-2.46.1.post382.dist-info → nucliadb-6.2.1.post2777.dist-info}/top_level.txt +0 -0
  431. {nucliadb-2.46.1.post382.dist-info → nucliadb-6.2.1.post2777.dist-info}/zip-safe +0 -0
@@ -1,294 +0,0 @@
1
- # Copyright (C) 2021 Bosutech XXI S.L.
2
- #
3
- # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
- # For commercial licensing, contact us at info@nuclia.com.
5
- #
6
- # AGPL:
7
- # This program is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU Affero General Public License as
9
- # published by the Free Software Foundation, either version 3 of the
10
- # License, or (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU Affero General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Affero General Public License
18
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- #
20
- from io import BytesIO
21
- from unittest.mock import AsyncMock, Mock
22
-
23
- import nats.errors
24
- import pytest
25
- from nucliadb_protos.writer_pb2 import BrokerMessage, BrokerMessageBlobReference
26
- from starlette.requests import Request
27
-
28
- from nucliadb.export_import.exceptions import ExportStreamExhausted
29
- from nucliadb.export_import.importer import ExportStream
30
- from nucliadb.export_import.models import ImportMetadata
31
- from nucliadb.export_import.utils import (
32
- IteratorExportStream,
33
- TaskRetryHandler,
34
- get_cloud_files,
35
- import_broker_message,
36
- transaction_commit,
37
- )
38
- from nucliadb_models.export_import import Status
39
- from nucliadb_protos import resources_pb2
40
- from nucliadb_utils.const import Streams
41
-
42
-
43
- @pytest.fixture(scope="function")
44
- def transaction():
45
- mock = Mock()
46
- mock.commit = AsyncMock()
47
- yield mock
48
-
49
-
50
- @pytest.fixture(scope="function")
51
- def partitioning():
52
- mock = Mock()
53
- mock.generate_partition = Mock(return_value=1)
54
- yield mock
55
-
56
-
57
- def get_cf(uri=None) -> resources_pb2.CloudFile:
58
- cf = resources_pb2.CloudFile()
59
- uri = uri or "//foo/bar"
60
- cf.uri = uri
61
- cf.source = resources_pb2.CloudFile.Source.LOCAL
62
- return cf
63
-
64
-
65
- @pytest.fixture(scope="function")
66
- def broker_message():
67
- bm = BrokerMessage()
68
- bm.kbid = "foobar"
69
-
70
- # Add a file field
71
- file = resources_pb2.FieldFile()
72
- file.file.CopyFrom(get_cf("file"))
73
- bm.files["file"].CopyFrom(file)
74
-
75
- # Add a conversation with an attachment
76
- conversation = resources_pb2.Conversation()
77
- message = resources_pb2.Message()
78
- attachment = get_cf("attachment")
79
- message.content.attachments.append(attachment)
80
- conversation.messages.append(message)
81
- bm.conversations["conversation"].CopyFrom(conversation)
82
-
83
- # Add a layout with a file
84
- layout = resources_pb2.FieldLayout()
85
- block = resources_pb2.Block()
86
- block.file.CopyFrom(get_cf("layout"))
87
- layout.body.blocks["foo"].CopyFrom(block)
88
- bm.layouts["layout"].CopyFrom(layout)
89
-
90
- # Field extracted data
91
- fed = resources_pb2.FileExtractedData()
92
- fed.file_generated["foo"].CopyFrom(get_cf("field_file_generated"))
93
- fed.file_preview.CopyFrom(get_cf("field_file_preview"))
94
- fed.file_thumbnail.CopyFrom(get_cf("field_file_thumbnail"))
95
- fed.file_pages_previews.pages.append(get_cf("field_file_pages_previews"))
96
- bm.file_extracted_data.append(fed)
97
-
98
- # Link extracted data
99
- led = resources_pb2.LinkExtractedData()
100
- led.link_thumbnail.CopyFrom(get_cf("link_thumbnail"))
101
- led.link_preview.CopyFrom(get_cf("link_preview"))
102
- led.link_image.CopyFrom(get_cf("link_image"))
103
- bm.link_extracted_data.append(led)
104
-
105
- # Field metadata
106
- fcmw = resources_pb2.FieldComputedMetadataWrapper()
107
- fcmw.metadata.metadata.thumbnail.CopyFrom(get_cf("metadata_thumbnail"))
108
- fcmw.metadata.split_metadata["foo"].thumbnail.CopyFrom(
109
- get_cf("metadata_split_thumbnail")
110
- )
111
- bm.field_metadata.append(fcmw)
112
-
113
- return bm
114
-
115
-
116
- class ContextMock:
117
- def __init__(self, transaction, partitioning):
118
- self.transaction = transaction
119
- self.partitioning = partitioning
120
-
121
-
122
- async def test_import_broker_message(broker_message, transaction, partitioning):
123
- context = ContextMock(transaction, partitioning)
124
-
125
- import_kbid = "import_kbid"
126
- assert broker_message.kbid != import_kbid
127
-
128
- await import_broker_message(context, import_kbid, broker_message)
129
-
130
- # Sends two messages
131
- assert transaction.commit.call_count == 2
132
-
133
- for call in transaction.commit.call_args_list:
134
- # Message contains import kbid
135
- assert call[0][0].kbid == import_kbid
136
-
137
- # Sends to correct topic
138
- assert call[1]["target_subject"] == Streams.INGEST_PROCESSED.subject
139
-
140
-
141
- def test_get_cloud_files(broker_message):
142
- # All expected binaries are returned
143
- binaries = get_cloud_files(broker_message)
144
- assert len(binaries) == 12
145
- for cf in binaries:
146
- assert cf.source == resources_pb2.CloudFile.Source.LOCAL
147
-
148
- # Make sure that the source is set to export on the broker message cfs
149
- for cf in get_cloud_files(broker_message):
150
- assert cf.source == resources_pb2.CloudFile.Source.EXPORT
151
-
152
-
153
- async def test_export_stream():
154
- export = BytesIO(b"1234567890")
155
- stream = ExportStream(export)
156
- assert stream.read_bytes == 0
157
- assert await stream.read(0) == b""
158
- assert stream.read_bytes == 0
159
- assert await stream.read(1) == b"1"
160
- assert stream.read_bytes == 1
161
- assert await stream.read(2) == b"23"
162
- assert stream.read_bytes == 3
163
- assert await stream.read(50) == b"4567890"
164
- assert stream.read_bytes == 10
165
- with pytest.raises(ExportStreamExhausted):
166
- await stream.read(1)
167
-
168
-
169
- class DummyTestRequest(Request):
170
- def __init__(self, data: bytes, receive_chunk_size: int = 10):
171
- super().__init__(
172
- scope={
173
- "type": "http",
174
- "http_version": "1.1",
175
- "method": "GET",
176
- "headers": [],
177
- },
178
- receive=self.receive,
179
- )
180
- self.receive_chunk_size = receive_chunk_size
181
- self.bytes = BytesIO(data)
182
-
183
- async def receive(self):
184
- chunk = self.bytes.read(self.receive_chunk_size)
185
- more_data = True
186
- if chunk == b"":
187
- more_data = False
188
- return {"type": "http.request", "body": chunk, "more_body": more_data}
189
-
190
-
191
- async def test_iterator_export_stream():
192
- request = DummyTestRequest(data=b"01234XYZ", receive_chunk_size=2)
193
-
194
- iterator = request.stream().__aiter__()
195
- export_stream = IteratorExportStream(iterator)
196
- assert await export_stream.read(0) == b""
197
- assert export_stream.read_bytes == 0
198
-
199
- for i in range(5):
200
- assert await export_stream.read(1) == f"{i}".encode()
201
- assert export_stream.read_bytes == 5
202
-
203
- assert await export_stream.read(3) == b"XYZ"
204
- assert export_stream.read_bytes == 8
205
-
206
- with pytest.raises(ExportStreamExhausted):
207
- await export_stream.read(1)
208
-
209
- with pytest.raises(ExportStreamExhausted):
210
- await export_stream.read(0)
211
-
212
- request = DummyTestRequest(data=b"foobar", receive_chunk_size=2)
213
- iterator = request.stream().__aiter__()
214
- export_stream = IteratorExportStream(iterator)
215
- assert await export_stream.read(50) == b"foobar"
216
- assert export_stream.read_bytes == 6
217
-
218
- with pytest.raises(ExportStreamExhausted):
219
- await export_stream.read(0)
220
-
221
-
222
- class TestTaskRetryHandler:
223
- @pytest.fixture(scope="function")
224
- def callback(self):
225
- return AsyncMock()
226
-
227
- @pytest.fixture(scope="function")
228
- def dm(self):
229
- dm = Mock()
230
- dm.set_metadata = AsyncMock()
231
- return dm
232
-
233
- @pytest.fixture(scope="function")
234
- def metadata(self):
235
- return ImportMetadata(kbid="kbid", id="import_id")
236
-
237
- async def test_ok(self, callback, dm, metadata):
238
- callback.return_value = 100
239
- trh = TaskRetryHandler("foo", dm, metadata)
240
- callback_retried = trh.wrap(callback)
241
-
242
- result = await callback_retried("foo", bar="baz")
243
- assert result == 100
244
-
245
- callback.assert_called_once_with("foo", bar="baz")
246
-
247
- assert metadata.task.status == Status.FINISHED
248
-
249
- async def test_errors_are_retried(self, callback, dm, metadata):
250
- callback.side_effect = ValueError("foo")
251
-
252
- trh = TaskRetryHandler("foo", dm, metadata, max_tries=2)
253
- callback_retried = trh.wrap(callback)
254
-
255
- with pytest.raises(ValueError):
256
- await callback_retried("foo", bar="baz")
257
-
258
- callback.assert_called_once_with("foo", bar="baz")
259
-
260
- assert metadata.task.status == Status.RUNNING
261
- assert metadata.task.retries == 1
262
-
263
- with pytest.raises(ValueError):
264
- await callback_retried("foo", bar="baz")
265
-
266
- assert metadata.task.status == Status.RUNNING
267
- assert metadata.task.retries == 2
268
-
269
- async def test_ignored_statuses(self, callback, dm, metadata):
270
- trh = TaskRetryHandler("foo", dm, metadata)
271
- callback_retried = trh.wrap(callback)
272
-
273
- for status in (Status.ERRORED, Status.FINISHED):
274
- metadata.task.status = status
275
- await callback_retried("foo", bar="baz")
276
- callback.assert_not_called()
277
-
278
-
279
- async def test_transaction_commit_sends_storage_reference_on_max_payload_error():
280
- context = Mock()
281
- context.transaction.commit = AsyncMock(
282
- side_effect=[nats.errors.MaxPayloadError, None]
283
- )
284
- context.blob_storage = AsyncMock()
285
- context.blob_storage.set_stream_message.return_value = "key"
286
-
287
- bm = BrokerMessage(kbid="kbid", uuid="uuid")
288
-
289
- await transaction_commit(context, bm, 1)
290
-
291
- assert context.transaction.commit.call_count == 2
292
- call = context.transaction.commit.call_args_list[-1]
293
- assert isinstance(call[1]["writer"], BrokerMessageBlobReference)
294
- assert call[1]["headers"] == {"X-MESSAGE-TYPE": "PROXY"}
@@ -1,19 +0,0 @@
1
- # Copyright (C) 2021 Bosutech XXI S.L.
2
- #
3
- # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
- # For commercial licensing, contact us at info@nuclia.com.
5
- #
6
- # AGPL:
7
- # This program is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU Affero General Public License as
9
- # published by the Free Software Foundation, either version 3 of the
10
- # License, or (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU Affero General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Affero General Public License
18
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- #
@@ -1,87 +0,0 @@
1
- # Copyright (C) 2021 Bosutech XXI S.L.
2
- #
3
- # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
- # For commercial licensing, contact us at info@nuclia.com.
5
- #
6
- # AGPL:
7
- # This program is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU Affero General Public License as
9
- # published by the Free Software Foundation, either version 3 of the
10
- # License, or (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU Affero General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Affero General Public License
18
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- #
20
- import types
21
- from unittest.mock import AsyncMock, Mock, patch
22
-
23
- import pytest
24
-
25
- from nucliadb.migrator import command, migrator
26
- from nucliadb.migrator.exceptions import MigrationValidationError
27
- from nucliadb.migrator.models import Migration
28
-
29
-
30
- def test_get_migrations():
31
- migrations = migrator.get_migrations()
32
- assert len(migrations) > 0
33
- assert migrations[0].version == 1
34
- assert migrations[0].module.__name__ == "migrations.0001_bootstrap"
35
-
36
-
37
- def test_get_migration_with_filtering():
38
- with patch("nucliadb.migrator.utils.get_migration_modules") as mock:
39
- mock.return_value = [
40
- (types.ModuleType("m1"), 1),
41
- (types.ModuleType("m2"), 2),
42
- (types.ModuleType("m3"), 3),
43
- (types.ModuleType("m4"), 4),
44
- ]
45
- migrations = migrator.get_migrations(from_version=2, to_version=3)
46
- assert len(migrations) == 1
47
- assert migrations[0].version == 3
48
- assert migrations[0].module.__name__ == "m3"
49
-
50
-
51
- async def test_run_all_kb_migrations_raises_on_failure():
52
- execution_context = Mock()
53
- execution_context.data_manager = Mock()
54
- execution_context.data_manager.get_kb_migrations = AsyncMock(
55
- return_value=["foo", "bar"]
56
- )
57
- execution_context.settings = Mock(max_concurrent_migrations=1)
58
- with patch(
59
- "nucliadb.migrator.migrator.run_kb_migrations",
60
- side_effect=[None, Exception("Boom")],
61
- ) as mock:
62
- with pytest.raises(Exception) as exc_info:
63
- await migrator.run_all_kb_migrations(execution_context, 1)
64
- assert "Failed to migrate KBs. Failures: 1" in str(exc_info.value)
65
- assert mock.call_count == 2
66
-
67
-
68
- async def test_migrations_validation():
69
- migrations = [
70
- Migration(version=1, module=Mock()),
71
- Migration(version=2, module=Mock()),
72
- Migration(version=3, module=Mock()),
73
- ]
74
- with patch("nucliadb.migrator.command.get_migrations", return_value=migrations):
75
- command.validate()
76
-
77
-
78
- async def test_migrations_validation_with_errors():
79
- migrations = [
80
- Migration(version=1, module=Mock()),
81
- Migration(version=2, module=Mock()),
82
- Migration(version=2, module=Mock()),
83
- Migration(version=3, module=Mock()),
84
- ]
85
- with patch("nucliadb.migrator.command.get_migrations", return_value=migrations):
86
- with pytest.raises(MigrationValidationError):
87
- command.validate()
@@ -1,19 +0,0 @@
1
- # Copyright (C) 2021 Bosutech XXI S.L.
2
- #
3
- # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
- # For commercial licensing, contact us at info@nuclia.com.
5
- #
6
- # AGPL:
7
- # This program is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU Affero General Public License as
9
- # published by the Free Software Foundation, either version 3 of the
10
- # License, or (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU Affero General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Affero General Public License
18
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- #
@@ -1,42 +0,0 @@
1
- # Copyright (C) 2021 Bosutech XXI S.L.
2
- #
3
- # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
- # For commercial licensing, contact us at info@nuclia.com.
5
- #
6
- # AGPL:
7
- # This program is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU Affero General Public License as
9
- # published by the Free Software Foundation, either version 3 of the
10
- # License, or (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU Affero General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Affero General Public License
18
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- #
20
- from unittest.mock import AsyncMock, Mock
21
-
22
- import nats
23
- import pytest
24
-
25
-
26
- @pytest.fixture(scope="function")
27
- def nats_manager():
28
- nats_manager = Mock()
29
- nats_manager.subscribe = AsyncMock()
30
- js = Mock()
31
- js.stream_info = AsyncMock(side_effect=nats.js.errors.NotFoundError)
32
- js.add_stream = AsyncMock()
33
- nats_manager.js = js
34
- yield nats_manager
35
-
36
-
37
- @pytest.fixture(scope="function")
38
- def context(nats_manager):
39
- context = Mock()
40
- context.initialize = AsyncMock()
41
- context.nats_manager = nats_manager
42
- yield context
@@ -1,93 +0,0 @@
1
- # Copyright (C) 2021 Bosutech XXI S.L.
2
- #
3
- # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
- # For commercial licensing, contact us at info@nuclia.com.
5
- #
6
- # AGPL:
7
- # This program is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU Affero General Public License as
9
- # published by the Free Software Foundation, either version 3 of the
10
- # License, or (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU Affero General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Affero General Public License
18
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- #
20
- from unittest.mock import AsyncMock, MagicMock
21
-
22
- import pydantic
23
- import pytest
24
-
25
- from nucliadb.tasks.consumer import create_consumer
26
-
27
-
28
- class Message(pydantic.BaseModel):
29
- kbid: str
30
-
31
-
32
- def test_create_consumer():
33
- stream = MagicMock()
34
-
35
- async def callback():
36
- ...
37
-
38
- consumer = create_consumer(
39
- "foo", stream=stream, msg_type=Message, callback=callback
40
- )
41
- assert not consumer.initialized
42
-
43
- assert consumer.name == "foo"
44
- assert consumer.stream == stream
45
- assert consumer.callback == callback
46
- assert consumer.msg_type == Message
47
-
48
-
49
- class TestSubscriptionWorker:
50
- @pytest.fixture(scope="function")
51
- async def callback(self):
52
- yield AsyncMock()
53
-
54
- @pytest.fixture(scope="function")
55
- async def consumer(self, context, callback):
56
- consumer = create_consumer(
57
- "foo", stream=MagicMock(), callback=callback, msg_type=Message
58
- )
59
- await consumer.initialize(context)
60
- yield consumer
61
-
62
- @pytest.fixture(scope="function")
63
- def task_message(self):
64
- yield Message(kbid="kbid")
65
-
66
- @pytest.fixture(scope="function")
67
- def msg(self, task_message):
68
- data = task_message.json().encode("utf-8")
69
- msg = MagicMock()
70
- msg.data = data
71
- msg.ack = AsyncMock()
72
- msg.nak = AsyncMock()
73
- yield msg
74
-
75
- async def test_callback_ok(self, consumer, msg, callback):
76
- await consumer.subscription_worker(msg)
77
-
78
- callback.assert_called_once()
79
-
80
- async def test_callback_error(self, consumer, msg, callback):
81
- callback.side_effect = Exception("foo")
82
-
83
- await consumer.subscription_worker(msg)
84
-
85
- callback.assert_called_once()
86
- msg.nak.assert_called_once()
87
-
88
- async def test_validation_error(self, consumer, msg):
89
- msg.data = b"foo"
90
-
91
- await consumer.subscription_worker(msg)
92
-
93
- msg.ack.assert_called_once()
@@ -1,95 +0,0 @@
1
- # Copyright (C) 2021 Bosutech XXI S.L.
2
- #
3
- # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
- # For commercial licensing, contact us at info@nuclia.com.
5
- #
6
- # AGPL:
7
- # This program is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU Affero General Public License as
9
- # published by the Free Software Foundation, either version 3 of the
10
- # License, or (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU Affero General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Affero General Public License
18
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- #
20
- from unittest.mock import AsyncMock, MagicMock, Mock
21
-
22
- import nats
23
- import pydantic
24
- import pytest
25
-
26
- from nucliadb.tasks.producer import create_producer
27
-
28
-
29
- class Message(pydantic.BaseModel):
30
- kbid: str
31
-
32
-
33
- def test_create_producer():
34
- stream = MagicMock()
35
-
36
- producer = create_producer("foo", stream=stream, msg_type=Message)
37
- assert not producer.initialized
38
-
39
- assert producer.name == "foo"
40
- assert producer.stream == stream
41
-
42
-
43
- class TestProducer:
44
- @pytest.fixture(scope="function")
45
- def stream(self):
46
- return MagicMock()
47
-
48
- @pytest.fixture(scope="function")
49
- def nats_manager(self):
50
- mgr = MagicMock()
51
- mgr.js.stream_info = AsyncMock(side_effect=nats.js.errors.NotFoundError)
52
- mgr.js.add_stream = AsyncMock()
53
- mgr.js.publish = AsyncMock()
54
- yield mgr
55
-
56
- @pytest.fixture(scope="function")
57
- async def producer(self, context, stream, nats_manager):
58
- async def callback(context, msg: Message):
59
- pass
60
-
61
- producer = create_producer("foo", stream=stream, msg_type=Message)
62
- await producer.initialize(context)
63
- producer.context.nats_manager = nats_manager
64
- yield producer
65
-
66
- async def test_initialize_creates_stream(self, producer, nats_manager):
67
- # Check that the stream is on inialization
68
- assert nats_manager.js.add_stream.call_count == 1
69
- assert nats_manager.js.add_stream.call_args[1]["name"] == producer.stream.name
70
- assert nats_manager.js.add_stream.call_args[1]["subjects"] == [
71
- producer.stream.subject
72
- ]
73
-
74
- async def test_produce_raises_error_if_not_initialized(self, producer):
75
- producer.initialized = False
76
- with pytest.raises(RuntimeError):
77
- await producer(Mock())
78
-
79
- async def test_produce_ok(self, producer, stream):
80
- msg = Message(kbid="kbid")
81
-
82
- await producer(msg)
83
-
84
- publish_args = producer.context.nats_manager.js.publish.call_args[0]
85
- assert publish_args[0] == stream.subject
86
-
87
- raw_message = publish_args[1]
88
- sent_message = Message.parse_raw(raw_message)
89
- assert sent_message == msg
90
-
91
- async def test_produce_raises_publish_errors(self, producer, nats_manager):
92
- nats_manager.js.publish.side_effect = ValueError("foo")
93
-
94
- with pytest.raises(ValueError):
95
- await producer(Mock())