nucliadb 4.0.0.post542__py3-none-any.whl → 6.2.1.post2798__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 (418) hide show
  1. migrations/0003_allfields_key.py +1 -35
  2. migrations/0009_upgrade_relations_and_texts_to_v2.py +4 -2
  3. migrations/0010_fix_corrupt_indexes.py +10 -10
  4. migrations/0011_materialize_labelset_ids.py +1 -16
  5. migrations/0012_rollover_shards.py +5 -10
  6. migrations/0014_rollover_shards.py +4 -5
  7. migrations/0015_targeted_rollover.py +5 -10
  8. migrations/0016_upgrade_to_paragraphs_v2.py +25 -28
  9. migrations/0017_multiple_writable_shards.py +2 -4
  10. migrations/0018_purge_orphan_kbslugs.py +5 -7
  11. migrations/0019_upgrade_to_paragraphs_v3.py +25 -28
  12. migrations/0020_drain_nodes_from_cluster.py +3 -3
  13. nucliadb/standalone/tests/unit/test_run.py → migrations/0021_overwrite_vectorsets_key.py +16 -19
  14. nucliadb/tests/unit/test_openapi.py → migrations/0022_fix_paragraph_deletion_bug.py +16 -11
  15. migrations/0023_backfill_pg_catalog.py +80 -0
  16. migrations/0025_assign_models_to_kbs_v2.py +113 -0
  17. migrations/0026_fix_high_cardinality_content_types.py +61 -0
  18. migrations/0027_rollover_texts3.py +73 -0
  19. nucliadb/ingest/fields/date.py → migrations/pg/0001_bootstrap.py +10 -12
  20. migrations/pg/0002_catalog.py +42 -0
  21. nucliadb/ingest/tests/unit/test_settings.py → migrations/pg/0003_catalog_kbid_index.py +5 -3
  22. nucliadb/common/cluster/base.py +30 -16
  23. nucliadb/common/cluster/discovery/base.py +6 -14
  24. nucliadb/common/cluster/discovery/k8s.py +9 -19
  25. nucliadb/common/cluster/discovery/manual.py +1 -3
  26. nucliadb/common/cluster/discovery/utils.py +1 -3
  27. nucliadb/common/cluster/grpc_node_dummy.py +3 -11
  28. nucliadb/common/cluster/index_node.py +10 -19
  29. nucliadb/common/cluster/manager.py +174 -59
  30. nucliadb/common/cluster/rebalance.py +27 -29
  31. nucliadb/common/cluster/rollover.py +353 -194
  32. nucliadb/common/cluster/settings.py +6 -0
  33. nucliadb/common/cluster/standalone/grpc_node_binding.py +13 -64
  34. nucliadb/common/cluster/standalone/index_node.py +4 -11
  35. nucliadb/common/cluster/standalone/service.py +2 -6
  36. nucliadb/common/cluster/standalone/utils.py +2 -6
  37. nucliadb/common/cluster/utils.py +29 -22
  38. nucliadb/common/constants.py +20 -0
  39. nucliadb/common/context/__init__.py +3 -0
  40. nucliadb/common/context/fastapi.py +8 -5
  41. nucliadb/{tests/knowledgeboxes/__init__.py → common/counters.py} +8 -2
  42. nucliadb/common/datamanagers/__init__.py +7 -1
  43. nucliadb/common/datamanagers/atomic.py +22 -4
  44. nucliadb/common/datamanagers/cluster.py +5 -5
  45. nucliadb/common/datamanagers/entities.py +6 -16
  46. nucliadb/common/datamanagers/fields.py +84 -0
  47. nucliadb/common/datamanagers/kb.py +83 -37
  48. nucliadb/common/datamanagers/labels.py +26 -56
  49. nucliadb/common/datamanagers/processing.py +2 -6
  50. nucliadb/common/datamanagers/resources.py +41 -103
  51. nucliadb/common/datamanagers/rollover.py +76 -15
  52. nucliadb/common/datamanagers/synonyms.py +1 -1
  53. nucliadb/common/datamanagers/utils.py +15 -6
  54. nucliadb/common/datamanagers/vectorsets.py +110 -0
  55. nucliadb/common/external_index_providers/base.py +257 -0
  56. nucliadb/{ingest/tests/unit/orm/test_orm_utils.py → common/external_index_providers/exceptions.py} +9 -8
  57. nucliadb/common/external_index_providers/manager.py +101 -0
  58. nucliadb/common/external_index_providers/pinecone.py +933 -0
  59. nucliadb/common/external_index_providers/settings.py +52 -0
  60. nucliadb/common/http_clients/auth.py +3 -6
  61. nucliadb/common/http_clients/processing.py +6 -11
  62. nucliadb/common/http_clients/utils.py +1 -3
  63. nucliadb/common/ids.py +240 -0
  64. nucliadb/common/locking.py +29 -7
  65. nucliadb/common/maindb/driver.py +11 -35
  66. nucliadb/common/maindb/exceptions.py +3 -0
  67. nucliadb/common/maindb/local.py +22 -9
  68. nucliadb/common/maindb/pg.py +206 -111
  69. nucliadb/common/maindb/utils.py +11 -42
  70. nucliadb/common/models_utils/from_proto.py +479 -0
  71. nucliadb/common/models_utils/to_proto.py +60 -0
  72. nucliadb/common/nidx.py +260 -0
  73. nucliadb/export_import/datamanager.py +25 -19
  74. nucliadb/export_import/exporter.py +5 -11
  75. nucliadb/export_import/importer.py +5 -7
  76. nucliadb/export_import/models.py +3 -3
  77. nucliadb/export_import/tasks.py +4 -4
  78. nucliadb/export_import/utils.py +25 -37
  79. nucliadb/health.py +1 -3
  80. nucliadb/ingest/app.py +15 -11
  81. nucliadb/ingest/consumer/auditing.py +21 -19
  82. nucliadb/ingest/consumer/consumer.py +82 -47
  83. nucliadb/ingest/consumer/materializer.py +5 -12
  84. nucliadb/ingest/consumer/pull.py +12 -27
  85. nucliadb/ingest/consumer/service.py +19 -17
  86. nucliadb/ingest/consumer/shard_creator.py +2 -4
  87. nucliadb/ingest/consumer/utils.py +1 -3
  88. nucliadb/ingest/fields/base.py +137 -105
  89. nucliadb/ingest/fields/conversation.py +18 -5
  90. nucliadb/ingest/fields/exceptions.py +1 -4
  91. nucliadb/ingest/fields/file.py +7 -16
  92. nucliadb/ingest/fields/link.py +5 -10
  93. nucliadb/ingest/fields/text.py +9 -4
  94. nucliadb/ingest/orm/brain.py +200 -213
  95. nucliadb/ingest/orm/broker_message.py +181 -0
  96. nucliadb/ingest/orm/entities.py +36 -51
  97. nucliadb/ingest/orm/exceptions.py +12 -0
  98. nucliadb/ingest/orm/knowledgebox.py +322 -197
  99. nucliadb/ingest/orm/processor/__init__.py +2 -700
  100. nucliadb/ingest/orm/processor/auditing.py +4 -23
  101. nucliadb/ingest/orm/processor/data_augmentation.py +164 -0
  102. nucliadb/ingest/orm/processor/pgcatalog.py +84 -0
  103. nucliadb/ingest/orm/processor/processor.py +752 -0
  104. nucliadb/ingest/orm/processor/sequence_manager.py +1 -1
  105. nucliadb/ingest/orm/resource.py +249 -403
  106. nucliadb/ingest/orm/utils.py +4 -4
  107. nucliadb/ingest/partitions.py +3 -9
  108. nucliadb/ingest/processing.py +70 -73
  109. nucliadb/ingest/py.typed +0 -0
  110. nucliadb/ingest/serialize.py +37 -167
  111. nucliadb/ingest/service/__init__.py +1 -3
  112. nucliadb/ingest/service/writer.py +185 -412
  113. nucliadb/ingest/settings.py +10 -20
  114. nucliadb/ingest/utils.py +3 -6
  115. nucliadb/learning_proxy.py +242 -55
  116. nucliadb/metrics_exporter.py +30 -19
  117. nucliadb/middleware/__init__.py +1 -3
  118. nucliadb/migrator/command.py +1 -3
  119. nucliadb/migrator/datamanager.py +13 -13
  120. nucliadb/migrator/migrator.py +47 -30
  121. nucliadb/migrator/utils.py +18 -10
  122. nucliadb/purge/__init__.py +139 -33
  123. nucliadb/purge/orphan_shards.py +7 -13
  124. nucliadb/reader/__init__.py +1 -3
  125. nucliadb/reader/api/models.py +1 -12
  126. nucliadb/reader/api/v1/__init__.py +0 -1
  127. nucliadb/reader/api/v1/download.py +21 -88
  128. nucliadb/reader/api/v1/export_import.py +1 -1
  129. nucliadb/reader/api/v1/knowledgebox.py +10 -10
  130. nucliadb/reader/api/v1/learning_config.py +2 -6
  131. nucliadb/reader/api/v1/resource.py +62 -88
  132. nucliadb/reader/api/v1/services.py +64 -83
  133. nucliadb/reader/app.py +12 -29
  134. nucliadb/reader/lifecycle.py +18 -4
  135. nucliadb/reader/py.typed +0 -0
  136. nucliadb/reader/reader/notifications.py +10 -28
  137. nucliadb/search/__init__.py +1 -3
  138. nucliadb/search/api/v1/__init__.py +1 -2
  139. nucliadb/search/api/v1/ask.py +17 -10
  140. nucliadb/search/api/v1/catalog.py +184 -0
  141. nucliadb/search/api/v1/feedback.py +16 -24
  142. nucliadb/search/api/v1/find.py +36 -36
  143. nucliadb/search/api/v1/knowledgebox.py +89 -60
  144. nucliadb/search/api/v1/resource/ask.py +2 -8
  145. nucliadb/search/api/v1/resource/search.py +49 -70
  146. nucliadb/search/api/v1/search.py +44 -210
  147. nucliadb/search/api/v1/suggest.py +39 -54
  148. nucliadb/search/app.py +12 -32
  149. nucliadb/search/lifecycle.py +10 -3
  150. nucliadb/search/predict.py +136 -187
  151. nucliadb/search/py.typed +0 -0
  152. nucliadb/search/requesters/utils.py +25 -58
  153. nucliadb/search/search/cache.py +149 -20
  154. nucliadb/search/search/chat/ask.py +571 -123
  155. nucliadb/search/{tests/unit/test_run.py → search/chat/exceptions.py} +14 -14
  156. nucliadb/search/search/chat/images.py +41 -17
  157. nucliadb/search/search/chat/prompt.py +817 -266
  158. nucliadb/search/search/chat/query.py +213 -309
  159. nucliadb/{tests/migrations/__init__.py → search/search/cut.py} +8 -8
  160. nucliadb/search/search/fetch.py +43 -36
  161. nucliadb/search/search/filters.py +9 -15
  162. nucliadb/search/search/find.py +214 -53
  163. nucliadb/search/search/find_merge.py +408 -391
  164. nucliadb/search/search/hydrator.py +191 -0
  165. nucliadb/search/search/merge.py +187 -223
  166. nucliadb/search/search/metrics.py +73 -2
  167. nucliadb/search/search/paragraphs.py +64 -106
  168. nucliadb/search/search/pgcatalog.py +233 -0
  169. nucliadb/search/search/predict_proxy.py +1 -1
  170. nucliadb/search/search/query.py +305 -150
  171. nucliadb/search/search/query_parser/exceptions.py +22 -0
  172. nucliadb/search/search/query_parser/models.py +101 -0
  173. nucliadb/search/search/query_parser/parser.py +183 -0
  174. nucliadb/search/search/rank_fusion.py +204 -0
  175. nucliadb/search/search/rerankers.py +270 -0
  176. nucliadb/search/search/shards.py +3 -32
  177. nucliadb/search/search/summarize.py +7 -18
  178. nucliadb/search/search/utils.py +27 -4
  179. nucliadb/search/settings.py +15 -1
  180. nucliadb/standalone/api_router.py +4 -10
  181. nucliadb/standalone/app.py +8 -14
  182. nucliadb/standalone/auth.py +7 -21
  183. nucliadb/standalone/config.py +7 -10
  184. nucliadb/standalone/lifecycle.py +26 -25
  185. nucliadb/standalone/migrations.py +1 -3
  186. nucliadb/standalone/purge.py +1 -1
  187. nucliadb/standalone/py.typed +0 -0
  188. nucliadb/standalone/run.py +3 -6
  189. nucliadb/standalone/settings.py +9 -16
  190. nucliadb/standalone/versions.py +15 -5
  191. nucliadb/tasks/consumer.py +8 -12
  192. nucliadb/tasks/producer.py +7 -6
  193. nucliadb/tests/config.py +53 -0
  194. nucliadb/train/__init__.py +1 -3
  195. nucliadb/train/api/utils.py +1 -2
  196. nucliadb/train/api/v1/shards.py +1 -1
  197. nucliadb/train/api/v1/trainset.py +2 -4
  198. nucliadb/train/app.py +10 -31
  199. nucliadb/train/generator.py +10 -19
  200. nucliadb/train/generators/field_classifier.py +7 -19
  201. nucliadb/train/generators/field_streaming.py +156 -0
  202. nucliadb/train/generators/image_classifier.py +12 -18
  203. nucliadb/train/generators/paragraph_classifier.py +5 -9
  204. nucliadb/train/generators/paragraph_streaming.py +6 -9
  205. nucliadb/train/generators/question_answer_streaming.py +19 -20
  206. nucliadb/train/generators/sentence_classifier.py +9 -15
  207. nucliadb/train/generators/token_classifier.py +48 -39
  208. nucliadb/train/generators/utils.py +14 -18
  209. nucliadb/train/lifecycle.py +7 -3
  210. nucliadb/train/nodes.py +23 -32
  211. nucliadb/train/py.typed +0 -0
  212. nucliadb/train/servicer.py +13 -21
  213. nucliadb/train/settings.py +2 -6
  214. nucliadb/train/types.py +13 -10
  215. nucliadb/train/upload.py +3 -6
  216. nucliadb/train/uploader.py +19 -23
  217. nucliadb/train/utils.py +1 -1
  218. nucliadb/writer/__init__.py +1 -3
  219. nucliadb/{ingest/fields/keywordset.py → writer/api/utils.py} +13 -10
  220. nucliadb/writer/api/v1/export_import.py +67 -14
  221. nucliadb/writer/api/v1/field.py +16 -269
  222. nucliadb/writer/api/v1/knowledgebox.py +218 -68
  223. nucliadb/writer/api/v1/resource.py +68 -88
  224. nucliadb/writer/api/v1/services.py +51 -70
  225. nucliadb/writer/api/v1/slug.py +61 -0
  226. nucliadb/writer/api/v1/transaction.py +67 -0
  227. nucliadb/writer/api/v1/upload.py +143 -117
  228. nucliadb/writer/app.py +6 -43
  229. nucliadb/writer/back_pressure.py +16 -38
  230. nucliadb/writer/exceptions.py +0 -4
  231. nucliadb/writer/lifecycle.py +21 -15
  232. nucliadb/writer/py.typed +0 -0
  233. nucliadb/writer/resource/audit.py +2 -1
  234. nucliadb/writer/resource/basic.py +48 -46
  235. nucliadb/writer/resource/field.py +37 -128
  236. nucliadb/writer/resource/origin.py +1 -2
  237. nucliadb/writer/settings.py +6 -2
  238. nucliadb/writer/tus/__init__.py +17 -15
  239. nucliadb/writer/tus/azure.py +111 -0
  240. nucliadb/writer/tus/dm.py +17 -5
  241. nucliadb/writer/tus/exceptions.py +1 -3
  242. nucliadb/writer/tus/gcs.py +49 -84
  243. nucliadb/writer/tus/local.py +21 -37
  244. nucliadb/writer/tus/s3.py +28 -68
  245. nucliadb/writer/tus/storage.py +5 -56
  246. nucliadb/writer/vectorsets.py +125 -0
  247. nucliadb-6.2.1.post2798.dist-info/METADATA +148 -0
  248. nucliadb-6.2.1.post2798.dist-info/RECORD +343 -0
  249. {nucliadb-4.0.0.post542.dist-info → nucliadb-6.2.1.post2798.dist-info}/WHEEL +1 -1
  250. nucliadb/common/maindb/redis.py +0 -194
  251. nucliadb/common/maindb/tikv.py +0 -433
  252. nucliadb/ingest/fields/layout.py +0 -58
  253. nucliadb/ingest/tests/conftest.py +0 -30
  254. nucliadb/ingest/tests/fixtures.py +0 -764
  255. nucliadb/ingest/tests/integration/consumer/__init__.py +0 -18
  256. nucliadb/ingest/tests/integration/consumer/test_auditing.py +0 -78
  257. nucliadb/ingest/tests/integration/consumer/test_materializer.py +0 -126
  258. nucliadb/ingest/tests/integration/consumer/test_pull.py +0 -144
  259. nucliadb/ingest/tests/integration/consumer/test_service.py +0 -81
  260. nucliadb/ingest/tests/integration/consumer/test_shard_creator.py +0 -68
  261. nucliadb/ingest/tests/integration/ingest/test_ingest.py +0 -684
  262. nucliadb/ingest/tests/integration/ingest/test_processing_engine.py +0 -95
  263. nucliadb/ingest/tests/integration/ingest/test_relations.py +0 -272
  264. nucliadb/ingest/tests/unit/consumer/__init__.py +0 -18
  265. nucliadb/ingest/tests/unit/consumer/test_auditing.py +0 -139
  266. nucliadb/ingest/tests/unit/consumer/test_consumer.py +0 -69
  267. nucliadb/ingest/tests/unit/consumer/test_pull.py +0 -60
  268. nucliadb/ingest/tests/unit/consumer/test_shard_creator.py +0 -140
  269. nucliadb/ingest/tests/unit/consumer/test_utils.py +0 -67
  270. nucliadb/ingest/tests/unit/orm/__init__.py +0 -19
  271. nucliadb/ingest/tests/unit/orm/test_brain.py +0 -247
  272. nucliadb/ingest/tests/unit/orm/test_brain_vectors.py +0 -74
  273. nucliadb/ingest/tests/unit/orm/test_processor.py +0 -131
  274. nucliadb/ingest/tests/unit/orm/test_resource.py +0 -331
  275. nucliadb/ingest/tests/unit/test_cache.py +0 -31
  276. nucliadb/ingest/tests/unit/test_partitions.py +0 -40
  277. nucliadb/ingest/tests/unit/test_processing.py +0 -171
  278. nucliadb/middleware/transaction.py +0 -117
  279. nucliadb/reader/api/v1/learning_collector.py +0 -63
  280. nucliadb/reader/tests/__init__.py +0 -19
  281. nucliadb/reader/tests/conftest.py +0 -31
  282. nucliadb/reader/tests/fixtures.py +0 -136
  283. nucliadb/reader/tests/test_list_resources.py +0 -75
  284. nucliadb/reader/tests/test_reader_file_download.py +0 -273
  285. nucliadb/reader/tests/test_reader_resource.py +0 -353
  286. nucliadb/reader/tests/test_reader_resource_field.py +0 -219
  287. nucliadb/search/api/v1/chat.py +0 -263
  288. nucliadb/search/api/v1/resource/chat.py +0 -174
  289. nucliadb/search/tests/__init__.py +0 -19
  290. nucliadb/search/tests/conftest.py +0 -33
  291. nucliadb/search/tests/fixtures.py +0 -199
  292. nucliadb/search/tests/node.py +0 -466
  293. nucliadb/search/tests/unit/__init__.py +0 -18
  294. nucliadb/search/tests/unit/api/__init__.py +0 -19
  295. nucliadb/search/tests/unit/api/v1/__init__.py +0 -19
  296. nucliadb/search/tests/unit/api/v1/resource/__init__.py +0 -19
  297. nucliadb/search/tests/unit/api/v1/resource/test_chat.py +0 -98
  298. nucliadb/search/tests/unit/api/v1/test_ask.py +0 -120
  299. nucliadb/search/tests/unit/api/v1/test_chat.py +0 -96
  300. nucliadb/search/tests/unit/api/v1/test_predict_proxy.py +0 -98
  301. nucliadb/search/tests/unit/api/v1/test_summarize.py +0 -99
  302. nucliadb/search/tests/unit/search/__init__.py +0 -18
  303. nucliadb/search/tests/unit/search/requesters/__init__.py +0 -18
  304. nucliadb/search/tests/unit/search/requesters/test_utils.py +0 -211
  305. nucliadb/search/tests/unit/search/search/__init__.py +0 -19
  306. nucliadb/search/tests/unit/search/search/test_shards.py +0 -45
  307. nucliadb/search/tests/unit/search/search/test_utils.py +0 -82
  308. nucliadb/search/tests/unit/search/test_chat_prompt.py +0 -270
  309. nucliadb/search/tests/unit/search/test_fetch.py +0 -108
  310. nucliadb/search/tests/unit/search/test_filters.py +0 -125
  311. nucliadb/search/tests/unit/search/test_paragraphs.py +0 -157
  312. nucliadb/search/tests/unit/search/test_predict_proxy.py +0 -106
  313. nucliadb/search/tests/unit/search/test_query.py +0 -153
  314. nucliadb/search/tests/unit/test_app.py +0 -79
  315. nucliadb/search/tests/unit/test_find_merge.py +0 -112
  316. nucliadb/search/tests/unit/test_merge.py +0 -34
  317. nucliadb/search/tests/unit/test_predict.py +0 -525
  318. nucliadb/standalone/tests/__init__.py +0 -19
  319. nucliadb/standalone/tests/conftest.py +0 -33
  320. nucliadb/standalone/tests/fixtures.py +0 -38
  321. nucliadb/standalone/tests/unit/__init__.py +0 -18
  322. nucliadb/standalone/tests/unit/test_api_router.py +0 -61
  323. nucliadb/standalone/tests/unit/test_auth.py +0 -169
  324. nucliadb/standalone/tests/unit/test_introspect.py +0 -35
  325. nucliadb/standalone/tests/unit/test_migrations.py +0 -63
  326. nucliadb/standalone/tests/unit/test_versions.py +0 -68
  327. nucliadb/tests/benchmarks/__init__.py +0 -19
  328. nucliadb/tests/benchmarks/test_search.py +0 -99
  329. nucliadb/tests/conftest.py +0 -32
  330. nucliadb/tests/fixtures.py +0 -735
  331. nucliadb/tests/knowledgeboxes/philosophy_books.py +0 -202
  332. nucliadb/tests/knowledgeboxes/ten_dummy_resources.py +0 -107
  333. nucliadb/tests/migrations/test_migration_0017.py +0 -76
  334. nucliadb/tests/migrations/test_migration_0018.py +0 -95
  335. nucliadb/tests/tikv.py +0 -240
  336. nucliadb/tests/unit/__init__.py +0 -19
  337. nucliadb/tests/unit/common/__init__.py +0 -19
  338. nucliadb/tests/unit/common/cluster/__init__.py +0 -19
  339. nucliadb/tests/unit/common/cluster/discovery/__init__.py +0 -19
  340. nucliadb/tests/unit/common/cluster/discovery/test_k8s.py +0 -172
  341. nucliadb/tests/unit/common/cluster/standalone/__init__.py +0 -18
  342. nucliadb/tests/unit/common/cluster/standalone/test_service.py +0 -114
  343. nucliadb/tests/unit/common/cluster/standalone/test_utils.py +0 -61
  344. nucliadb/tests/unit/common/cluster/test_cluster.py +0 -408
  345. nucliadb/tests/unit/common/cluster/test_kb_shard_manager.py +0 -173
  346. nucliadb/tests/unit/common/cluster/test_rebalance.py +0 -38
  347. nucliadb/tests/unit/common/cluster/test_rollover.py +0 -282
  348. nucliadb/tests/unit/common/maindb/__init__.py +0 -18
  349. nucliadb/tests/unit/common/maindb/test_driver.py +0 -127
  350. nucliadb/tests/unit/common/maindb/test_tikv.py +0 -53
  351. nucliadb/tests/unit/common/maindb/test_utils.py +0 -92
  352. nucliadb/tests/unit/common/test_context.py +0 -36
  353. nucliadb/tests/unit/export_import/__init__.py +0 -19
  354. nucliadb/tests/unit/export_import/test_datamanager.py +0 -37
  355. nucliadb/tests/unit/export_import/test_utils.py +0 -301
  356. nucliadb/tests/unit/migrator/__init__.py +0 -19
  357. nucliadb/tests/unit/migrator/test_migrator.py +0 -87
  358. nucliadb/tests/unit/tasks/__init__.py +0 -19
  359. nucliadb/tests/unit/tasks/conftest.py +0 -42
  360. nucliadb/tests/unit/tasks/test_consumer.py +0 -92
  361. nucliadb/tests/unit/tasks/test_producer.py +0 -95
  362. nucliadb/tests/unit/tasks/test_tasks.py +0 -58
  363. nucliadb/tests/unit/test_field_ids.py +0 -49
  364. nucliadb/tests/unit/test_health.py +0 -86
  365. nucliadb/tests/unit/test_kb_slugs.py +0 -54
  366. nucliadb/tests/unit/test_learning_proxy.py +0 -252
  367. nucliadb/tests/unit/test_metrics_exporter.py +0 -77
  368. nucliadb/tests/unit/test_purge.py +0 -136
  369. nucliadb/tests/utils/__init__.py +0 -74
  370. nucliadb/tests/utils/aiohttp_session.py +0 -44
  371. nucliadb/tests/utils/broker_messages/__init__.py +0 -171
  372. nucliadb/tests/utils/broker_messages/fields.py +0 -197
  373. nucliadb/tests/utils/broker_messages/helpers.py +0 -33
  374. nucliadb/tests/utils/entities.py +0 -78
  375. nucliadb/train/api/v1/check.py +0 -60
  376. nucliadb/train/tests/__init__.py +0 -19
  377. nucliadb/train/tests/conftest.py +0 -29
  378. nucliadb/train/tests/fixtures.py +0 -342
  379. nucliadb/train/tests/test_field_classification.py +0 -122
  380. nucliadb/train/tests/test_get_entities.py +0 -80
  381. nucliadb/train/tests/test_get_info.py +0 -51
  382. nucliadb/train/tests/test_get_ontology.py +0 -34
  383. nucliadb/train/tests/test_get_ontology_count.py +0 -63
  384. nucliadb/train/tests/test_image_classification.py +0 -221
  385. nucliadb/train/tests/test_list_fields.py +0 -39
  386. nucliadb/train/tests/test_list_paragraphs.py +0 -73
  387. nucliadb/train/tests/test_list_resources.py +0 -39
  388. nucliadb/train/tests/test_list_sentences.py +0 -71
  389. nucliadb/train/tests/test_paragraph_classification.py +0 -123
  390. nucliadb/train/tests/test_paragraph_streaming.py +0 -118
  391. nucliadb/train/tests/test_question_answer_streaming.py +0 -239
  392. nucliadb/train/tests/test_sentence_classification.py +0 -143
  393. nucliadb/train/tests/test_token_classification.py +0 -136
  394. nucliadb/train/tests/utils.py +0 -101
  395. nucliadb/writer/layouts/__init__.py +0 -51
  396. nucliadb/writer/layouts/v1.py +0 -59
  397. nucliadb/writer/tests/__init__.py +0 -19
  398. nucliadb/writer/tests/conftest.py +0 -31
  399. nucliadb/writer/tests/fixtures.py +0 -191
  400. nucliadb/writer/tests/test_fields.py +0 -475
  401. nucliadb/writer/tests/test_files.py +0 -740
  402. nucliadb/writer/tests/test_knowledgebox.py +0 -49
  403. nucliadb/writer/tests/test_reprocess_file_field.py +0 -133
  404. nucliadb/writer/tests/test_resources.py +0 -476
  405. nucliadb/writer/tests/test_service.py +0 -137
  406. nucliadb/writer/tests/test_tus.py +0 -203
  407. nucliadb/writer/tests/utils.py +0 -35
  408. nucliadb/writer/tus/pg.py +0 -125
  409. nucliadb-4.0.0.post542.dist-info/METADATA +0 -135
  410. nucliadb-4.0.0.post542.dist-info/RECORD +0 -462
  411. {nucliadb/ingest/tests → migrations/pg}/__init__.py +0 -0
  412. /nucliadb/{ingest/tests/integration → common/external_index_providers}/__init__.py +0 -0
  413. /nucliadb/{ingest/tests/integration/ingest → common/models_utils}/__init__.py +0 -0
  414. /nucliadb/{ingest/tests/unit → search/search/query_parser}/__init__.py +0 -0
  415. /nucliadb/{ingest/tests → tests}/vectors.py +0 -0
  416. {nucliadb-4.0.0.post542.dist-info → nucliadb-6.2.1.post2798.dist-info}/entry_points.txt +0 -0
  417. {nucliadb-4.0.0.post542.dist-info → nucliadb-6.2.1.post2798.dist-info}/top_level.txt +0 -0
  418. {nucliadb-4.0.0.post542.dist-info → nucliadb-6.2.1.post2798.dist-info}/zip-safe +0 -0
