nucliadb 6.9.0.post5078__py3-none-any.whl → 6.9.0.post5086__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.

Potentially problematic release.


This version of nucliadb might be problematic. Click here for more details.

@@ -58,7 +58,19 @@ class Conversation(Field[PBConversation]):
58
58
  self._splits_metadata: Optional[SplitsMetadata] = None
59
59
  self.metadata = None
60
60
 
61
+ async def delete_value(self):
62
+ await self.resource.txn.delete_by_prefix(
63
+ CONVERSATION_METADATA.format(kbid=self.kbid, uuid=self.uuid, type=self.type, field=self.id)
64
+ )
65
+ self._split_metadata = None
66
+ self.metadata = None
67
+ self.value.clear()
68
+
61
69
  async def set_value(self, payload: PBConversation):
70
+ if payload.replace_field:
71
+ # As we need to overwrite the value of the conversation, first delete any previous data.
72
+ await self.delete_value()
73
+
62
74
  metadata = await self.get_metadata()
63
75
  metadata.extract_strategy = payload.extract_strategy
64
76
  metadata.split_strategy = payload.split_strategy
@@ -249,9 +249,10 @@ async def parse_conversation_field_adapter(
249
249
  writer: BrokerMessage,
250
250
  toprocess: PushPayload,
251
251
  resource_classifications: ResourceClassifications,
252
+ replace_field: bool = False,
252
253
  ):
253
254
  return await parse_conversation_field(
254
- field_id, field_payload, writer, toprocess, kbid, rid, resource_classifications
255
+ field_id, field_payload, writer, toprocess, kbid, rid, resource_classifications, replace_field
255
256
  )
256
257
 
257
258
 
@@ -380,7 +381,9 @@ async def add_resource_field_conversation_rslug_prefix(
380
381
  field_id: FieldIdString,
381
382
  field_payload: models.InputConversationField,
382
383
  ) -> ResourceFieldAdded:
383
- return await add_field_to_resource_by_slug(request, kbid, rslug, field_id, field_payload)
384
+ return await add_field_to_resource_by_slug(
385
+ request, kbid, rslug, field_id, field_payload, replace_field=True
386
+ )
384
387
 
385
388
 
