nucliadb 6.3.1.post3570__py3-none-any.whl → 6.3.1.post3574__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.
@@ -17,7 +17,6 @@
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
19
  #
20
- from nucliadb.common.context import ApplicationContext
21
20
  from nucliadb.export_import.exporter import export_kb_to_blob_storage
22
21
  from nucliadb.export_import.importer import import_kb_from_blob_storage
23
22
  from nucliadb.export_import.models import NatsTaskMessage
@@ -60,14 +59,13 @@ def get_exports_consumer() -> NatsTaskConsumer[NatsTaskMessage]:
60
59
  )
61
60
 
62
61
 
63
- async def get_exports_producer(context: ApplicationContext) -> NatsTaskProducer[NatsTaskMessage]:
62
+ def get_exports_producer() -> NatsTaskProducer[NatsTaskMessage]:
64
63
  producer = create_producer(
65
64
  name="exports_producer",
66
65
  stream=ExportsNatsConfig.stream,
67
66
  producer_subject=ExportsNatsConfig.consumer.subject,
68
67
  msg_type=NatsTaskMessage,
69
68
  )
70
- await producer.initialize(context)
71
69
  return producer
72
70
 
73
71
 
@@ -82,12 +80,11 @@ def get_imports_consumer() -> NatsTaskConsumer[NatsTaskMessage]:
82
80
  )
83
81
 
84
82
 
85
- async def get_imports_producer(context: ApplicationContext) -> NatsTaskProducer[NatsTaskMessage]:
83
+ def get_imports_producer() -> NatsTaskProducer[NatsTaskMessage]:
86
84
  producer = create_producer(
87
85
  name="imports_producer",
88
86
  stream=ImportsNatsConfig.stream,
89
87
  producer_subject=ImportsNatsConfig.consumer.subject,
90
88
  msg_type=NatsTaskMessage,
91
89
  )
92
- await producer.initialize(context)
93
90
  return producer
@@ -272,6 +272,7 @@ async def get_relations_results_from_entities(
272
272
  timeout: Optional[float] = None,
273
273
  only_with_metadata: bool = False,
274
274
  only_agentic_relations: bool = False,
275
+ only_entity_to_entity: bool = False,
275
276
  deleted_entities: set[str] = set(),
276
277
  ) -> Relations:
277
278
  request = SearchRequest()
@@ -295,7 +296,11 @@ async def get_relations_results_from_entities(
295
296
  )
296
297
  relations_results: list[RelationSearchResponse] = [result.relation for result in results]
297
298
  return await merge_relations_results(
298
- relations_results, request.relation_subgraph, only_with_metadata, only_agentic_relations
299
+ relations_results,
300
+ request.relation_subgraph,
301
+ only_with_metadata,
302
+ only_agentic_relations,
303
+ only_entity_to_entity,
299
304
  )
300
305
 
301
306
 
@@ -369,8 +369,10 @@ async def get_graph_results(
369
369
  kbid=kbid,
370
370
  entities=entities_to_explore,
371
371
  timeout=5.0,
372
- only_with_metadata=True,
372
+ only_with_metadata=not graph_strategy.relation_text_as_paragraphs,
373
373
  only_agentic_relations=graph_strategy.agentic_graph_only,
374
+ # We only want entity to entity relations (skip resource/labels/collaborators/etc.)
375
+ only_entity_to_entity=True,
374
376
  deleted_entities=explored_entities,
375
377
  )
376
378
  except Exception as e:
@@ -683,6 +685,7 @@ def build_text_blocks_from_relations(
683
685
  triplets: dict[tuple[str, str, str], tuple[float, Relations, Optional[ParagraphId]]] = defaultdict(
684
686
  lambda: (0.0, Relations(entities={}), None)
685
687
  )
688
+ paragraph_count = 0
686
689
  for ent, subgraph in relations.entities.items():
687
690
  for rel, score in zip(subgraph.related_to, scores[ent]):
688
691
  key = (
@@ -702,6 +705,14 @@ def build_text_blocks_from_relations(
702
705
  # we keep the first one, but we lose the other ones
703
706
  if p_id is None and rel.metadata and rel.metadata.paragraph_id:
704
707
  p_id = ParagraphId.from_string(rel.metadata.paragraph_id)
708
+ else:
709
+ # No paragraph ID set, fake it so we can hydrate the resource
710
+ p_id = ParagraphId(
711
+ field_id=FieldId(rel.resource_id, "a", "usermetadata"),
712
+ paragraph_start=paragraph_count,
713
+ paragraph_end=paragraph_count + 1,
714
+ )
715
+ paragraph_count += 1
705
716
  existing_relations.entities[ent].related_to.append(rel)
706
717
  # XXX: Here we use the max even though all relations with same triplet should have same score
707
718
  triplets[key] = (max(existing_score, score), existing_relations, p_id)
@@ -35,6 +35,7 @@ from nucliadb.search.search.fetch import (
35
35
  )
36
36
  from nucliadb_models.common import FieldTypeName
37
37
  from nucliadb_models.labels import translate_system_to_alias_label
38
+ from nucliadb_models.metadata import RelationType
38
39
  from nucliadb_models.resource import ExtractedDataTypeName
39
40
  from nucliadb_models.search import (
40
41
  DirectionalRelation,
@@ -445,6 +446,7 @@ async def merge_relations_results(
445
446
  query: EntitiesSubgraphRequest,
446
447
  only_with_metadata: bool = False,
447
448
  only_agentic: bool = False,
449
+ only_entity_to_entity: bool = False,
448
450
  ) -> Relations:
449
451
  loop = asyncio.get_event_loop()
450
452
  return await loop.run_in_executor(
@@ -454,6 +456,7 @@ async def merge_relations_results(
454
456
  query,
455
457
  only_with_metadata,
456
458
  only_agentic,
459
+ only_entity_to_entity,
457
460
  )
458
461
 
459
462
 
@@ -462,6 +465,7 @@ def _merge_relations_results(
462
465
  query: EntitiesSubgraphRequest,
463
466
  only_with_metadata: bool,
464
467
  only_agentic: bool,
468
+ only_entity_to_entity: bool,
465
469
  ) -> Relations:
466
470
  """
467
471
  Merge relation search responses into a single Relations object while applying filters.
@@ -490,33 +494,41 @@ def _merge_relations_results(
490
494
  # If only_with_metadata is True, we check that metadata for the relation is not None
491
495
  # If only_agentic is True, we check that metadata for the relation is not None and that it has a data_augmentation_task_id
492
496
  # TODO: This is suboptimal, we should be able to filter this in the query to the index,
493
- if (not only_with_metadata or metadata) and (
494
- not only_agentic or (metadata and metadata.data_augmentation_task_id)
495
- ):
496
- if origin.value in relations.entities:
497
- relations.entities[origin.value].related_to.append(
498
- DirectionalRelation(
499
- entity=destination.value,
500
- entity_type=relation_node_type_to_entity_type(destination.ntype),
501
- entity_subtype=destination.subtype,
502
- relation=relation_type,
503
- relation_label=relation_label,
504
- direction=RelationDirection.OUT,
505
- metadata=from_proto.relation_metadata(metadata) if metadata else None,
506
- )
497
+ if only_with_metadata and not metadata:
498
+ continue
499
+
500
+ if only_agentic and (not metadata or not metadata.data_augmentation_task_id):
501
+ continue
502
+
503
+ if only_entity_to_entity and relation_type != RelationType.ENTITY:
504
+ continue
505
+
506
+ if origin.value in relations.entities:
507
+ relations.entities[origin.value].related_to.append(
508
+ DirectionalRelation(
509
+ entity=destination.value,
510
+ entity_type=relation_node_type_to_entity_type(destination.ntype),
511
+ entity_subtype=destination.subtype,
512
+ relation=relation_type,
513
+ relation_label=relation_label,
514
+ direction=RelationDirection.OUT,
515
+ metadata=from_proto.relation_metadata(metadata) if metadata else None,
516
+ resource_id=relation.resource_id,
507
517
  )
508
- elif destination.value in relations.entities:
509
- relations.entities[destination.value].related_to.append(
510
- DirectionalRelation(
511
- entity=origin.value,
512
- entity_type=relation_node_type_to_entity_type(origin.ntype),
513
- entity_subtype=origin.subtype,
514
- relation=relation_type,
515
- relation_label=relation_label,
516
- direction=RelationDirection.IN,
517
- metadata=from_proto.relation_metadata(metadata) if metadata else None,
518
- )
518
+ )
519
+ elif destination.value in relations.entities:
520
+ relations.entities[destination.value].related_to.append(
521
+ DirectionalRelation(
522
+ entity=origin.value,
523
+ entity_type=relation_node_type_to_entity_type(origin.ntype),
524
+ entity_subtype=origin.subtype,
525
+ relation=relation_type,
526
+ relation_label=relation_label,
527
+ direction=RelationDirection.IN,
528
+ metadata=from_proto.relation_metadata(metadata) if metadata else None,
529
+ resource_id=relation.resource_id,
519
530
  )
531
+ )
520
532
 
521
533
  return relations
522
534
 
@@ -17,13 +17,13 @@
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
19
  #
20
- from typing import Generic, Optional, Type
20
+ from typing import Generic, Type
21
21
 
22
- from nucliadb.common.context import ApplicationContext
23
22
  from nucliadb.tasks.logger import logger
24
23
  from nucliadb.tasks.models import MsgType
25
- from nucliadb.tasks.utils import NatsStream, create_nats_stream_if_not_exists
24
+ from nucliadb.tasks.utils import NatsStream
26
25
  from nucliadb_telemetry import errors
26
+ from nucliadb_utils.utilities import get_nats_manager
27
27
 
28
28
 
29
29
  class NatsTaskProducer(Generic[MsgType]):
@@ -38,29 +38,17 @@ class NatsTaskProducer(Generic[MsgType]):
38
38
  self.stream = stream
39
39
  self.producer_subject = producer_subject
40
40
  self.msg_type = msg_type
41
- self.context: Optional[ApplicationContext] = None
42
- self.initialized = False
43
-
44
- async def initialize(self, context: ApplicationContext):
45
- self.context = context
46
- await create_nats_stream_if_not_exists(
47
- self.context,
48
- self.stream.name,
49
- subjects=self.stream.subjects,
50
- )
51
- self.initialized = True
41
+ self.nats_manager = get_nats_manager()
52
42
 
53
43
  async def send(self, msg: MsgType) -> int:
54
44
  """
55
45
  Publish message to the producer's nats stream.
56
46
  Returns the sequence number of the published message.
57
47
  """
58
- if not self.initialized:
59
- raise RuntimeError("NatsTaskProducer not initialized")
60
48
  try:
61
- pub_ack = await self.context.nats_manager.js.publish( # type: ignore
49
+ pub_ack = await self.nats_manager.js.publish(
62
50
  self.producer_subject,
63
- msg.model_dump_json().encode("utf-8"), # type: ignore
51
+ msg.model_dump_json().encode("utf-8"),
64
52
  )
65
53
  logger.info(
66
54
  "Message sent to Nats",
@@ -195,7 +195,7 @@ async def start_export_task(context: ApplicationContext, kbid: str, export_id: s
195
195
  metadata.task.status = Status.SCHEDULED
196
196
  await dm.set_metadata("export", metadata)
197
197
  try:
198
- producer = await get_exports_producer(context)
198
+ producer = get_exports_producer()
199
199
  msg = NatsTaskMessage(kbid=kbid, id=export_id)
200
200
  seqid = await producer.send(msg)
201
201
  logger.info(f"Export task produced. seqid={seqid} kbid={kbid} export_id={export_id}")
@@ -212,7 +212,7 @@ async def start_import_task(context: ApplicationContext, kbid: str, import_id: s
212
212
  metadata.total = import_size or 0
213
213
  await dm.set_metadata("import", metadata)
214
214
  try:
215
- producer = await get_imports_producer(context)
215
+ producer = get_imports_producer()
216
216
  msg = NatsTaskMessage(kbid=kbid, id=import_id)
217
217
  seqid = await producer.send(msg)
218
218
  logger.info(f"Import task produced. seqid={seqid} kbid={kbid} import_id={import_id}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nucliadb
3
- Version: 6.3.1.post3570
3
+ Version: 6.3.1.post3574
4
4
  Summary: NucliaDB
5
5
  Author-email: Nuclia <nucliadb@nuclia.com>
6
6
  License: AGPL
@@ -20,11 +20,11 @@ Classifier: Programming Language :: Python :: 3.12
20
20
  Classifier: Programming Language :: Python :: 3 :: Only
21
21
  Requires-Python: <4,>=3.9
22
22
  Description-Content-Type: text/markdown
23
- Requires-Dist: nucliadb-telemetry[all]>=6.3.1.post3570
24
- Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.3.1.post3570
25
- Requires-Dist: nucliadb-protos>=6.3.1.post3570
26
- Requires-Dist: nucliadb-models>=6.3.1.post3570
27
- Requires-Dist: nidx-protos>=6.3.1.post3570
23
+ Requires-Dist: nucliadb-telemetry[all]>=6.3.1.post3574
24
+ Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.3.1.post3574
25
+ Requires-Dist: nucliadb-protos>=6.3.1.post3574
26
+ Requires-Dist: nucliadb-models>=6.3.1.post3574
27
+ Requires-Dist: nidx-protos>=6.3.1.post3574
28
28
  Requires-Dist: nucliadb-admin-assets>=1.0.0.post1224
29
29
  Requires-Dist: nuclia-models>=0.24.2
30
30
  Requires-Dist: uvicorn
@@ -108,7 +108,7 @@ nucliadb/export_import/exceptions.py,sha256=Dw8WqfG4r6MPJc5TPfbjMvCgXXWTcTOecGHR
108
108
  nucliadb/export_import/exporter.py,sha256=k2QVx1EjqFlDYiggriWiEJzwtMXzHbldsqWdpGQM3_U,7074
109
109
  nucliadb/export_import/importer.py,sha256=v5cq9Nn8c2zrY_K_00mydR52f8mdFxR7tLdtNLQ0qvk,4229
110
110
  nucliadb/export_import/models.py,sha256=dbjScNkiMRv4X3Ktudy1JRliD25bfoDTy3JmEZgQSCc,2121
111
- nucliadb/export_import/tasks.py,sha256=4JX3bygyLCLSuGxMCStYyoclh_CL8rPxrVVWuGqvcmM,3146
111
+ nucliadb/export_import/tasks.py,sha256=DWbdqY97ffoyfipelGXz3Jqz1iam6JCjQSh367Fc3NA,2947
112
112
  nucliadb/export_import/utils.py,sha256=iAQAjYuNx0dhM2b5-1A0NEs8tSRsznuT-izysUrTwS0,19986
113
113
  nucliadb/ingest/__init__.py,sha256=fsw3C38VP50km3R-nHL775LNGPpJ4JxqXJ2Ib1f5SqE,1011
114
114
  nucliadb/ingest/app.py,sha256=rX1KE5vsAzG9hlArBk8WE2SOlvdYylcb-jNkMQNPJdQ,7407
@@ -224,10 +224,10 @@ nucliadb/search/search/fetch.py,sha256=XJHIFnZmXM_8Kb37lb4lg1GYG7cZ1plT-qAIb_Qzi
224
224
  nucliadb/search/search/filters.py,sha256=1MkHlJjAQqoRCj7e5cEzK2HvBxGLE17I_omsjiklbtw,6476
225
225
  nucliadb/search/search/find.py,sha256=jQZOqu8VeX8k3ELV8bLK4TwUUjGrvmubouxvO1IvJV0,10236
226
226
  nucliadb/search/search/find_merge.py,sha256=3FnzKFEnVemg6FO_6zveulbAU7klvsiPEBvLrpBBMg8,17450
227
- nucliadb/search/search/graph_strategy.py,sha256=ahwcUTQZ0Ll-rnS285DO9PmRyiM-1p4BM3UvmOYVwhM,31750
227
+ nucliadb/search/search/graph_strategy.py,sha256=gisL2GpbSIa_SucyOwEt7TWdqURyAQqxvD_-PkXQct8,32339
228
228
  nucliadb/search/search/hydrator.py,sha256=-R37gCrGxkyaiHQalnTWHNG_FCx11Zucd7qA1vQCxuw,6985
229
229
  nucliadb/search/search/ingestion_agents.py,sha256=NeJr4EEX-bvFFMGvXOOwLv8uU7NuQ-ntJnnrhnKfMzY,3174
230
- nucliadb/search/search/merge.py,sha256=i_PTBFRqC5iTTziOMEltxLIlmokIou5hjjgR4BnoLBE,22635
230
+ nucliadb/search/search/merge.py,sha256=aUn6f5XnwWzUFhVC6uBqHE8NKdlfgw_xcTo57rS23U8,22950
231
231
  nucliadb/search/search/metrics.py,sha256=GGGtXHLhK79_ESV277xkBVjcaMURXHCxYG0EdGamUd8,2886
232
232
  nucliadb/search/search/paragraphs.py,sha256=pNAEiYqJGGUVcEf7xf-PFMVqz0PX4Qb-WNG-_zPGN2o,7799
233
233
  nucliadb/search/search/pgcatalog.py,sha256=V1NYLEUSXHpWmgcPIo1HS2riK_HDXSi-uykJjSoOOrE,9033
@@ -243,7 +243,7 @@ nucliadb/search/search/chat/ask.py,sha256=olZT08JVo3ZGDsDXkjvI2JTlqQln_o91HJzv0T
243
243
  nucliadb/search/search/chat/exceptions.py,sha256=Siy4GXW2L7oPhIR86H3WHBhE9lkV4A4YaAszuGGUf54,1356
244
244
  nucliadb/search/search/chat/images.py,sha256=PA8VWxT5_HUGfW1ULhKTK46UBsVyINtWWqEM1ulzX1E,3095
245
245
  nucliadb/search/search/chat/prompt.py,sha256=Jnja-Ss7skgnnDY8BymVfdeYsFPnIQFL8tEvcRXTKUE,47356
246
- nucliadb/search/search/chat/query.py,sha256=2QhVzvX12zLHOpVZ5MlBflqAauyCBl6dojhRGdm_6qU,16388
246
+ nucliadb/search/search/chat/query.py,sha256=0IoeW-JNaRBe2d9C3bXNfkYpzmsN_IIg3U4Vqb8eOEk,16485
247
247
  nucliadb/search/search/query_parser/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
248
248
  nucliadb/search/search/query_parser/catalog.py,sha256=PtH5nb6UTzH8l7Lmdd1RgLVFsn9CN5M5-JkVq9YeR4k,7116
249
249
  nucliadb/search/search/query_parser/exceptions.py,sha256=szAOXUZ27oNY-OSa9t2hQ5HHkQQC0EX1FZz_LluJHJE,1224
@@ -271,7 +271,7 @@ nucliadb/tasks/__init__.py,sha256=oFJ3A8HD7w11mBu-IixYE_KxA7juMGlYQb7YD_y6WPM,97
271
271
  nucliadb/tasks/consumer.py,sha256=xc0Ql3N1Iq52dJ3t4YYGJFj1NCQAly0J5W_brfLa_F8,6894
272
272
  nucliadb/tasks/logger.py,sha256=C7keOEO_mjLVp5VbqAZ2QXfqVB2Hot7NgBlUP_SDSMw,924
273
273
  nucliadb/tasks/models.py,sha256=qrZKi5DNDQ07waMsp5L4_Fi7WRs57YiO-kmXlrBzEAA,1168
274
- nucliadb/tasks/producer.py,sha256=JRGnATkALyr_iLHq0OAjzVbfxZ_SOUa6sx-smU5p6SQ,3136
274
+ nucliadb/tasks/producer.py,sha256=UnpJAzhj_GElsCoO5G6T4m6MshsgOaqR2tVzJmEta64,2625
275
275
  nucliadb/tasks/retries.py,sha256=Zv-3Hys-SKayG9VQ7_7EIflkegE5j-xPGrf-nwaxsfY,5075
276
276
  nucliadb/tasks/utils.py,sha256=tV1AbWdFc3qfIULX44Veqj41FCD1B6XYjG6brULBeiw,1459
277
277
  nucliadb/tests/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
@@ -322,7 +322,7 @@ nucliadb/writer/api/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20
322
322
  nucliadb/writer/api/constants.py,sha256=qWEDjFUycrEZnSJyLnNK4PQNodU2oVmkO4NycaEZtio,1738
323
323
  nucliadb/writer/api/utils.py,sha256=wIQHlU8RQiIGVLI72suvyVIKlCU44Unh0Ae0IiN6Qwo,1313
324
324
  nucliadb/writer/api/v1/__init__.py,sha256=akI9A_jloNLb0dU4T5zjfdyvmSAiDeIdjAlzNx74FlU,1128
325
- nucliadb/writer/api/v1/export_import.py,sha256=FxGY_rofj3AH-HQReoMDOYfEpACeWB5bsmxrT03QUtQ,8227
325
+ nucliadb/writer/api/v1/export_import.py,sha256=elf-EQY5DD3mhw8kWb9tQpDcbrF9sY6VFYqxQOjuVP0,8201
326
326
  nucliadb/writer/api/v1/field.py,sha256=OsWOYA0WQ6onE5Rkl20QIEdtrSi7Jgnu62fUt90Ziy8,17503
327
327
  nucliadb/writer/api/v1/knowledgebox.py,sha256=MLeIuym4jPrJgfy1NTcN9CpUGwuBiqDHMcx0hY9DR7g,9530
328
328
  nucliadb/writer/api/v1/learning_config.py,sha256=CKBjqcbewkfPwGUPLDWzZSpro6XkmCaVppe5Qtpu5Go,3117
@@ -347,8 +347,8 @@ nucliadb/writer/tus/local.py,sha256=7jYa_w9b-N90jWgN2sQKkNcomqn6JMVBOVeDOVYJHto,
347
347
  nucliadb/writer/tus/s3.py,sha256=vF0NkFTXiXhXq3bCVXXVV-ED38ECVoUeeYViP8uMqcU,8357
348
348
  nucliadb/writer/tus/storage.py,sha256=ToqwjoYnjI4oIcwzkhha_MPxi-k4Jk3Lt55zRwaC1SM,2903
349
349
  nucliadb/writer/tus/utils.py,sha256=MSdVbRsRSZVdkaum69_0wku7X3p5wlZf4nr6E0GMKbw,2556
350
- nucliadb-6.3.1.post3570.dist-info/METADATA,sha256=a5FFqexlq9oEflkrfSYCAW8j3sV62OJnY1LCgPtpbJg,4291
351
- nucliadb-6.3.1.post3570.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
352
- nucliadb-6.3.1.post3570.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
353
- nucliadb-6.3.1.post3570.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
354
- nucliadb-6.3.1.post3570.dist-info/RECORD,,
350
+ nucliadb-6.3.1.post3574.dist-info/METADATA,sha256=JiB_eKqj0pPsq4nf9VvqU9gm6CEEQkYvElBlLSISd7c,4291
351
+ nucliadb-6.3.1.post3574.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
352
+ nucliadb-6.3.1.post3574.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
353
+ nucliadb-6.3.1.post3574.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
354
+ nucliadb-6.3.1.post3574.dist-info/RECORD,,