@@ -20,65 +20,108 @@
20
20
  from __future__ import annotations
21
21
 
22
22
  import asyncio
23
- from typing import Any, AsyncGenerator, Optional, Union
23
+ import logging
24
+ from contextlib import asynccontextmanager
25
+ from typing import Any, AsyncGenerator, Optional
24
26
 
25
- import asyncpg
26
27
  import backoff
28
+ import psycopg
29
+ import psycopg_pool
27
30
 
28
31
  from nucliadb.common.maindb.driver import DEFAULT_SCAN_LIMIT, Driver, Transaction
32
+ from nucliadb.common.maindb.exceptions import ConflictError
33
+ from nucliadb_telemetry import metrics
29
34
 
30
35
  RETRIABLE_EXCEPTIONS = (
31
- asyncpg.CannotConnectNowError,
36
+ psycopg_pool.PoolTimeout,
32
37
  OSError,
33
38
  ConnectionResetError,
34
39
  )
35
40
 
36
- CREATE_TABLE = """
37
- CREATE TABLE IF NOT EXISTS resources (
38
- key TEXT PRIMARY KEY,
39
- value BYTEA
40
- );
41
- """
41
+ logger = logging.getLogger(__name__)
42
+
43
+ # Request Metrics
44
+ pg_observer = metrics.Observer(
45
+ "pg_client",
46
+ labels={"type": ""},
47
+ )
48
+
49
+ # Pool metrics
50
+ POOL_METRICS_COUNTERS = {
51
+ # Requests for a connection to the pool
52
+ "requests_num": metrics.Counter("pg_client_pool_requests_total"),
53
+ "requests_queued": metrics.Counter("pg_client_pool_requests_queued_total"),
54
+ "requests_errors": metrics.Counter("pg_client_pool_requests_errors_total"),
55
+ "requests_wait_ms": metrics.Counter("pg_client_pool_requests_queued_seconds_total"),
56
+ "usage_ms": metrics.Counter("pg_client_pool_requests_usage_seconds_total"),
57
+ # Pool opening a connection to PG
58
+ "connections_num": metrics.Counter("pg_client_pool_connections_total"),
59
+ "connections_ms": metrics.Counter("pg_client_pool_connections_seconds_total"),
60
+ }
61
+ POOL_METRICS_GAUGES = {
62
+ "pool_size": metrics.Gauge("pg_client_pool_connections_open"),
63
+ # The two below most likely change too rapidly to be useful in a metric
64
+ "pool_available": metrics.Gauge("pg_client_pool_connections_available"),
65
+ "requests_waiting": metrics.Gauge("pg_client_pool_requests_waiting"),
66
+ }
42
67
 
