nucliadb 6.2.1.post2777__py3-none-any.whl → 6.2.1.post2803__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.
@@ -146,6 +146,27 @@ class KnowledgeBox:
146
146
  kb_shards.actual = -1
147
147
 
148
148
  vs_external_indexes = []
149
+
150
+ # HACK! Currently, we share responsibility of deciding where to
151
+ # store extracted vectors with processing. Depending on whether
152
+ # it sends the vectorset id or not (in the extracted vectors
153
+ # wrapper) nucliadb will store the extracted vectors in a different place
154
+ #
155
+ # Right now, processing behaviour is not setting vectorset ids
156
+ # if there's only one semantic model configured. This is done
157
+ # for Bw/c with KBs previous to vectorsets.
158
+ #
159
+ # We now hardcode this assumption here, so we can annotate each
160
+ # vectorset with a mark and don't depend on processing
161
+ # information to decide the storage key. Once this is done we'll
162
+ # be able to force processing to always send vectorset ids and
163
+ # remove that bw/c behavior
164
+ #
165
+ if len(semantic_models) == 1:
166
+ storage_key_kind = knowledgebox_pb2.VectorSetConfig.StorageKeyKind.LEGACY
167
+ else:
168
+ storage_key_kind = knowledgebox_pb2.VectorSetConfig.StorageKeyKind.VECTORSET_PREFIX
169
+
149
170
  for vectorset_id, semantic_model in semantic_models.items(): # type: ignore
150
171
  # if this KB uses a matryoshka model, we can choose a different
151
172
  # dimension
@@ -172,6 +193,7 @@ class KnowledgeBox:
172
193
  vector_dimension=dimension,
173
194
  ),
174
195
  matryoshka_dimensions=semantic_model.matryoshka_dimensions,
196
+ storage_key_kind=storage_key_kind,
175
197
  )
176
198
  await datamanagers.vectorsets.set(txn, kbid=kbid, config=vectorset_config)
177
199
 
@@ -504,7 +504,6 @@ class Resource:
504
504
  @processor_observer.wrap({"type": "apply_fields"})
505
505
  async def apply_fields(self, message: BrokerMessage):
506
506
  message_updated_fields = []
507
-
508
507
  for field, text in message.texts.items():
509
508
  fid = FieldID(field_type=FieldType.TEXT, field=field)
510
509
  await self.set_field(fid.field_type, fid.field, text)
@@ -261,6 +261,7 @@ class ProcessingEngine:
261
261
  "content_type": file.file.content_type,
262
262
  "password": file.password,
263
263
  "language": file.language,
264
+ "extract_strategy": file.extract_strategy,
264
265
  }
265
266
  return jwt.encode(payload, self.nuclia_jwt_key, algorithm="HS256")
266
267
 
@@ -278,6 +279,8 @@ class ProcessingEngine:
278
279
  headers["X-LANGUAGE"] = file.language
279
280
  headers["X-FILENAME"] = base64.b64encode(file.file.filename.encode()).decode() # type: ignore
280
281
  headers["X-MD5"] = file.file.md5
282
+ if file.extract_strategy is not None:
283
+ headers["X-EXTRACT-STRATEGY"] = file.extract_strategy
281
284
  headers["CONTENT_TYPE"] = file.file.content_type
282
285
  headers["CONTENT-LENGTH"] = str(len(file.file.payload)) # type: ignore
283
286
  headers["X-STF-NUAKEY"] = f"Bearer {self.nuclia_service_account}"
@@ -317,6 +320,7 @@ class ProcessingEngine:
317
320
  "content_type": file_field.file.content_type,
318
321
  "language": file_field.language,
319
322
  "password": file_field.password,
323
+ "extract_strategy": file_field.extract_strategy,
320
324
  }
321
325
  return jwt.encode(payload, self.nuclia_jwt_key, algorithm="HS256")
322
326
 
@@ -341,6 +345,8 @@ class ProcessingEngine:
341
345
  headers["CONTENT-TYPE"] = file.file.content_type
342
346
  if file.file.size:
343
347
  headers["CONTENT-LENGTH"] = str(file.file.size)