386
389
  @api.put(
@@ -399,7 +402,7 @@ async def add_resource_field_conversation_rid_prefix(
399
402
  field_id: FieldIdString,
400
403
  field_payload: models.InputConversationField,
401
404
  ) -> ResourceFieldAdded:
402
- return await add_field_to_resource(request, kbid, rid, field_id, field_payload)
405
+ return await add_field_to_resource(request, kbid, rid, field_id, field_payload, replace_field=True)
403
406
 
404
407
 
405
408
  @api.put(
@@ -466,7 +469,9 @@ async def append_messages_to_conversation_field_rslug_prefix(
466
469
  field = models.InputConversationField(messages=messages)
467
470
  except pydantic.ValidationError as e:
468
471
  raise HTTPException(status_code=422, detail=str(e))
469
- return await add_field_to_resource_by_slug(request, kbid, rslug, field_id, field)
472
+ return await add_field_to_resource_by_slug(
473
+ request, kbid, rslug, field_id, field, replace_field=False
474
+ )
470
475
 
471
476
 
472
477
  @api.put(
@@ -489,7 +494,7 @@ async def append_messages_to_conversation_field_rid_prefix(
489
494
  field = models.InputConversationField(messages=messages)
490
495
  except pydantic.ValidationError as e:
491
496
  raise HTTPException(status_code=422, detail=str(e))
492
- return await add_field_to_resource(request, kbid, rid, field_id, field)
497
+ return await add_field_to_resource(request, kbid, rid, field_id, field, replace_field=False)
493
498
 
494
499
 
495
500
  @api.delete(
@@ -228,6 +228,7 @@ async def parse_fields(
228
228
  kbid,
229
229
  uuid,
230
230
  resource_classifications,
231
+ replace_field=True,
231
232
  )
232
233
 
233
234
 
@@ -431,19 +432,15 @@ async def parse_conversation_field(
431
432
  kbid: str,
432
433
  uuid: str,
433
434
  resource_classifications: ResourceClassifications,
435
+ replace_field: bool,
434
436
  ) -> None:
435
- # Make sure that the max number of messages is not exceeded
436
- current_message_count = await get_current_conversation_message_count(kbid, uuid, key)
437
- if len(conversation_field.messages) + current_message_count > MAX_CONVERSATION_MESSAGES:
438
- raise HTTPException(
439
- status_code=422,
440
- detail=f"Conversation fields cannot have more than {MAX_CONVERSATION_MESSAGES} messages.",
441
- )
442
-
437
+ if not replace_field:
438
+ # Appending messages to conversation
439
+ await _conversation_append_checks(kbid, uuid, key, conversation_field)
443
440
  classif_labels = resource_classifications.for_field(key, resources_pb2.FieldType.CONVERSATION)
444
441
  storage = await get_storage(service_name=SERVICE_NAME)
445
442
  processing = get_processing()
446
- field_value = resources_pb2.Conversation()
443
+ field_value = resources_pb2.Conversation(replace_field=replace_field)
447
444
  convs = processing_models.PushConversation()
448
445
  for message in conversation_field.messages:
449
446
  cm = resources_pb2.Message()
@@ -554,13 +551,31 @@ async def get_stored_resource_classifications(
554
551
  return rc
555
552
 
556
553
 
557
- async def get_current_conversation_message_count(kbid: str, rid: str, field_id: str) -> int:
554
+ async def _conversation_append_checks(
555
+ kbid: str, rid: str, field_id: str, input: models.InputConversationField
556
+ ):
558
557
  async with datamanagers.with_ro_transaction() as txn:
559
558
  resource_obj = await datamanagers.resources.get_resource(txn, kbid=kbid, rid=rid)
560
559
  if resource_obj is None:
561
- return 0
562
- field_obj: Conversation = await resource_obj.get_field(
560
+ return
561
+ conv: Conversation = await resource_obj.get_field(
563
562
  field_id, resources_pb2.FieldType.CONVERSATION, load=False
564
563
  )
565
- metadata = await field_obj.get_metadata()
566
- return metadata.total
564
+
565
+ # Make sure that the max number of messages is not exceeded
566
+ current_message_count = (await conv.get_metadata()).total
567
+ if len(input.messages) + current_message_count > MAX_CONVERSATION_MESSAGES:
568
+ raise HTTPException(
569
+ status_code=422,
570
+ detail=f"Conversation fields cannot have more than {MAX_CONVERSATION_MESSAGES} messages.",
571
+ )
572
+
573
+ # Make sure input messages use unique idents
574
+ existing_message_ids = set((await conv.get_splits_metadata()).metadata.keys())
575
+ input_message_ids = {message.ident for message in input.messages}
576
+ intersection = input_message_ids.intersection(existing_message_ids)
577
+ if intersection != set():
578
+ raise HTTPException(
579
+ status_code=422,
580
+ detail=f"Message identifiers must be unique field={field_id}: {list(intersection)[:50]}",
581
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nucliadb
3
- Version: 6.9.0.post5078
3
+ Version: 6.9.0.post5086
4
4
  Summary: NucliaDB
5
5
  Author-email: Nuclia <nucliadb@nuclia.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -19,11 +19,11 @@ Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Programming Language :: Python :: 3 :: Only
20
20
  Requires-Python: <4,>=3.9
21
21
  Description-Content-Type: text/markdown
22
- Requires-Dist: nucliadb-telemetry[all]>=6.9.0.post5078
23
- Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.9.0.post5078
24
- Requires-Dist: nucliadb-protos>=6.9.0.post5078
25
- Requires-Dist: nucliadb-models>=6.9.0.post5078
26
- Requires-Dist: nidx-protos>=6.9.0.post5078
22
+ Requires-Dist: nucliadb-telemetry[all]>=6.9.0.post5086
23
+ Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.9.0.post5086
24
+ Requires-Dist: nucliadb-protos>=6.9.0.post5086
25
+ Requires-Dist: nucliadb-models>=6.9.0.post5086
26
+ Requires-Dist: nidx-protos>=6.9.0.post5086
27
27
  Requires-Dist: nucliadb-admin-assets>=1.0.0.post1224
28
28
  Requires-Dist: nuclia-models>=0.50.0
29
29
  Requires-Dist: uvicorn[standard]
@@ -155,7 +155,7 @@ nucliadb/ingest/consumer/shard_creator.py,sha256=UKIk0yaS_jC_nGQqymn9NGJWzwZEqhI
155
155
  nucliadb/ingest/consumer/utils.py,sha256=jpX8D4lKzuPCpArQLZeX_Zczq3pfen_zAf8sPJfOEZU,2642
156
156
  nucliadb/ingest/fields/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
157
157
  nucliadb/ingest/fields/base.py,sha256=D8NzawonF7hivDW9zvQBbV938TKA6e2OCGqV4kS96RU,24405
158
- nucliadb/ingest/fields/conversation.py,sha256=Jb6nDvlGQiX60VM6NzX1-okrNexlXuUSZ-Ge_yIJYVw,9098
158
+ nucliadb/ingest/fields/conversation.py,sha256=KkOvNM1rZFQRg2RsfGd3Jrz3lpx0HpGpN1cmlpz_mZw,9563
159
159
  nucliadb/ingest/fields/exceptions.py,sha256=sZBk21BSrXFdOdo1qUdCAyD-9YMYakSLdn4_WdIPCIQ,1217
160
160
  nucliadb/ingest/fields/file.py,sha256=1v4jLg3balUua2VmSV8hHkAwPFShTUCOzufZvIUQcQw,4740
161
161
  nucliadb/ingest/fields/generic.py,sha256=elgtqv15aJUq3zY7X_g0bli_2BpcwPArVvzhe54Y4Ig,1547
@@ -361,7 +361,7 @@ nucliadb/writer/api/constants.py,sha256=SCdqGDbEmpdczQdTfbTlpHzVjbLqccPtMQ25MPIF
361
361
  nucliadb/writer/api/utils.py,sha256=wIQHlU8RQiIGVLI72suvyVIKlCU44Unh0Ae0IiN6Qwo,1313
362
362
  nucliadb/writer/api/v1/__init__.py,sha256=akI9A_jloNLb0dU4T5zjfdyvmSAiDeIdjAlzNx74FlU,1128
363
363
  nucliadb/writer/api/v1/export_import.py,sha256=v0sU55TtRSqDzwkDgcwv2uSaqKCuQTtGcMpYoHQYBQA,8192
364
- nucliadb/writer/api/v1/field.py,sha256=qcuniSwR9tR9vn5abpK3rB_olpuUTEj_0LcL_1eAiLw,18972
364
+ nucliadb/writer/api/v1/field.py,sha256=nO3IEV6v5hokdIo5HoaecdwDqvr1PzCJlh5DafzcNTw,19130
365
365
  nucliadb/writer/api/v1/knowledgebox.py,sha256=kioqjD3yN-y1cDTgmXAAOwivXHX9NXxwblcSzGqJup0,9533
366
366
  nucliadb/writer/api/v1/learning_config.py,sha256=DTLEzKJ3dHvi8pbZscjElUqCH_ZvLc6WZgvalFqHo10,4450
367
367
  nucliadb/writer/api/v1/resource.py,sha256=IfcT6HXnR5sC5wSnQSuKmFzEWcLTh7OzZEAV4hYmXnA,20442
@@ -374,7 +374,7 @@ nucliadb/writer/api/v1/vectorsets.py,sha256=F3iMViL5G95_Tns4aO2SOA0DwAzxK2_P8MXx
374
374
  nucliadb/writer/resource/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
375
375
  nucliadb/writer/resource/audit.py,sha256=FvxMZPzrNHtd31HgpZEvxzwAkbxJTZRhPLqRYYJi3tA,1426
376
376
  nucliadb/writer/resource/basic.py,sha256=44GK8M9EEVoAUfGiabdLrrpENqeFwNn7qwxF2AHhQGg,10504
377
- nucliadb/writer/resource/field.py,sha256=eM2KFxhcG3u6-ldniZDSYqGzhJ5bpWgIQBGXXFwskqw,22195
377
+ nucliadb/writer/resource/field.py,sha256=kJFxOgmizGbEuTRPb5o0cNqonZ8sa9ehVlSfRk-ektY,22866
378
378
  nucliadb/writer/resource/origin.py,sha256=pvhUDdU0mlWPUcpoQi4LDUJaRtfjzVVrA8XcGVI_N8k,2021
379
379
  nucliadb/writer/tus/__init__.py,sha256=Kera0BtxoDX0ngPftXiMjNgjrhtQ3l2XFc5nJqSBOJY,5498
380
380
  nucliadb/writer/tus/azure.py,sha256=yxoRi4PhGDikTqVK3PiuVyguy8H9DOS66JpZCY4hpUY,4177
@@ -385,8 +385,8 @@ nucliadb/writer/tus/local.py,sha256=7jYa_w9b-N90jWgN2sQKkNcomqn6JMVBOVeDOVYJHto,
385
385
  nucliadb/writer/tus/s3.py,sha256=vu1BGg4VqJ_x2P1u2BxqPKlSfw5orT_a3R-Ln5oPUpU,8483
386
386
  nucliadb/writer/tus/storage.py,sha256=ToqwjoYnjI4oIcwzkhha_MPxi-k4Jk3Lt55zRwaC1SM,2903
387
387
  nucliadb/writer/tus/utils.py,sha256=MSdVbRsRSZVdkaum69_0wku7X3p5wlZf4nr6E0GMKbw,2556
388
- nucliadb-6.9.0.post5078.dist-info/METADATA,sha256=x9K2fNkUdKoA0BNuiVFTg6IkhDHeiAvUZntKj6P4g94,4158
389
- nucliadb-6.9.0.post5078.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
390
- nucliadb-6.9.0.post5078.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
391
- nucliadb-6.9.0.post5078.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
392
- nucliadb-6.9.0.post5078.dist-info/RECORD,,
388
+ nucliadb-6.9.0.post5086.dist-info/METADATA,sha256=kaY1HSGwZVkCNZzUpp-_XgKI32QB48_6dRb-kK9GUSA,4158
389
+ nucliadb-6.9.0.post5086.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
390
+ nucliadb-6.9.0.post5086.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
391
+ nucliadb-6.9.0.post5086.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
392
+ nucliadb-6.9.0.post5086.dist-info/RECORD,,