43
68
 
44
69
  class DataLayer:
45
- def __init__(self, connection: Union[asyncpg.Connection, asyncpg.Pool]):
70
+ def __init__(self, connection: psycopg.AsyncConnection):
46
71
  self.connection = connection
47
- self.lock = asyncio.Lock()
48
72
 
49
- async def get(self, key: str) -> Optional[bytes]:
50
- async with self.lock:
51
- return await self.connection.fetchval(
52
- "SELECT value FROM resources WHERE key = $1", key
53
- )
73
+ async def get(self, key: str, select_for_update: bool = False) -> Optional[bytes]:
74
+ with pg_observer({"type": "get"}):
75
+ statement = "SELECT value FROM resources WHERE key = %s"
76
+ if select_for_update:
77
+ statement += " FOR UPDATE"
78
+ async with self.connection.cursor() as cur:
79
+ await cur.execute(statement, (key,))
80
+ row = await cur.fetchone()
81
+ return row[0] if row else None
54
82
 
55
83
  async def set(self, key: str, value: bytes) -> None:
56
- async with self.lock:
57
- await self.connection.execute(
58
- """
59
- INSERT INTO resources (key, value)
60
- VALUES ($1, $2)
61
- ON CONFLICT (key)
62
- DO UPDATE SET value = EXCLUDED.value
63
- """,
64
- key,
65
- value,
66
- )
84
+ with pg_observer({"type": "set"}):
85
+ async with self.connection.cursor() as cur:
86
+ await cur.execute(
87
+ "INSERT INTO resources (key, value) "
88
+ "VALUES (%s, %s) "
89
+ "ON CONFLICT (key) "
90
+ "DO UPDATE SET value = EXCLUDED.value",
91
+ (key, value),
92
+ )
93
+
94
+ async def insert(self, key: str, value: bytes) -> None:
95
+ with pg_observer({"type": "insert"}):
96
+ async with self.connection.cursor() as cur:
97
+ try:
98
+ await cur.execute(
99
+ "INSERT INTO resources (key, value) VALUES (%s, %s) ",
100
+ (key, value),
101
+ )
102
+ except psycopg.errors.UniqueViolation:
103
+ raise ConflictError(key)
67
104
 