348
+ if file.extract_strategy != "":
349
+ headers["X-EXTRACT-STRATEGY"] = file.extract_strategy
344
350
  headers["X-STF-NUAKEY"] = f"Bearer {self.nuclia_service_account}"
345
351
 
346
352
  iterator = storage.downloadbytescf_iterator(file.file)
@@ -23,7 +23,7 @@ import uuid
23
23
  from datetime import datetime
24
24
  from hashlib import md5
25
25
  from io import BytesIO
26
- from typing import Optional
26
+ from typing import Annotated, Optional
27
27
 
28
28
  from fastapi import HTTPException
29
29
  from fastapi.params import Header
@@ -82,6 +82,10 @@ TUS_HEADERS = {
82
82
  "Tus-Extension": "creation-defer-length",
83
83
  }
84
84
 
85
+ ExtractStrategyHeader = Header(
86
+ description="Extract strategy to use when uploading a file. If not provided, the default strategy will be used.",
87
+ )
88
+
85
89
 
86
90
  @api.options(
87
91
  f"/{KB_PREFIX}/{{kbid}}/{RSLUG_PREFIX}/{{rslug}}/file/{{field}}/{TUSUPLOAD}/{{upload_id}}",
@@ -142,9 +146,12 @@ async def tus_post_rslug_prefix(
142
146
  rslug: str,
143
147
  field: FieldIdString,
144
148
  item: Optional[CreateResourcePayload] = None,
149
+ x_extract_strategy: Annotated[Optional[str], ExtractStrategyHeader] = None,
145
150
  ) -> Response:
146
151
  rid = await get_rid_from_slug_or_raise_error(kbid, rslug)
147
- return await _tus_post(request, kbid, item, path_rid=rid, field_id=field)
152
+ return await _tus_post(
153
+ request, kbid, item, path_rid=rid, field_id=field, extract_strategy=x_extract_strategy
154
+ )
148
155
 
149
156
 
150
157
  @api.post(
@@ -161,8 +168,11 @@ async def tus_post_rid_prefix(
161
168
  path_rid: str,
162
169
  field: FieldIdString,
163
170
  item: Optional[CreateResourcePayload] = None,
171
+ x_extract_strategy: Annotated[Optional[str], ExtractStrategyHeader] = None,
164
172
  ) -> Response:
165
- return await _tus_post(request, kbid, item, path_rid=path_rid, field_id=field)
173
+ return await _tus_post(
174
+ request, kbid, item, path_rid=path_rid, field_id=field, extract_strategy=x_extract_strategy
175
+ )
166
176
 
167
177
 
168
178
  @api.post(
@@ -177,8 +187,9 @@ async def tus_post(
177
187
  request: Request,
178
188
  kbid: str,
179
189
  item: Optional[CreateResourcePayload] = None,
190
+ x_extract_strategy: Annotated[Optional[str], ExtractStrategyHeader] = None,
180
191
  ) -> Response:
181
- return await _tus_post(request, kbid, item)
192
+ return await _tus_post(request, kbid, item, extract_strategy=x_extract_strategy)
182
193
 
183
194
 
184
195
  # called by one the three POST above - there are defined distinctly to produce clean API doc
@@ -188,6 +199,7 @@ async def _tus_post(
188
199
  item: Optional[CreateResourcePayload] = None,
189
200
  path_rid: Optional[str] = None,
190
201
  field_id: Optional[str] = None,
202
+ extract_strategy: Optional[str] = None,
191
203
  ) -> Response:
192
204
  """
193
205
  An empty POST request is used to create a new upload resource.
@@ -285,6 +297,7 @@ async def _tus_post(
285
297
  deferred_length=deferred_length,
286
298
  offset=0,
287
299
  item=creation_payload,
300
+ extract_strategy=extract_strategy,
288
301
  )
289
302
 
290
303
  if size is not None:
@@ -569,6 +582,7 @@ async def _tus_patch(
569
582
  request=request,
570
583
  bucket=storage_manager.storage.get_bucket_name(kbid),
571
584
  item=creation_payload,
585
+ extract_strategy=dm.get("extract_strategy") or None,
572
586
  )
573
587
  except LimitsExceededError as exc:
574
588
  raise HTTPException(status_code=exc.status_code, detail=exc.detail)
@@ -606,6 +620,7 @@ async def upload_rslug_prefix(
606
620
  x_password: Optional[list[str]] = Header(None), # type: ignore
607
621
  x_language: Optional[list[str]] = Header(None), # type: ignore
608
622
  x_md5: Optional[list[str]] = Header(None), # type: ignore
623
+ x_extract_strategy: Annotated[Optional[str], ExtractStrategyHeader] = None,
609
624
  ) -> ResourceFileUploaded:
610
625
  rid = await get_rid_from_slug_or_raise_error(kbid, rslug)
611
626
  return await _upload(
@@ -617,6 +632,7 @@ async def upload_rslug_prefix(
617
632
  x_password=x_password,
618
633
  x_language=x_language,
619
634
  x_md5=x_md5,
635
+ x_extract_strategy=x_extract_strategy,
620
636
  )
621
637
 
622
638
 
@@ -638,6 +654,7 @@ async def upload_rid_prefix(
638
654
  x_password: Optional[list[str]] = Header(None), # type: ignore
639
655
  x_language: Optional[list[str]] = Header(None), # type: ignore
640
656
  x_md5: Optional[list[str]] = Header(None), # type: ignore
657
+ x_extract_strategy: Annotated[Optional[str], ExtractStrategyHeader] = None,
641
658
  ) -> ResourceFileUploaded:
642
659
  return await _upload(
643
660
  request,
@@ -648,6 +665,7 @@ async def upload_rid_prefix(
648
665
  x_password=x_password,
649
666
  x_language=x_language,
650
667
  x_md5=x_md5,
668
+ x_extract_strategy=x_extract_strategy,
651
669
  )
652
670
 
653
671
 
@@ -667,6 +685,7 @@ async def upload(
667
685
  x_password: Optional[list[str]] = Header(None), # type: ignore
668
686
  x_language: Optional[list[str]] = Header(None), # type: ignore
669
687
  x_md5: Optional[list[str]] = Header(None), # type: ignore
688
+ x_extract_strategy: Annotated[Optional[str], ExtractStrategyHeader] = None,
670
689
  ) -> ResourceFileUploaded:
671
690
  return await _upload(
672
691
  request,
@@ -675,6 +694,7 @@ async def upload(
675
694
  x_password=x_password,
676
695
  x_language=x_language,
677
696
  x_md5=x_md5,
697
+ x_extract_strategy=x_extract_strategy,
678
698
  )
679
699
 
680
700
 
@@ -688,6 +708,7 @@ async def _upload(
688
708
  x_password: Optional[list[str]] = Header(None), # type: ignore
689
709
  x_language: Optional[list[str]] = Header(None), # type: ignore
690
710
  x_md5: Optional[list[str]] = Header(None), # type: ignore
711
+ x_extract_strategy: Optional[str] = None,
691
712
  ) -> ResourceFileUploaded:
692
713
  if path_rid is not None:
693
714
  await validate_rid_exists_or_raise_error(kbid, path_rid)
@@ -781,6 +802,7 @@ async def _upload(
781
802
  path=path,
782
803
  request=request,
783
804
  bucket=storage_manager.storage.get_bucket_name(kbid),
805
+ extract_strategy=x_extract_strategy,
784
806
  )
785
807
  except LimitsExceededError as exc:
786
808
  raise HTTPException(status_code=exc.status_code, detail=exc.detail)
@@ -840,6 +862,7 @@ async def store_file_on_nuclia_db(
840
862
  language: Optional[str] = None,
841
863
  md5: Optional[str] = None,
842
864
  item: Optional[CreateResourcePayload] = None,
865
+ extract_strategy: Optional[str] = None,
843
866
  ) -> Optional[int]:
844
867
  # File is on NucliaDB Storage at path
845
868
  partitioning = get_partitioning()
@@ -921,6 +944,8 @@ async def store_file_on_nuclia_db(
921
944
  file_field.language = language
922
945
  if password:
923
946
  file_field.password = password
947
+ if extract_strategy is not None:
948
+ file_field.extract_strategy = extract_strategy
924
949
 
925
950
  writer.files[field].CopyFrom(file_field)
926
951
  # Do not store passwords on maindb
@@ -50,6 +50,7 @@ async def extract_file_field_from_pb(field_pb: resources_pb2.FieldFile) -> str:
50
50
  language=field_pb.language,
51
51
  password=field_pb.password,
52
52
  file=models.File(payload=None, uri=field_pb.file.uri),
53
+ extract_strategy=field_pb.extract_strategy,
53
54
  )
54
55
  return processing.convert_external_filefield_to_str(file_field)
55
56
  else:
@@ -171,6 +172,8 @@ def parse_text_field(
171
172
  writer: BrokerMessage,
172
173
  toprocess: PushPayload,
173
174
  ) -> None:
175
+ if text_field.extract_strategy is not None:
176
+ writer.texts[key].extract_strategy = text_field.extract_strategy
174
177
  writer.texts[key].body = text_field.body
175
178
  writer.texts[key].format = resources_pb2.FieldText.Format.Value(text_field.format.value)
176
179
  etw = resources_pb2.ExtractedTextWrapper()
@@ -181,6 +184,7 @@ def parse_text_field(
181
184
  toprocess.textfield[key] = models.Text(
182
185
  body=text_field.body,
183
186
  format=getattr(models.PushTextFormat, text_field.format.value),
187
+ extract_strategy=text_field.extract_strategy,
184
188
  )
185
189
 
186
190
 
@@ -213,6 +217,8 @@ async def parse_internal_file_field(
213
217
  writer.files[key].added.FromDatetime(datetime.now())
214
218
  if file_field.language:
215
219
  writer.files[key].language = file_field.language
220
+ if file_field.extract_strategy is not None:
221
+ writer.files[key].extract_strategy = file_field.extract_strategy
216
222
 
217
223
  processing = get_processing()
218
224
 
@@ -248,6 +254,8 @@ def parse_external_file_field(
248
254
  writer.files[key].added.FromDatetime(datetime.now())
249
255
  if file_field.language:
250
256
  writer.files[key].language = file_field.language
257
+ if file_field.extract_strategy is not None:
258
+ writer.files[key].extract_strategy = file_field.extract_strategy
251
259
  uri = file_field.file.uri
252
260
  writer.files[key].url = uri # type: ignore
253
261
  writer.files[key].file.uri = uri # type: ignore
@@ -290,6 +298,9 @@ def parse_link_field(
290
298
  if link_field.xpath is not None:
291
299
  writer.links[key].xpath = link_field.xpath
292
300
 
301
+ if link_field.extract_strategy is not None:
302
+ writer.links[key].extract_strategy = link_field.extract_strategy
303
+
293
304
  toprocess.linkfield[key] = models.LinkUpload(
294
305
  link=link_field.uri,
295
306
  headers=link_field.headers or {},
@@ -297,6 +308,7 @@ def parse_link_field(
297
308
  localstorage=link_field.localstorage or {},
298
309
  css_selector=link_field.css_selector,
299
310
  xpath=link_field.xpath,
311
+ extract_strategy=link_field.extract_strategy,
300
312
  )
301
313
 
302
314
 
@@ -310,7 +322,6 @@ async def parse_conversation_field(
310
322
  ) -> None:
311
323
  storage = await get_storage(service_name=SERVICE_NAME)
312
324
  processing = get_processing()
313
-
314
325
  field_value = resources_pb2.Conversation()
315
326
  convs = models.PushConversation()
316
327
  for message in conversation_field.messages:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nucliadb
3
- Version: 6.2.1.post2777
3
+ Version: 6.2.1.post2803
4
4
  Home-page: https://docs.nuclia.dev/docs/management/nucliadb/intro
5
5
  Author: NucliaDB Community
6
6
  Author-email: nucliadb@nuclia.com
@@ -22,10 +22,10 @@ Classifier: Programming Language :: Python :: 3.12
22
22
  Classifier: Programming Language :: Python :: 3 :: Only
23
23
  Requires-Python: >=3.9, <4
24
24
  Description-Content-Type: text/markdown
25
- Requires-Dist: nucliadb-telemetry[all]>=6.2.1.post2777
26
- Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.2.1.post2777
27
- Requires-Dist: nucliadb-protos>=6.2.1.post2777
28
- Requires-Dist: nucliadb-models>=6.2.1.post2777
25
+ Requires-Dist: nucliadb-telemetry[all]>=6.2.1.post2803
26
+ Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.2.1.post2803
27
+ Requires-Dist: nucliadb-protos>=6.2.1.post2803
28
+ Requires-Dist: nucliadb-models>=6.2.1.post2803
29
29
  Requires-Dist: nucliadb-admin-assets>=1.0.0.post1224
30
30
  Requires-Dist: nucliadb-node-binding>=2.26.0
31
31
  Requires-Dist: nuclia-models>=0.24.2
@@ -111,7 +111,7 @@ nucliadb/ingest/__init__.py,sha256=fsw3C38VP50km3R-nHL775LNGPpJ4JxqXJ2Ib1f5SqE,1
111
111
  nucliadb/ingest/app.py,sha256=L8MDbURnSdD6yI4yCnSbmnNccsnha-zJEkKSaGk1xMg,7612
112
112
  nucliadb/ingest/cache.py,sha256=w7jMMzamOmQ7gwXna6Dqm6isRNBVv6l5BTBlTxaYWjE,1005
113
113
  nucliadb/ingest/partitions.py,sha256=2NIhMYbNT0TNBL6bX1UMSi7vxFGICstCKEqsB0TXHOE,2410
114
- nucliadb/ingest/processing.py,sha256=0iWEgJVdcOHudwY8Uz9vXRdDoUznM3_WGmviY8FQWT0,20276
114
+ nucliadb/ingest/processing.py,sha256=gg1DqbMFwqdOsmCSGsZc2abRdYz86xOZJun9vrHOCzs,20618
115
115
  nucliadb/ingest/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
116
116
  nucliadb/ingest/serialize.py,sha256=l2cIIHgo0rgkbaYvAY5slzjr8keVo_3Vb3B6DI120IY,15272
117
117
  nucliadb/ingest/settings.py,sha256=0B-wQNa8FLqtNcQgRzh-fuIuGptM816XHcbH1NQKfmE,3050
@@ -138,9 +138,9 @@ nucliadb/ingest/orm/brain.py,sha256=Hzq-3aarKaUCiUoa8H83unRUfduRE9TsQH1dEq0mvZY,
138
138
  nucliadb/ingest/orm/broker_message.py,sha256=JYYUJIZEL_EqovQuw6u-FmEkjyoYlxIXJq9hFekOiks,6441
139
139
  nucliadb/ingest/orm/entities.py,sha256=2PslT1FZ6yCvJtjR0UpKTSzxJrtS-C_gZx4ZTWHunTc,15759
140
140
  nucliadb/ingest/orm/exceptions.py,sha256=k4Esv4NtL4TrGTcsQpwrSfDhPQpiYcRbB1SpYmBX5MY,1432
141
- nucliadb/ingest/orm/knowledgebox.py,sha256=dBetjoJBYT6JuGmMHiqjcfJeD8qJrK3MQt9X03IrHRA,23228
141
+ nucliadb/ingest/orm/knowledgebox.py,sha256=UpWJrVaVfCtk8R4qfSR6h6vzwOKXa8Teuwkna5QSljE,24508
142
142
  nucliadb/ingest/orm/metrics.py,sha256=OkwMSPKLZcKba0ZTwtTiIxwBgaLMX5ydhGieKvi2y7E,1096
143
- nucliadb/ingest/orm/resource.py,sha256=uqX50Cp74BaysV9duMuRvnAkeWBqNelYszXBiyTc0uE,55728
143
+ nucliadb/ingest/orm/resource.py,sha256=FIC7Tzef_0hoN92tFwN8PUi8IHlUkyifPJxsA1_XumM,55727
144
144
  nucliadb/ingest/orm/utils.py,sha256=vCe_9UxHu26JDFGLwQ0wH-XyzJIpQCTK-Ow9dtZR5Vg,2716
145
145
  nucliadb/ingest/orm/processor/__init__.py,sha256=Aqd9wCNTvggkMkCY3WvoI8spdr94Jnqk-0iq9XpLs18,922
146
146
  nucliadb/ingest/orm/processor/auditing.py,sha256=TeYhXGJRyQ7ROytbb2u8R0fIh_FYi3HgTu3S1ribY3U,4623
@@ -320,11 +320,11 @@ nucliadb/writer/api/v1/router.py,sha256=RjuoWLpZer6Kl2BW_wznpNo6XL3BOpdTGqXZCn3Q
320
320
  nucliadb/writer/api/v1/services.py,sha256=U8OGxhA1tdt-wxw2uDAjFpwFXFEXSDTfBe1iV5nfmx8,9897
321
321
  nucliadb/writer/api/v1/slug.py,sha256=xlVBDBpRi9bNulpBHZwhyftVvulfE0zFm1XZIWl-AKY,2389
322
322
  nucliadb/writer/api/v1/transaction.py,sha256=d2Vbgnkk_-FLGSTt3vfldwiJIUf0XoyD0wP1jQNz_DY,2430
323
- nucliadb/writer/api/v1/upload.py,sha256=8M_Hwt25sRnQvk8w71QqCBMZYgUZ9xRnLu6-fIaO9Ow,32065
323
+ nucliadb/writer/api/v1/upload.py,sha256=q2_YmQBz6MyFfX4xPHNLMwO0BvHdCFOewi9dlGg0Cq8,33384
324
324
  nucliadb/writer/resource/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
325
325
  nucliadb/writer/resource/audit.py,sha256=FvxMZPzrNHtd31HgpZEvxzwAkbxJTZRhPLqRYYJi3tA,1426
326
326
  nucliadb/writer/resource/basic.py,sha256=l9zD-Qiq4eUkHezMf0w1Ksx2izKYLYuNoMIlXcNxxpM,11163
327
- nucliadb/writer/resource/field.py,sha256=N2TDSMxOhCvrrUicFZMXfkCP_4zq9nQrubGAKom5PYg,13953
327
+ nucliadb/writer/resource/field.py,sha256=sh4BrewJrPKAajA7jx3dcnm3UB0L7FKbLueBWnpxq9I,14601
328
328
  nucliadb/writer/resource/origin.py,sha256=pvhUDdU0mlWPUcpoQi4LDUJaRtfjzVVrA8XcGVI_N8k,2021
329
329
  nucliadb/writer/tus/__init__.py,sha256=huWpKnDnjsrKlBBJk30ta5vamlA-4x0TbPs_2Up8hyM,5443
330
330
  nucliadb/writer/tus/azure.py,sha256=XhWAlWTM0vmXcXtuEPYjjeEhuZjiZXZu8q9WsJ7omFE,4107
@@ -335,9 +335,9 @@ nucliadb/writer/tus/local.py,sha256=7jYa_w9b-N90jWgN2sQKkNcomqn6JMVBOVeDOVYJHto,
335
335
  nucliadb/writer/tus/s3.py,sha256=vF0NkFTXiXhXq3bCVXXVV-ED38ECVoUeeYViP8uMqcU,8357
336
336
  nucliadb/writer/tus/storage.py,sha256=ToqwjoYnjI4oIcwzkhha_MPxi-k4Jk3Lt55zRwaC1SM,2903
337
337
  nucliadb/writer/tus/utils.py,sha256=MSdVbRsRSZVdkaum69_0wku7X3p5wlZf4nr6E0GMKbw,2556
338
- nucliadb-6.2.1.post2777.dist-info/METADATA,sha256=oVR3xzLObP57xg2Fi4Xhy4MvhyP-pdGWYAh3LE0fR1w,4689
339
- nucliadb-6.2.1.post2777.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
340
- nucliadb-6.2.1.post2777.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
341
- nucliadb-6.2.1.post2777.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
342
- nucliadb-6.2.1.post2777.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
343
- nucliadb-6.2.1.post2777.dist-info/RECORD,,
338
+ nucliadb-6.2.1.post2803.dist-info/METADATA,sha256=NZ6FUiG4RGSNyA919ez19edmW1geeUPg9AIFVSRrt4k,4689
339
+ nucliadb-6.2.1.post2803.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
340
+ nucliadb-6.2.1.post2803.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
341
+ nucliadb-6.2.1.post2803.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
342
+ nucliadb-6.2.1.post2803.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
343
+ nucliadb-6.2.1.post2803.dist-info/RECORD,,