nucliadb 6.2.0.post2675__py3-none-any.whl → 6.2.1__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.
- migrations/0028_extracted_vectors_reference.py +61 -0
- migrations/0029_backfill_field_status.py +149 -0
- migrations/0030_label_deduplication.py +60 -0
- nucliadb/common/cluster/manager.py +41 -331
- nucliadb/common/cluster/rebalance.py +2 -2
- nucliadb/common/cluster/rollover.py +12 -71
- nucliadb/common/cluster/settings.py +3 -0
- nucliadb/common/cluster/standalone/utils.py +0 -43
- nucliadb/common/cluster/utils.py +0 -16
- nucliadb/common/counters.py +1 -0
- nucliadb/common/datamanagers/fields.py +48 -7
- nucliadb/common/datamanagers/vectorsets.py +11 -2
- nucliadb/common/external_index_providers/base.py +2 -1
- nucliadb/common/external_index_providers/pinecone.py +3 -5
- nucliadb/common/ids.py +18 -4
- nucliadb/common/models_utils/from_proto.py +479 -0
- nucliadb/common/models_utils/to_proto.py +60 -0
- nucliadb/common/nidx.py +76 -37
- nucliadb/export_import/models.py +3 -3
- nucliadb/health.py +0 -7
- nucliadb/ingest/app.py +0 -8
- nucliadb/ingest/consumer/auditing.py +1 -1
- nucliadb/ingest/consumer/shard_creator.py +1 -1
- nucliadb/ingest/fields/base.py +83 -21
- nucliadb/ingest/orm/brain.py +55 -56
- nucliadb/ingest/orm/broker_message.py +12 -2
- nucliadb/ingest/orm/entities.py +6 -17
- nucliadb/ingest/orm/knowledgebox.py +44 -22
- nucliadb/ingest/orm/processor/data_augmentation.py +7 -29
- nucliadb/ingest/orm/processor/processor.py +5 -2
- nucliadb/ingest/orm/resource.py +222 -413
- nucliadb/ingest/processing.py +8 -2
- nucliadb/ingest/serialize.py +77 -46
- nucliadb/ingest/service/writer.py +2 -56
- nucliadb/ingest/settings.py +1 -4
- nucliadb/learning_proxy.py +6 -4
- nucliadb/purge/__init__.py +102 -12
- nucliadb/purge/orphan_shards.py +6 -4
- nucliadb/reader/api/models.py +3 -3
- nucliadb/reader/api/v1/__init__.py +1 -0
- nucliadb/reader/api/v1/download.py +2 -2
- nucliadb/reader/api/v1/knowledgebox.py +3 -3
- nucliadb/reader/api/v1/resource.py +23 -12
- nucliadb/reader/api/v1/services.py +4 -4
- nucliadb/reader/api/v1/vectorsets.py +48 -0
- nucliadb/search/api/v1/ask.py +11 -1
- nucliadb/search/api/v1/feedback.py +3 -3
- nucliadb/search/api/v1/knowledgebox.py +8 -13
- nucliadb/search/api/v1/search.py +3 -2
- nucliadb/search/api/v1/suggest.py +0 -2
- nucliadb/search/predict.py +6 -4
- nucliadb/search/requesters/utils.py +1 -2
- nucliadb/search/search/chat/ask.py +77 -13
- nucliadb/search/search/chat/prompt.py +16 -5
- nucliadb/search/search/chat/query.py +74 -34
- nucliadb/search/search/exceptions.py +2 -7
- nucliadb/search/search/find.py +9 -5
- nucliadb/search/search/find_merge.py +10 -4
- nucliadb/search/search/graph_strategy.py +884 -0
- nucliadb/search/search/hydrator.py +6 -0
- nucliadb/search/search/merge.py +79 -24
- nucliadb/search/search/query.py +74 -245
- nucliadb/search/search/query_parser/exceptions.py +11 -1
- nucliadb/search/search/query_parser/fetcher.py +405 -0
- nucliadb/search/search/query_parser/models.py +0 -3
- nucliadb/search/search/query_parser/parser.py +22 -21
- nucliadb/search/search/rerankers.py +1 -42
- nucliadb/search/search/shards.py +19 -0
- nucliadb/standalone/api_router.py +2 -14
- nucliadb/standalone/settings.py +4 -0
- nucliadb/train/generators/field_streaming.py +7 -3
- nucliadb/train/lifecycle.py +3 -6
- nucliadb/train/nodes.py +14 -12
- nucliadb/train/resource.py +380 -0
- nucliadb/writer/api/constants.py +20 -16
- nucliadb/writer/api/v1/__init__.py +1 -0
- nucliadb/writer/api/v1/export_import.py +1 -1
- nucliadb/writer/api/v1/field.py +13 -7
- nucliadb/writer/api/v1/knowledgebox.py +3 -46
- nucliadb/writer/api/v1/resource.py +20 -13
- nucliadb/writer/api/v1/services.py +10 -1
- nucliadb/writer/api/v1/upload.py +61 -34
- nucliadb/writer/{vectorsets.py → api/v1/vectorsets.py} +99 -47
- nucliadb/writer/back_pressure.py +17 -46
- nucliadb/writer/resource/basic.py +9 -7
- nucliadb/writer/resource/field.py +42 -9
- nucliadb/writer/settings.py +2 -2
- nucliadb/writer/tus/gcs.py +11 -10
- {nucliadb-6.2.0.post2675.dist-info → nucliadb-6.2.1.dist-info}/METADATA +11 -14
- {nucliadb-6.2.0.post2675.dist-info → nucliadb-6.2.1.dist-info}/RECORD +94 -96
- {nucliadb-6.2.0.post2675.dist-info → nucliadb-6.2.1.dist-info}/WHEEL +1 -1
- nucliadb/common/cluster/discovery/base.py +0 -178
- nucliadb/common/cluster/discovery/k8s.py +0 -301
- nucliadb/common/cluster/discovery/manual.py +0 -57
- nucliadb/common/cluster/discovery/single.py +0 -51
- nucliadb/common/cluster/discovery/types.py +0 -32
- nucliadb/common/cluster/discovery/utils.py +0 -67
- nucliadb/common/cluster/standalone/grpc_node_binding.py +0 -349
- nucliadb/common/cluster/standalone/index_node.py +0 -123
- nucliadb/common/cluster/standalone/service.py +0 -84
- nucliadb/standalone/introspect.py +0 -208
- nucliadb-6.2.0.post2675.dist-info/zip-safe +0 -1
- /nucliadb/common/{cluster/discovery → models_utils}/__init__.py +0 -0
- {nucliadb-6.2.0.post2675.dist-info → nucliadb-6.2.1.dist-info}/entry_points.txt +0 -0
- {nucliadb-6.2.0.post2675.dist-info → nucliadb-6.2.1.dist-info}/top_level.txt +0 -0
nucliadb/writer/back_pressure.py
CHANGED
@@ -30,7 +30,6 @@ from cachetools import TTLCache
|
|
30
30
|
from fastapi import HTTPException, Request
|
31
31
|
|
32
32
|
from nucliadb.common import datamanagers
|
33
|
-
from nucliadb.common.cluster.manager import get_index_nodes
|
34
33
|
from nucliadb.common.context import ApplicationContext
|
35
34
|
from nucliadb.common.context.fastapi import get_app_context
|
36
35
|
from nucliadb.common.http_clients.processing import ProcessingHTTPClient
|
@@ -168,7 +167,7 @@ class Materializer:
|
|
168
167
|
self.ingest_check_interval = ingest_check_interval
|
169
168
|
|
170
169
|
self.ingest_pending: int = 0
|
171
|
-
self.indexing_pending:
|
170
|
+
self.indexing_pending: int = 0
|
172
171
|
|
173
172
|
self._tasks: list[asyncio.Task] = []
|
174
173
|
self._running = False
|
@@ -232,7 +231,7 @@ class Materializer:
|
|
232
231
|
response = await self.processing_http_client.stats(kbid=kbid, timeout=0.5)
|
233
232
|
return response.incomplete
|
234
233
|
|
235
|
-
def get_indexing_pending(self) ->
|
234
|
+
def get_indexing_pending(self) -> int:
|
236
235
|
return self.indexing_pending
|
237
236
|
|
238
237
|
def get_ingest_pending(self) -> int:
|
@@ -241,20 +240,18 @@ class Materializer:
|
|
241
240
|
async def _get_indexing_pending_task(self):
|
242
241
|
try:
|
243
242
|
while True:
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
self.
|
248
|
-
|
249
|
-
|
250
|
-
consumer=const.Streams.INDEX.group.format(node=node.id),
|
251
|
-
)
|
252
|
-
except Exception:
|
253
|
-
logger.exception(
|
254
|
-
"Error getting pending messages to index",
|
255
|
-
exc_info=True,
|
256
|
-
extra={"node_id": node.id},
|
243
|
+
try:
|
244
|
+
with back_pressure_observer({"type": "get_indexing_pending"}):
|
245
|
+
self.indexing_pending = await get_nats_consumer_pending_messages(
|
246
|
+
self.nats_manager,
|
247
|
+
stream="nidx",
|
248
|
+
consumer="nidx",
|
257
249
|
)
|
250
|
+
except Exception:
|
251
|
+
logger.exception(
|
252
|
+
"Error getting pending messages to index",
|
253
|
+
exc_info=True,
|
254
|
+
)
|
258
255
|
await asyncio.sleep(self.indexing_check_interval)
|
259
256
|
except asyncio.CancelledError:
|
260
257
|
pass
|
@@ -386,7 +383,7 @@ async def check_indexing_behind(
|
|
386
383
|
context: ApplicationContext,
|
387
384
|
kbid: str,
|
388
385
|
resource_uuid: Optional[str],
|
389
|
-
|
386
|
+
pending: int,
|
390
387
|
):
|
391
388
|
"""
|
392
389
|
If a resource uuid is provided, it will check the nodes that have the replicas
|
@@ -398,36 +395,10 @@ async def check_indexing_behind(
|
|
398
395
|
# Indexing back pressure is disabled
|
399
396
|
return
|
400
397
|
|
401
|
-
if
|
402
|
-
logger.warning("No nodes found to check for pending messages")
|
403
|
-
return
|
404
|
-
|
405
|
-
# Get nodes that are involved in the indexing of the request
|
406
|
-
if resource_uuid is not None:
|
407
|
-
nodes_to_check = await get_nodes_for_resource_shard(context, kbid, resource_uuid)
|
408
|
-
else:
|
409
|
-
nodes_to_check = await get_nodes_for_kb_active_shards(context, kbid)
|
410
|
-
|
411
|
-
if len(nodes_to_check) == 0:
|
412
|
-
logger.warning(
|
413
|
-
"No nodes found to check for pending messages",
|
414
|
-
extra={"kbid": kbid, "resource_uuid": resource_uuid},
|
415
|
-
)
|
416
|
-
return
|
417
|
-
|
418
|
-
# Get the highest pending value
|
419
|
-
highest_pending = 0
|
420
|
-
for node in nodes_to_check:
|
421
|
-
if node not in pending_by_node:
|
422
|
-
logger.warning("Node not found in pending messages", extra={"node": node})
|
423
|
-
continue
|
424
|
-
if pending_by_node[node] > highest_pending:
|
425
|
-
highest_pending = pending_by_node[node]
|
426
|
-
|
427
|
-
if highest_pending > max_pending:
|
398
|
+
if pending > max_pending:
|
428
399
|
try_after = estimate_try_after(
|
429
400
|
rate=settings.indexing_rate,
|
430
|
-
pending=
|
401
|
+
pending=pending,
|
431
402
|
max_wait=settings.max_wait_time,
|
432
403
|
)
|
433
404
|
data = BackPressureData(type="indexing", try_after=try_after)
|
@@ -437,7 +408,7 @@ async def check_indexing_behind(
|
|
437
408
|
"kbid": kbid,
|
438
409
|
"resource_uuid": resource_uuid,
|
439
410
|
"try_after": try_after,
|
440
|
-
"pending":
|
411
|
+
"pending": pending,
|
441
412
|
},
|
442
413
|
)
|
443
414
|
raise BackPressureException(data)
|
@@ -22,17 +22,19 @@ from typing import Optional
|
|
22
22
|
|
23
23
|
from fastapi import HTTPException
|
24
24
|
|
25
|
+
from nucliadb.common.models_utils import to_proto
|
26
|
+
from nucliadb.common.models_utils.from_proto import (
|
27
|
+
RelationNodeTypeMap,
|
28
|
+
RelationTypeMap,
|
29
|
+
)
|
25
30
|
from nucliadb.ingest.orm.utils import set_title
|
26
31
|
from nucliadb.ingest.processing import PushPayload
|
27
|
-
from nucliadb_models.common import FIELD_TYPES_MAP_REVERSE
|
28
32
|
from nucliadb_models.content_types import GENERIC_MIME_TYPE
|
29
33
|
from nucliadb_models.file import FileField
|
30
34
|
from nucliadb_models.link import LinkField
|
31
35
|
from nucliadb_models.metadata import (
|
32
36
|
ParagraphAnnotation,
|
33
37
|
QuestionAnswerAnnotation,
|
34
|
-
RelationNodeTypeMap,
|
35
|
-
RelationTypeMap,
|
36
38
|
)
|
37
39
|
from nucliadb_models.text import TEXT_FORMAT_TO_MIMETYPE, PushTextFormat, Text
|
38
40
|
from nucliadb_models.writer import (
|
@@ -93,7 +95,8 @@ def parse_basic_modify(bm: BrokerMessage, item: ComingResourcePayload, toprocess
|
|
93
95
|
if item.metadata.language:
|
94
96
|
bm.basic.metadata.language = item.metadata.language
|
95
97
|
if item.metadata.languages:
|
96
|
-
|
98
|
+
unique_languages = list(set(item.metadata.languages))
|
99
|
+
bm.basic.metadata.languages.extend(unique_languages)
|
97
100
|
|
98
101
|
if item.fieldmetadata is not None:
|
99
102
|
for fieldmetadata in item.fieldmetadata:
|
@@ -144,9 +147,8 @@ def parse_basic_modify(bm: BrokerMessage, item: ComingResourcePayload, toprocess
|
|
144
147
|
userfieldmetadata.question_answers.append(qa_annotation_pb)
|
145
148
|
|
146
149
|
userfieldmetadata.field.field = fieldmetadata.field.field
|
147
|
-
|
148
|
-
|
149
|
-
]
|
150
|
+
|
151
|
+
userfieldmetadata.field.field_type = to_proto.field_type(fieldmetadata.field.field_type)
|
150
152
|
|
151
153
|
bm.basic.fieldmetadata.append(userfieldmetadata)
|
152
154
|
|
@@ -23,16 +23,13 @@ from typing import Optional, Union
|
|
23
23
|
from google.protobuf.json_format import MessageToDict
|
24
24
|
|
25
25
|
import nucliadb_models as models
|
26
|
+
from nucliadb.common.models_utils import from_proto, to_proto
|
26
27
|
from nucliadb.ingest.fields.conversation import Conversation
|
27
28
|
from nucliadb.ingest.orm.resource import Resource as ORMResource
|
28
29
|
from nucliadb.ingest.processing import PushPayload
|
29
30
|
from nucliadb.writer import SERVICE_NAME
|
30
31
|
from nucliadb.writer.utilities import get_processing
|
31
|
-
from nucliadb_models.common import
|
32
|
-
FIELD_TYPES_MAP,
|
33
|
-
FIELD_TYPES_MAP_REVERSE,
|
34
|
-
FieldTypeName,
|
35
|
-
)
|
32
|
+
from nucliadb_models.common import FieldTypeName
|
36
33
|
from nucliadb_models.content_types import GENERIC_MIME_TYPE
|
37
34
|
from nucliadb_models.conversation import PushConversation
|
38
35
|
from nucliadb_models.writer import (
|
@@ -40,7 +37,7 @@ from nucliadb_models.writer import (
|
|
40
37
|
UpdateResourcePayload,
|
41
38
|
)
|
42
39
|
from nucliadb_protos import resources_pb2
|
43
|
-
from nucliadb_protos.writer_pb2 import BrokerMessage
|
40
|
+
from nucliadb_protos.writer_pb2 import BrokerMessage, FieldIDStatus, FieldStatus
|
44
41
|
from nucliadb_utils.storages.storage import StorageField
|
45
42
|
from nucliadb_utils.utilities import get_storage
|
46
43
|
|
@@ -53,6 +50,7 @@ async def extract_file_field_from_pb(field_pb: resources_pb2.FieldFile) -> str:
|
|
53
50
|
language=field_pb.language,
|
54
51
|
password=field_pb.password,
|
55
52
|
file=models.File(payload=None, uri=field_pb.file.uri),
|
53
|
+
extract_strategy=field_pb.extract_strategy,
|
56
54
|
)
|
57
55
|
return processing.convert_external_filefield_to_str(file_field)
|
58
56
|
else:
|
@@ -83,7 +81,7 @@ async def extract_fields(resource: ORMResource, toprocess: PushPayload):
|
|
83
81
|
storage = await get_storage(service_name=SERVICE_NAME)
|
84
82
|
await resource.get_fields()
|
85
83
|
for (field_type, field_id), field in resource.fields.items():
|
86
|
-
field_type_name =
|
84
|
+
field_type_name = from_proto.field_type_name(field_type)
|
87
85
|
|
88
86
|
if field_type_name not in {
|
89
87
|
FieldTypeName.TEXT,
|
@@ -174,6 +172,8 @@ def parse_text_field(
|
|
174
172
|
writer: BrokerMessage,
|
175
173
|
toprocess: PushPayload,
|
176
174
|
) -> None:
|
175
|
+
if text_field.extract_strategy is not None:
|
176
|
+
writer.texts[key].extract_strategy = text_field.extract_strategy
|
177
177
|
writer.texts[key].body = text_field.body
|
178
178
|
writer.texts[key].format = resources_pb2.FieldText.Format.Value(text_field.format.value)
|
179
179
|
etw = resources_pb2.ExtractedTextWrapper()
|
@@ -184,6 +184,13 @@ def parse_text_field(
|
|
184
184
|
toprocess.textfield[key] = models.Text(
|
185
185
|
body=text_field.body,
|
186
186
|
format=getattr(models.PushTextFormat, text_field.format.value),
|
187
|
+
extract_strategy=text_field.extract_strategy,
|
188
|
+
)
|
189
|
+
writer.field_statuses.append(
|
190
|
+
FieldIDStatus(
|
191
|
+
id=resources_pb2.FieldID(field_type=resources_pb2.FieldType.TEXT, field=key),
|
192
|
+
status=FieldStatus.Status.PENDING,
|
193
|
+
)
|
187
194
|
)
|
188
195
|
|
189
196
|
|
@@ -203,6 +210,13 @@ async def parse_file_field(
|
|
203
210
|
key, file_field, writer, toprocess, kbid, uuid, skip_store=skip_store
|
204
211
|
)
|
205
212
|
|
213
|
+
writer.field_statuses.append(
|
214
|
+
FieldIDStatus(
|
215
|
+
id=resources_pb2.FieldID(field_type=resources_pb2.FieldType.FILE, field=key),
|
216
|
+
status=FieldStatus.Status.PENDING,
|
217
|
+
)
|
218
|
+
)
|
219
|
+
|
206
220
|
|
207
221
|
async def parse_internal_file_field(
|
208
222
|
key: str,
|
@@ -216,6 +230,8 @@ async def parse_internal_file_field(
|
|
216
230
|
writer.files[key].added.FromDatetime(datetime.now())
|
217
231
|
if file_field.language:
|
218
232
|
writer.files[key].language = file_field.language
|
233
|
+
if file_field.extract_strategy is not None:
|
234
|
+
writer.files[key].extract_strategy = file_field.extract_strategy
|
219
235
|
|
220
236
|
processing = get_processing()
|
221
237
|
|
@@ -251,6 +267,8 @@ def parse_external_file_field(
|
|
251
267
|
writer.files[key].added.FromDatetime(datetime.now())
|
252
268
|
if file_field.language:
|
253
269
|
writer.files[key].language = file_field.language
|
270
|
+
if file_field.extract_strategy is not None:
|
271
|
+
writer.files[key].extract_strategy = file_field.extract_strategy
|
254
272
|
uri = file_field.file.uri
|
255
273
|
writer.files[key].url = uri # type: ignore
|
256
274
|
writer.files[key].file.uri = uri # type: ignore
|
@@ -293,6 +311,9 @@ def parse_link_field(
|
|
293
311
|
if link_field.xpath is not None:
|
294
312
|
writer.links[key].xpath = link_field.xpath
|
295
313
|
|
314
|
+
if link_field.extract_strategy is not None:
|
315
|
+
writer.links[key].extract_strategy = link_field.extract_strategy
|
316
|
+
|
296
317
|
toprocess.linkfield[key] = models.LinkUpload(
|
297
318
|
link=link_field.uri,
|
298
319
|
headers=link_field.headers or {},
|
@@ -300,6 +321,13 @@ def parse_link_field(
|
|
300
321
|
localstorage=link_field.localstorage or {},
|
301
322
|
css_selector=link_field.css_selector,
|
302
323
|
xpath=link_field.xpath,
|
324
|
+
extract_strategy=link_field.extract_strategy,
|
325
|
+
)
|
326
|
+
writer.field_statuses.append(
|
327
|
+
FieldIDStatus(
|
328
|
+
id=resources_pb2.FieldID(field_type=resources_pb2.FieldType.LINK, field=key),
|
329
|
+
status=FieldStatus.Status.PENDING,
|
330
|
+
)
|
303
331
|
)
|
304
332
|
|
305
333
|
|
@@ -313,7 +341,6 @@ async def parse_conversation_field(
|
|
313
341
|
) -> None:
|
314
342
|
storage = await get_storage(service_name=SERVICE_NAME)
|
315
343
|
processing = get_processing()
|
316
|
-
|
317
344
|
field_value = resources_pb2.Conversation()
|
318
345
|
convs = models.PushConversation()
|
319
346
|
for message in conversation_field.messages:
|
@@ -338,7 +365,7 @@ async def parse_conversation_field(
|
|
338
365
|
cm.content.attachments_fields.extend(
|
339
366
|
[
|
340
367
|
resources_pb2.FieldRef(
|
341
|
-
field_type=
|
368
|
+
field_type=to_proto.field_type_name(attachment.field_type),
|
342
369
|
field_id=attachment.field_id,
|
343
370
|
split=attachment.split if attachment.split is not None else "",
|
344
371
|
)
|
@@ -377,3 +404,9 @@ async def parse_conversation_field(
|
|
377
404
|
|
378
405
|
toprocess.conversationfield[key] = convs
|
379
406
|
writer.conversations[key].CopyFrom(field_value)
|
407
|
+
writer.field_statuses.append(
|
408
|
+
FieldIDStatus(
|
409
|
+
id=resources_pb2.FieldID(field_type=resources_pb2.FieldType.CONVERSATION, field=key),
|
410
|
+
status=FieldStatus.Status.PENDING,
|
411
|
+
)
|
412
|
+
)
|
nucliadb/writer/settings.py
CHANGED
@@ -36,7 +36,7 @@ class BackPressureSettings(BaseSettings):
|
|
36
36
|
alias="back_pressure_enabled",
|
37
37
|
)
|
38
38
|
indexing_rate: float = Field(
|
39
|
-
default=
|
39
|
+
default=10,
|
40
40
|
description="Estimation of the indexing rate in messages per second. This is used to calculate the try again in time", # noqa
|
41
41
|
)
|
42
42
|
ingest_rate: float = Field(
|
@@ -48,7 +48,7 @@ class BackPressureSettings(BaseSettings):
|
|
48
48
|
description="Estimation of the processing rate in messages per second. This is used to calculate the try again in time", # noqa
|
49
49
|
)
|
50
50
|
max_indexing_pending: int = Field(
|
51
|
-
default=
|
51
|
+
default=1000,
|
52
52
|
description="Max number of messages pending to index in a node queue before rate limiting writes. Set to 0 to disable indexing back pressure checks", # noqa
|
53
53
|
alias="back_pressure_max_indexing_pending",
|
54
54
|
)
|
nucliadb/writer/tus/gcs.py
CHANGED
@@ -354,23 +354,24 @@ class GCloudFileStorageManager(FileStorageManager):
|
|
354
354
|
if dm.size == 0:
|
355
355
|
if self.storage.session is None:
|
356
356
|
raise AttributeError()
|
357
|
-
#
|
358
|
-
|
359
|
-
|
360
|
-
|
357
|
+
# In case of empty file, we need to send a PUT request with empty body
|
358
|
+
# and Content-Range header set to "bytes */0"
|
359
|
+
headers = {
|
360
|
+
"Content-Length": "0",
|
361
|
+
"Content-Range": "bytes */0",
|
362
|
+
}
|
361
363
|
resumable_uri = dm.get("resumable_uri")
|
362
364
|
async with self.storage.session.put(
|
363
365
|
resumable_uri,
|
364
|
-
headers=
|
365
|
-
"Content-Length": "0",
|
366
|
-
"Content-Range": content_range,
|
367
|
-
},
|
366
|
+
headers=headers,
|
368
367
|
data="",
|
369
368
|
) as call:
|
370
|
-
text = await call.text() # noqa
|
371
369
|
if call.status not in [200, 201, 308]:
|
370
|
+
try:
|
371
|
+
text = await call.text()
|
372
|
+
except Exception:
|
373
|
+
text = ""
|
372
374
|
raise GoogleCloudException(f"{call.status}: {text}")
|
373
|
-
return call
|
374
375
|
path = dm.get("path")
|
375
376
|
await dm.finish()
|
376
377
|
return path
|
@@ -1,15 +1,13 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: nucliadb
|
3
|
-
Version: 6.2.
|
4
|
-
|
5
|
-
Author:
|
6
|
-
|
7
|
-
License: BSD
|
3
|
+
Version: 6.2.1
|
4
|
+
Summary: NucliaDB
|
5
|
+
Author-email: Nuclia <nucliadb@nuclia.com>
|
6
|
+
License: AGPL
|
8
7
|
Project-URL: Nuclia, https://nuclia.com
|
9
8
|
Project-URL: Github, https://github.com/nuclia/nucliadb
|
10
9
|
Project-URL: Slack, https://nuclia-community.slack.com
|
11
10
|
Project-URL: API Reference, https://docs.nuclia.dev/docs/api
|
12
|
-
Keywords: search,semantic,AI
|
13
11
|
Classifier: Development Status :: 4 - Beta
|
14
12
|
Classifier: Intended Audience :: Developers
|
15
13
|
Classifier: Intended Audience :: Information Technology
|
@@ -20,14 +18,14 @@ Classifier: Programming Language :: Python :: 3.10
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.11
|
21
19
|
Classifier: Programming Language :: Python :: 3.12
|
22
20
|
Classifier: Programming Language :: Python :: 3 :: Only
|
23
|
-
Requires-Python:
|
21
|
+
Requires-Python: <4,>=3.9
|
24
22
|
Description-Content-Type: text/markdown
|
25
|
-
Requires-Dist: nucliadb-telemetry[all]>=6.2.
|
26
|
-
Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.2.
|
27
|
-
Requires-Dist: nucliadb-protos>=6.2.
|
28
|
-
Requires-Dist: nucliadb-models>=6.2.
|
23
|
+
Requires-Dist: nucliadb-telemetry[all]>=6.2.1.post3260
|
24
|
+
Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.2.1.post3260
|
25
|
+
Requires-Dist: nucliadb-protos>=6.2.1.post3260
|
26
|
+
Requires-Dist: nucliadb-models>=6.2.1.post3260
|
27
|
+
Requires-Dist: nidx-protos>=6.2.1.post3260
|
29
28
|
Requires-Dist: nucliadb-admin-assets>=1.0.0.post1224
|
30
|
-
Requires-Dist: nucliadb-node-binding>=2.26.0
|
31
29
|
Requires-Dist: nuclia-models>=0.24.2
|
32
30
|
Requires-Dist: uvicorn
|
33
31
|
Requires-Dist: argdantic
|
@@ -78,7 +76,6 @@ Requires-Dist: async_lru>=2.0.4
|
|
78
76
|
Requires-Dist: async-timeout>=4.0.3
|
79
77
|
Requires-Dist: cachetools>=5.3.2
|
80
78
|
Requires-Dist: types-cachetools>=5.3.0.5
|
81
|
-
Requires-Dist: kubernetes_asyncio<30.0.0
|
82
79
|
Provides-Extra: redis
|
83
80
|
Requires-Dist: redis>=4.3.4; extra == "redis"
|
84
81
|
|