68
105
  async def delete(self, key: str) -> None:
69
- async with self.lock:
70
- await self.connection.execute("DELETE FROM resources WHERE key = $1", key)
71
-
72
- async def batch_get(self, keys: list[str]) -> list[Optional[bytes]]:
73
- async with self.lock:
74
- records = {
75
- record["key"]: record["value"]
76
- for record in await self.connection.fetch(
77
- "SELECT key, value FROM resources WHERE key = ANY($1)", keys
78
- )
79
- }
80
- # get sorted by keys
81
- return [records.get(key) for key in keys]
106
+ with pg_observer({"type": "delete"}):
107
+ async with self.connection.cursor() as cur:
108
+ await cur.execute("DELETE FROM resources WHERE key = %s", (key,))
109
+
110
+ async def delete_by_prefix(self, prefix: str) -> None:
111
+ with pg_observer({"type": "delete_by_prefix"}):
112
+ async with self.connection.cursor() as cur:
113
+ await cur.execute("DELETE FROM resources WHERE key LIKE %s", (prefix + "%",))
114
+
115
+ async def batch_get(self, keys: list[str], select_for_update: bool = False) -> list[Optional[bytes]]:
116
+ with pg_observer({"type": "batch_get"}):
117
+ async with self.connection.cursor() as cur:
118
+ statement = "SELECT key, value FROM resources WHERE key = ANY(%s)"
119
+ if select_for_update:
120
+ statement += " FOR UPDATE"
121
+ await cur.execute(statement, (keys,))
122
+ records = {record[0]: record[1] for record in await cur.fetchall()}
123
+ # get sorted by keys
124
+ return [records.get(key) for key in keys]
82
125
 
83
126
  async def scan_keys(
84
127
  self,
@@ -86,26 +129,25 @@ DO UPDATE SET value = EXCLUDED.value
86
129
  limit: int = DEFAULT_SCAN_LIMIT,
87
130
  include_start: bool = True,
88
131
  ) -> AsyncGenerator[str, None]:
89
- query = """SELECT key FROM resources
90
- WHERE key LIKE $1
91
- ORDER BY key
92
- """
132
+ query = "SELECT key FROM resources WHERE key LIKE %s ORDER BY key"
133
+
93
134
  args: list[Any] = [prefix + "%"]
94
135
  if limit > 0:
95
- query += " LIMIT $2"
136
+ query += " LIMIT %s"
96
137
  args.append(limit)
97
- async with self.lock:
98
- async for record in self.connection.cursor(query, *args):
99
- if not include_start and record["key"] == prefix:
100
- continue
101
- yield record["key"]
138
+ with pg_observer({"type": "scan_keys"}):
139
+ async with self.connection.cursor() as cur:
140
+ async for record in cur.stream(query, args):
141
+ if not include_start and record[0] == prefix:
142
+ continue
143
+ yield record[0]
102
144
 
103
145
  async def count(self, match: str) -> int:
104
- async with self.lock:
105
- results = await self.connection.fetch(
106
- "SELECT count(*) FROM resources WHERE key LIKE $1", match + "%"
107
- )
108
- return results[0]["count"]
146
+ with pg_observer({"type": "count"}):
147
+ async with self.connection.cursor() as cur:
148
+ await cur.execute("SELECT count(*) FROM resources WHERE key LIKE %s", (match + "%",))
149
+ row = await cur.fetchone()
150
+ return row[0] # type: ignore
109
151
 
110
152
 
111
153
  class PGTransaction(Transaction):
@@ -113,62 +155,60 @@ class PGTransaction(Transaction):
113
155
 
114
156
  def __init__(
115
157
  self,
116
- pool: asyncpg.Pool,
117
- connection: asyncpg.Connection,
118
- txn: Any,
119
158
  driver: PGDriver,
159
+ connection: psycopg.AsyncConnection,
120
160
  ):
121
- self.pool = pool
161
+ self.driver = driver
122
162
  self.connection = connection
123
163
  self.data_layer = DataLayer(connection)
124
- self.txn = txn
125
- self.driver = driver
126
164
  self.open = True
127
- self._lock = asyncio.Lock()
128
165
 
129
166
  async def abort(self):
130
- async with self._lock:
167
+ with pg_observer({"type": "rollback"}):
131
168
  if self.open:
132
169
  try:
133
- await self.txn.rollback()
170
+ await self.connection.rollback()
134
171
  finally:
135
172
  self.open = False
136
- await self.connection.close()
137
173
 
138
174
  async def commit(self):
139
- async with self._lock:
175
+ with pg_observer({"type": "commit"}):
140
176
  try:
141
- await self.txn.commit()
177
+ await self.connection.commit()
142
178
  except Exception:
143
- await self.txn.rollback()
179
+ await self.connection.rollback()
144
180
  raise
145
181
  finally:
146
182
  self.open = False
147
- await self.connection.close()
148
183
 
149
- async def batch_get(self, keys: list[str]):
150
- return await self.data_layer.batch_get(keys)
184
+ async def batch_get(self, keys: list[str], for_update: bool = True):
185
+ return await self.data_layer.batch_get(keys, select_for_update=for_update)
151
186
 
152
- async def get(self, key: str) -> Optional[bytes]:
153
- return await self.data_layer.get(key)
187
+ async def get(self, key: str, for_update: bool = True) -> Optional[bytes]:
188
+ return await self.data_layer.get(key, select_for_update=for_update)
154
189
 
155
190
  async def set(self, key: str, value: bytes):
156
191
  await self.data_layer.set(key, value)
157
192
 
193
+ async def insert(self, key: str, value: bytes):
194
+ await self.data_layer.insert(key, value)
195
+
158
196
  async def delete(self, key: str):
159
197
  await self.data_layer.delete(key)
160
198
 
161
- @backoff.on_exception(
162
- backoff.expo, RETRIABLE_EXCEPTIONS, jitter=backoff.random_jitter, max_tries=2
163
- )
199
+ async def delete_by_prefix(self, prefix: str) -> None:
200
+ await self.data_layer.delete_by_prefix(prefix)
201
+
202
+ @backoff.on_exception(backoff.expo, RETRIABLE_EXCEPTIONS, jitter=backoff.random_jitter, max_tries=2)
164
203
  async def keys(
165
204
  self,
166
205
  match: str,
167
206
  count: int = DEFAULT_SCAN_LIMIT,
168
207
  include_start: bool = True,
169
208
  ):
170
- async with self.pool.acquire() as conn, conn.transaction():
171
- # all txn implementations implement this API outside of the current txn
209
+ # Check out a new connection to guarantee that the cursor iteration does not
210
+ # run concurrently with other queries
211
+ async with self.driver._get_connection() as conn, conn.transaction():
172
212
  dl = DataLayer(conn)
173
213
  async for key in dl.scan_keys(match, count, include_start=include_start):
174
214
  yield key
@@ -180,8 +220,7 @@ class PGTransaction(Transaction):
180
220
  class ReadOnlyPGTransaction(Transaction):
181
221
  driver: PGDriver
182
222
 
183
- def __init__(self, pool: asyncpg.Pool, driver: PGDriver):
184
- self.pool = pool
223
+ def __init__(self, driver: PGDriver):
185
224
  self.driver = driver
186
225
  self.open = True
187
226
 
@@ -192,11 +231,15 @@ class ReadOnlyPGTransaction(Transaction):
192
231
  async def commit(self):
193
232
  raise Exception("Cannot commit transaction in read only mode")
194
233
 
195
- async def batch_get(self, keys: list[str]):
196
- return await DataLayer(self.pool).batch_get(keys)
234
+ @backoff.on_exception(backoff.expo, RETRIABLE_EXCEPTIONS, jitter=backoff.random_jitter, max_tries=3)
235
+ async def batch_get(self, keys: list[str], for_update: bool = False):
236
+ async with self.driver._get_connection() as conn:
237
+ return await DataLayer(conn).batch_get(keys, select_for_update=False)
197
238
 
198
- async def get(self, key: str) -> Optional[bytes]:
199
- return await DataLayer(self.pool).get(key)
239
+ @backoff.on_exception(backoff.expo, RETRIABLE_EXCEPTIONS, jitter=backoff.random_jitter, max_tries=3)
240
+ async def get(self, key: str, for_update: bool = False) -> Optional[bytes]:
241
+ async with self.driver._get_connection() as conn:
242
+ return await DataLayer(conn).get(key, select_for_update=False)
200
243
 
201
244
  async def set(self, key: str, value: bytes):
202
245
  raise Exception("Cannot set in read only transaction")
@@ -204,62 +247,114 @@ class ReadOnlyPGTransaction(Transaction):
204
247
  async def delete(self, key: str):
205
248
  raise Exception("Cannot delete in read only transaction")
206
249
 
250
+ @backoff.on_exception(backoff.expo, RETRIABLE_EXCEPTIONS, jitter=backoff.random_jitter, max_tries=3)
207
251
  async def keys(
208
252
  self,
209
253
  match: str,
210
254
  count: int = DEFAULT_SCAN_LIMIT,
211
255
  include_start: bool = True,
212
256
  ):
213
- async with self.pool.acquire() as conn, conn.transaction():
214
- # all txn implementations implement this API outside of the current txn
257
+ async with self.driver._get_connection() as conn, conn.transaction():
215
258
  dl = DataLayer(conn)
216
259
  async for key in dl.scan_keys(match, count, include_start=include_start):
217
260
  yield key
218
261
 
262
+ @backoff.on_exception(backoff.expo, RETRIABLE_EXCEPTIONS, jitter=backoff.random_jitter, max_tries=3)
219
263
  async def count(self, match: str) -> int:
220
- return await DataLayer(self.pool).count(match)
264
+ async with self.driver._get_connection() as conn:
265
+ return await DataLayer(conn).count(match)
221
266
 
222
267
 
223
268
  class PGDriver(Driver):
224
- pool: asyncpg.Pool
269
+ pool: psycopg_pool.AsyncConnectionPool
225
270
 
226
- def __init__(self, url: str, connection_pool_max_size: int = 10):
271
+ def __init__(
272
+ self,
273
+ url: str,
274
+ connection_pool_min_size: int = 10,
275
+ connection_pool_max_size: int = 10,
276
+ acquire_timeout_ms: int = 200,
277
+ ):
227
278
  self.url = url
279
+ self.connection_pool_min_size = connection_pool_min_size
228
280
  self.connection_pool_max_size = connection_pool_max_size
281
+ self.acquire_timeout_ms = acquire_timeout_ms
229
282
  self._lock = asyncio.Lock()
230
283
 
231
284
  async def initialize(self):
232
285
  async with self._lock:
233
286
  if self.initialized is False:
234
- self.pool = await asyncpg.create_pool(
287
+ self.pool = psycopg_pool.AsyncConnectionPool(
235
288
  self.url,
289
+ min_size=self.connection_pool_min_size,
236
290
  max_size=self.connection_pool_max_size,
291
+ check=psycopg_pool.AsyncConnectionPool.check_connection,
292
+ open=False,
237
293
  )
238
-
239
- # check if table exists
240
- try:
241
- async with self.pool.acquire() as conn:
242
- await conn.execute(CREATE_TABLE)
243
- except asyncpg.exceptions.UniqueViolationError: # pragma: no cover
244
- pass
294
+ await self.pool.open()
245
295
 
246
296
  self.initialized = True
297
+ self.metrics_task = asyncio.create_task(self._report_metrics_task())
247
298
 
248
299
  async def finalize(self):
249
300
  async with self._lock:
250
- await self.pool.close()
251
- self.initialized = False
252
-
253
- @backoff.on_exception(
254
- backoff.expo, RETRIABLE_EXCEPTIONS, jitter=backoff.random_jitter, max_tries=3
255
- )
256
- async def begin(
257
- self, read_only: bool = False
258
- ) -> Union[PGTransaction, ReadOnlyPGTransaction]:
301
+ if self.initialized:
302
+ await self.pool.close()
303
+ self.initialized = False
304
+ self.metrics_task.cancel()
305
+
306
+ async def _report_metrics_task(self):
307
+ while True:
308
+ self._report_metrics()
309
+ await asyncio.sleep(60)
310
+
311
+ def _report_metrics(self):
312
+ if not self.initialized:
313
+ return
314
+
315
+ metrics = self.pool.pop_stats()
316
+ for key, metric in POOL_METRICS_COUNTERS.items():
317
+ value = metrics.get(key, 0)
318
+ if key.endswith("_ms"):
319
+ value /= 1000
320
+ metric.inc(value=value)
321
+
322
+ for key, metric in POOL_METRICS_GAUGES.items():
323
+ value = metrics.get(key, 0)
324
+ metric.set(value)
325
+
326
+ @asynccontextmanager
327
+ async def transaction(self, read_only: bool = False) -> AsyncGenerator[Transaction, None]:
259
328
  if read_only:
260
- return ReadOnlyPGTransaction(self.pool, driver=self)
329
+ yield ReadOnlyPGTransaction(self)
261
330
  else:
262
- conn: asyncpg.Connection = await self.pool.acquire()
263
- txn = conn.transaction()
264
- await txn.start()
265
- return PGTransaction(self.pool, conn, txn, driver=self)
331
+ async with self._get_connection() as conn:
332
+ txn = PGTransaction(self, conn)
333
+ try:
334
+ yield txn
335
+ finally:
336
+ if txn.open:
337
+ await txn.abort()
338
+
339
+ @asynccontextmanager
340
+ async def _get_connection(self) -> AsyncGenerator[psycopg.AsyncConnection, None]:
341
+ timeout = self.acquire_timeout_ms / 1000
342
+ # Manual retry loop since backoff.on_exception does not play well with async context managers
343
+ retries = 0
344
+ while True:
345
+ with pg_observer({"type": "acquire"}):
346
+ try:
347
+ async with self.pool.connection(timeout=timeout) as conn:
348
+ yield conn
349
+ return
350
+ except psycopg_pool.PoolTimeout as e:
351
+ logger.warning(
352
+ f"Timeout getting connection from the pool, backing off. Retries = {retries}"
353
+ )
354
+ if retries < 3:
355
+ await asyncio.sleep(1)
356
+ retries += 1
357
+ else:
358
+ raise e
359
+ except Exception as e:
360
+ raise e
@@ -16,6 +16,8 @@
16
16
  #
17
17
  # You should have received a copy of the GNU Affero General Public License
18
18
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ from warnings import warn
20
+
19
21
  from nucliadb.common.maindb.driver import Driver
20
22
  from nucliadb.common.maindb.exceptions import UnsetUtility
21
23
  from nucliadb.ingest.settings import DriverConfig, settings
@@ -23,19 +25,11 @@ from nucliadb_utils.exceptions import ConfigurationError
23
25
  from nucliadb_utils.utilities import Utility, clean_utility, get_utility, set_utility
24
26
 
25
27
  try:
26
- from nucliadb.common.maindb.redis import RedisDriver
27
-
28
- REDIS = True
29
- except ImportError: # pragma: no cover
30
- REDIS = False
31
-
32
- try:
33
- from nucliadb.common.maindb.tikv import TiKVDriver
28
+ from nucliadb.common.maindb.local import LocalDriver
34
29
 
35
- TIKV = True
30
+ FILES = True
36
31
  except ImportError: # pragma: no cover
37
- TIKV = False
38
-
32
+ FILES = False
39
33
 
40
34
  try:
41
35
  from nucliadb.common.maindb.pg import PGDriver
@@ -44,13 +38,6 @@ try:
44
38
  except ImportError: # pragma: no cover
45
39
  PG = False
46
40
 
47
- try:
48
- from nucliadb.common.maindb.local import LocalDriver
49
-
50
- FILES = True
51
- except ImportError: # pragma: no cover
52
- FILES = False
53
-
54
41
 
55
42
  def get_driver() -> Driver:
56
43
  driver = get_utility(Utility.MAINDB_DRIVER)
@@ -64,32 +51,16 @@ async def setup_driver() -> Driver:
64
51
  if driver is not None:
65
52
  return driver
66
53
 
67
- if settings.driver == DriverConfig.REDIS:
68
- if not REDIS:
69
- raise ConfigurationError("`redis` python package not installed.")
70
- if settings.driver_redis_url is None:
71
- raise ConfigurationError("No DRIVER_REDIS_URL env var defined.")
72
-
73
- redis_driver = RedisDriver(settings.driver_redis_url)
74
- set_utility(Utility.MAINDB_DRIVER, redis_driver)
75
- elif settings.driver == DriverConfig.TIKV:
76
- if not TIKV:
77
- raise ConfigurationError("`tikv_client` python package not installed.")
78
- if settings.driver_tikv_url is None:
79
- raise ConfigurationError("No DRIVER_TIKV_URL env var defined.")
80
-
81
- tikv_driver = TiKVDriver(
82
- settings.driver_tikv_url, settings.driver_tikv_connection_pool_size
83
- )
84
- set_utility(Utility.MAINDB_DRIVER, tikv_driver)
85
- elif settings.driver == DriverConfig.PG:
54
+ if settings.driver == DriverConfig.PG:
86
55
  if not PG:
87
- raise ConfigurationError("`asyncpg` python package not installed.")
56
+ raise ConfigurationError("`psycopg` python package not installed.")
88
57
  if settings.driver_pg_url is None:
89
58
  raise ConfigurationError("No DRIVER_PG_URL env var defined.")
90
59
  pg_driver = PGDriver(
91
60
  url=settings.driver_pg_url,
61
+ connection_pool_min_size=settings.driver_pg_connection_pool_min_size,
92
62
  connection_pool_max_size=settings.driver_pg_connection_pool_max_size,
63
+ acquire_timeout_ms=settings.driver_pg_connection_pool_acquire_timeout_ms,
93
64
  )
94
65
  set_utility(Utility.MAINDB_DRIVER, pg_driver)
95
66
  elif settings.driver == DriverConfig.LOCAL:
@@ -97,13 +68,11 @@ async def setup_driver() -> Driver:
97
68
  raise ConfigurationError("`aiofiles` python package not installed.")
98
69
  if settings.driver_local_url is None:
99
70
  raise ConfigurationError("No DRIVER_LOCAL_URL env var defined.")
100
-
101
71
  local_driver = LocalDriver(settings.driver_local_url)
102
72
  set_utility(Utility.MAINDB_DRIVER, local_driver)
73
+ warn("LocalDriver is not recommended for production use", RuntimeWarning)
103
74
  else:
104
- raise ConfigurationError(
105
- f"Invalid DRIVER defined configured: {settings.driver}"
106
- )
75
+ raise ConfigurationError(f"Invalid DRIVER defined configured: {settings.driver}")
107
76
 
108
77
  driver = get_driver()
109
78
  if not driver.initialized: