nucliadb 6.3.7.post4066__py3-none-any.whl → 6.3.7.post4068__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.
- nucliadb/search/api/v1/search.py +6 -39
- nucliadb/search/search/chat/ask.py +19 -26
- nucliadb/search/search/chat/query.py +6 -6
- nucliadb/search/search/find.py +21 -91
- nucliadb/search/search/find_merge.py +18 -9
- nucliadb/search/search/graph_strategy.py +9 -10
- nucliadb/search/search/merge.py +76 -65
- nucliadb/search/search/query.py +2 -455
- nucliadb/search/search/query_parser/fetcher.py +41 -0
- nucliadb/search/search/query_parser/models.py +82 -8
- nucliadb/search/search/query_parser/parsers/ask.py +77 -0
- nucliadb/search/search/query_parser/parsers/common.py +189 -0
- nucliadb/search/search/query_parser/parsers/find.py +175 -13
- nucliadb/search/search/query_parser/parsers/search.py +249 -0
- nucliadb/search/search/query_parser/parsers/unit_retrieval.py +176 -0
- nucliadb/search/search/rerankers.py +4 -2
- {nucliadb-6.3.7.post4066.dist-info → nucliadb-6.3.7.post4068.dist-info}/METADATA +6 -6
- {nucliadb-6.3.7.post4066.dist-info → nucliadb-6.3.7.post4068.dist-info}/RECORD +21 -17
- {nucliadb-6.3.7.post4066.dist-info → nucliadb-6.3.7.post4068.dist-info}/WHEEL +0 -0
- {nucliadb-6.3.7.post4066.dist-info → nucliadb-6.3.7.post4068.dist-info}/entry_points.txt +0 -0
- {nucliadb-6.3.7.post4066.dist-info → nucliadb-6.3.7.post4068.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,249 @@
|
|
1
|
+
# Copyright (C) 2021 Bosutech XXI S.L.
|
2
|
+
#
|
3
|
+
# nucliadb is offered under the AGPL v3.0 and as commercial software.
|
4
|
+
# For commercial licensing, contact us at info@nuclia.com.
|
5
|
+
#
|
6
|
+
# AGPL:
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as
|
9
|
+
# published by the Free Software Foundation, either version 3 of the
|
10
|
+
# License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
from typing import Optional
|
21
|
+
|
22
|
+
from nucliadb.search.search.metrics import query_parser_observer
|
23
|
+
from nucliadb.search.search.query import expand_entities
|
24
|
+
from nucliadb.search.search.query_parser.exceptions import InvalidQueryError
|
25
|
+
from nucliadb.search.search.query_parser.fetcher import Fetcher
|
26
|
+
from nucliadb.search.search.query_parser.filter_expression import parse_expression
|
27
|
+
from nucliadb.search.search.query_parser.models import (
|
28
|
+
Filters,
|
29
|
+
NoopReranker,
|
30
|
+
ParsedQuery,
|
31
|
+
Query,
|
32
|
+
RankFusion,
|
33
|
+
RelationQuery,
|
34
|
+
UnitRetrieval,
|
35
|
+
_TextQuery,
|
36
|
+
)
|
37
|
+
from nucliadb.search.search.query_parser.old_filters import OldFilterParams, parse_old_filters
|
38
|
+
from nucliadb.search.search.utils import filter_hidden_resources
|
39
|
+
from nucliadb_models import search as search_models
|
40
|
+
from nucliadb_models.filters import FilterExpression
|
41
|
+
from nucliadb_models.search import (
|
42
|
+
SearchRequest,
|
43
|
+
SortField,
|
44
|
+
SortOptions,
|
45
|
+
SortOrder,
|
46
|
+
)
|
47
|
+
from nucliadb_protos import nodereader_pb2, utils_pb2
|
48
|
+
|
49
|
+
from .common import parse_keyword_query, parse_semantic_query, parse_top_k, validate_base_request
|
50
|
+
|
51
|
+
INDEX_SORTABLE_FIELDS = [
|
52
|
+
SortField.CREATED,
|
53
|
+
SortField.MODIFIED,
|
54
|
+
]
|
55
|
+
|
56
|
+
|
57
|
+
@query_parser_observer.wrap({"type": "parse_search"})
|
58
|
+
async def parse_search(
|
59
|
+
kbid: str, item: SearchRequest, *, fetcher: Optional[Fetcher] = None
|
60
|
+
) -> ParsedQuery:
|
61
|
+
fetcher = fetcher or fetcher_for_search(kbid, item)
|
62
|
+
parser = _SearchParser(kbid, item, fetcher)
|
63
|
+
retrieval = await parser.parse()
|
64
|
+
return ParsedQuery(fetcher=fetcher, retrieval=retrieval, generation=None)
|
65
|
+
|
66
|
+
|
67
|
+
def fetcher_for_search(kbid: str, item: SearchRequest) -> Fetcher:
|
68
|
+
return Fetcher(
|
69
|
+
kbid=kbid,
|
70
|
+
query=item.query,
|
71
|
+
user_vector=item.vector,
|
72
|
+
vectorset=item.vectorset,
|
73
|
+
rephrase=item.rephrase,
|
74
|
+
rephrase_prompt=item.rephrase_prompt,
|
75
|
+
generative_model=None,
|
76
|
+
)
|
77
|
+
|
78
|
+
|
79
|
+
class _SearchParser:
|
80
|
+
def __init__(self, kbid: str, item: SearchRequest, fetcher: Fetcher):
|
81
|
+
self.kbid = kbid
|
82
|
+
self.item = item
|
83
|
+
self.fetcher = fetcher
|
84
|
+
|
85
|
+
# cached data while parsing
|
86
|
+
self._query: Optional[Query] = None
|
87
|
+
self._top_k: Optional[int] = None
|
88
|
+
|
89
|
+
async def parse(self) -> UnitRetrieval:
|
90
|
+
validate_base_request(self.item)
|
91
|
+
|
92
|
+
self._top_k = parse_top_k(self.item)
|
93
|
+
|
94
|
+
# parse search types (features)
|
95
|
+
|
96
|
+
self._query = Query()
|
97
|
+
|
98
|
+
if search_models.SearchOptions.KEYWORD in self.item.features:
|
99
|
+
keyword = await self._parse_text_query()
|
100
|
+
self._query.keyword = keyword
|
101
|
+
|
102
|
+
if search_models.SearchOptions.FULLTEXT in self.item.features:
|
103
|
+
# copy from keyword, as everything is the same and we can't search
|
104
|
+
# anything different right now
|
105
|
+
keyword = self._query.keyword or (await self._parse_text_query())
|
106
|
+
self._query.fulltext = keyword
|
107
|
+
|
108
|
+
if search_models.SearchOptions.SEMANTIC in self.item.features:
|
109
|
+
self._query.semantic = await parse_semantic_query(self.item, fetcher=self.fetcher)
|
110
|
+
|
111
|
+
if search_models.SearchOptions.RELATIONS in self.item.features:
|
112
|
+
self._query.relation = await self._parse_relation_query()
|
113
|
+
|
114
|
+
filters = await self._parse_filters()
|
115
|
+
|
116
|
+
return UnitRetrieval(
|
117
|
+
query=self._query,
|
118
|
+
top_k=self._top_k,
|
119
|
+
filters=filters,
|
120
|
+
# TODO: this should be in a post retrieval step
|
121
|
+
rank_fusion=RankFusion(window=self._top_k),
|
122
|
+
reranker=NoopReranker(),
|
123
|
+
)
|
124
|
+
|
125
|
+
async def _parse_text_query(self) -> _TextQuery:
|
126
|
+
assert self._top_k is not None, "top_k must be parsed before text query"
|
127
|
+
|
128
|
+
keyword = await parse_keyword_query(self.item, fetcher=self.fetcher)
|
129
|
+
sort, order_by, limit = self._parse_sorting()
|
130
|
+
keyword.sort = sort
|
131
|
+
keyword.order_by = order_by
|
132
|
+
if limit is not None:
|
133
|
+
# sort limit can extend top_k
|
134
|
+
self._top_k = max(self._top_k, limit)
|
135
|
+
return keyword
|
136
|
+
|
137
|
+
async def _parse_relation_query(self) -> RelationQuery:
|
138
|
+
detected_entities = await self._get_detected_entities()
|
139
|
+
deleted_entity_groups = await self.fetcher.get_deleted_entity_groups()
|
140
|
+
meta_cache = await self.fetcher.get_entities_meta_cache()
|
141
|
+
deleted_entities = meta_cache.deleted_entities
|
142
|
+
return RelationQuery(
|
143
|
+
detected_entities=detected_entities,
|
144
|
+
deleted_entity_groups=deleted_entity_groups,
|
145
|
+
deleted_entities=deleted_entities,
|
146
|
+
)
|
147
|
+
|
148
|
+
async def _get_detected_entities(self) -> list[utils_pb2.RelationNode]:
|
149
|
+
detected_entities = await self.fetcher.get_detected_entities()
|
150
|
+
meta_cache = await self.fetcher.get_entities_meta_cache()
|
151
|
+
detected_entities = expand_entities(meta_cache, detected_entities)
|
152
|
+
return detected_entities
|
153
|
+
|
154
|
+
def _parse_sorting(self) -> tuple[search_models.SortOrder, search_models.SortField, Optional[int]]:
|
155
|
+
sort = self.item.sort
|
156
|
+
if len(self.item.query) == 0:
|
157
|
+
if sort is None:
|
158
|
+
sort = SortOptions(
|
159
|
+
field=SortField.CREATED,
|
160
|
+
order=SortOrder.DESC,
|
161
|
+
limit=None,
|
162
|
+
)
|
163
|
+
elif sort.field not in INDEX_SORTABLE_FIELDS:
|
164
|
+
raise InvalidQueryError(
|
165
|
+
"sort_field",
|
166
|
+
f"Empty query can only be sorted by '{SortField.CREATED}' or"
|
167
|
+
f" '{SortField.MODIFIED}' and sort limit won't be applied",
|
168
|
+
)
|
169
|
+
else:
|
170
|
+
if sort is None:
|
171
|
+
sort = SortOptions(
|
172
|
+
field=SortField.SCORE,
|
173
|
+
order=SortOrder.DESC,
|
174
|
+
limit=None,
|
175
|
+
)
|
176
|
+
elif sort.field not in INDEX_SORTABLE_FIELDS and sort.limit is None:
|
177
|
+
raise InvalidQueryError(
|
178
|
+
"sort_field",
|
179
|
+
f"Sort by '{sort.field}' requires setting a sort limit",
|
180
|
+
)
|
181
|
+
|
182
|
+
# We need to ask for all and cut later
|
183
|
+
top_k = None
|
184
|
+
if sort and sort.limit is not None:
|
185
|
+
# As the index can't sort, we have to do it when merging. To
|
186
|
+
# have consistent results, we must limit them
|
187
|
+
top_k = sort.limit
|
188
|
+
|
189
|
+
return (sort.order, sort.field, top_k)
|
190
|
+
|
191
|
+
async def _parse_filters(self) -> Filters:
|
192
|
+
assert self._query is not None, "query must be parsed before filters"
|
193
|
+
|
194
|
+
has_old_filters = (
|
195
|
+
len(self.item.filters) > 0
|
196
|
+
or len(self.item.fields) > 0
|
197
|
+
or self.item.range_creation_start is not None
|
198
|
+
or self.item.range_creation_end is not None
|
199
|
+
or self.item.range_modification_start is not None
|
200
|
+
or self.item.range_modification_end is not None
|
201
|
+
)
|
202
|
+
if self.item.filter_expression is not None and has_old_filters:
|
203
|
+
raise InvalidQueryError("filter_expression", "Cannot mix old filters with filter_expression")
|
204
|
+
|
205
|
+
field_expr = None
|
206
|
+
paragraph_expr = None
|
207
|
+
filter_operator = nodereader_pb2.FilterOperator.AND
|
208
|
+
|
209
|
+
if has_old_filters:
|
210
|
+
old_filters = OldFilterParams(
|
211
|
+
label_filters=self.item.filters,
|
212
|
+
keyword_filters=[],
|
213
|
+
range_creation_start=self.item.range_creation_start,
|
214
|
+
range_creation_end=self.item.range_creation_end,
|
215
|
+
range_modification_start=self.item.range_modification_start,
|
216
|
+
range_modification_end=self.item.range_modification_end,
|
217
|
+
fields=self.item.fields,
|
218
|
+
)
|
219
|
+
field_expr, paragraph_expr = await parse_old_filters(old_filters, self.fetcher)
|
220
|
+
|
221
|
+
if self.item.filter_expression is not None:
|
222
|
+
if self.item.filter_expression.field:
|
223
|
+
field_expr = await parse_expression(self.item.filter_expression.field, self.kbid)
|
224
|
+
if self.item.filter_expression.paragraph:
|
225
|
+
paragraph_expr = await parse_expression(self.item.filter_expression.paragraph, self.kbid)
|
226
|
+
if self.item.filter_expression.operator == FilterExpression.Operator.OR:
|
227
|
+
filter_operator = nodereader_pb2.FilterOperator.OR
|
228
|
+
else:
|
229
|
+
filter_operator = nodereader_pb2.FilterOperator.AND
|
230
|
+
|
231
|
+
autofilter = None
|
232
|
+
if self.item.autofilter:
|
233
|
+
if self._query.relation is not None:
|
234
|
+
autofilter = self._query.relation.detected_entities
|
235
|
+
else:
|
236
|
+
autofilter = await self._get_detected_entities()
|
237
|
+
|
238
|
+
hidden = await filter_hidden_resources(self.kbid, self.item.show_hidden)
|
239
|
+
|
240
|
+
return Filters(
|
241
|
+
autofilter=autofilter,
|
242
|
+
facets=self.item.faceted,
|
243
|
+
field_expression=field_expr,
|
244
|
+
paragraph_expression=paragraph_expr,
|
245
|
+
filter_expression_operator=filter_operator,
|
246
|
+
security=self.item.security,
|
247
|
+
hidden=hidden,
|
248
|
+
with_duplicates=self.item.with_duplicates,
|
249
|
+
)
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# Copyright (C) 2021 Bosutech XXI S.L.
|
2
|
+
#
|
3
|
+
# nucliadb is offered under the AGPL v3.0 and as commercial software.
|
4
|
+
# For commercial licensing, contact us at info@nuclia.com.
|
5
|
+
#
|
6
|
+
# AGPL:
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as
|
9
|
+
# published by the Free Software Foundation, either version 3 of the
|
10
|
+
# License, or (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
from typing import Optional
|
21
|
+
|
22
|
+
from nucliadb.search.search.filters import (
|
23
|
+
translate_label,
|
24
|
+
)
|
25
|
+
from nucliadb.search.search.metrics import (
|
26
|
+
node_features,
|
27
|
+
query_parser_observer,
|
28
|
+
)
|
29
|
+
from nucliadb.search.search.query import (
|
30
|
+
apply_entities_filter,
|
31
|
+
get_sort_field_proto,
|
32
|
+
)
|
33
|
+
from nucliadb.search.search.query_parser.filter_expression import add_and_expression
|
34
|
+
from nucliadb.search.search.query_parser.models import ParsedQuery, PredictReranker, UnitRetrieval
|
35
|
+
from nucliadb_models.labels import LABEL_HIDDEN, translate_system_to_alias_label
|
36
|
+
from nucliadb_models.search import (
|
37
|
+
SortOrderMap,
|
38
|
+
)
|
39
|
+
from nucliadb_protos import nodereader_pb2, utils_pb2
|
40
|
+
from nucliadb_protos.nodereader_pb2 import SearchRequest
|
41
|
+
|
42
|
+
|
43
|
+
@query_parser_observer.wrap({"type": "convert_retrieval_to_proto"})
|
44
|
+
async def convert_retrieval_to_proto(
|
45
|
+
parsed: ParsedQuery,
|
46
|
+
) -> tuple[SearchRequest, bool, list[str], Optional[str]]:
|
47
|
+
request = SearchRequest()
|
48
|
+
|
49
|
+
## queries
|
50
|
+
|
51
|
+
if parsed.retrieval.query.keyword and parsed.retrieval.query.fulltext:
|
52
|
+
assert parsed.retrieval.query.keyword == parsed.retrieval.query.fulltext, (
|
53
|
+
"search proto doesn't support different queries for fulltext and keyword search"
|
54
|
+
)
|
55
|
+
|
56
|
+
if parsed.retrieval.query.fulltext:
|
57
|
+
request.document = True
|
58
|
+
node_features.inc({"type": "documents"})
|
59
|
+
if parsed.retrieval.query.keyword:
|
60
|
+
request.paragraph = True
|
61
|
+
node_features.inc({"type": "paragraphs"})
|
62
|
+
|
63
|
+
text_query = parsed.retrieval.query.keyword or parsed.retrieval.query.fulltext
|
64
|
+
if text_query is not None:
|
65
|
+
request.min_score_bm25 = text_query.min_score
|
66
|
+
|
67
|
+
if text_query.is_synonyms_query:
|
68
|
+
request.advanced_query = text_query.query
|
69
|
+
else:
|
70
|
+
request.body = text_query.query
|
71
|
+
|
72
|
+
# sort order
|
73
|
+
sort_field = get_sort_field_proto(text_query.order_by)
|
74
|
+
if sort_field is not None:
|
75
|
+
request.order.sort_by = sort_field
|
76
|
+
request.order.type = SortOrderMap[text_query.sort] # type: ignore
|
77
|
+
|
78
|
+
if parsed.retrieval.query.semantic:
|
79
|
+
node_features.inc({"type": "vectors"})
|
80
|
+
|
81
|
+
request.min_score_semantic = parsed.retrieval.query.semantic.min_score
|
82
|
+
|
83
|
+
query_vector = parsed.retrieval.query.semantic.query
|
84
|
+
if query_vector is not None:
|
85
|
+
request.vectorset = parsed.retrieval.query.semantic.vectorset
|
86
|
+
request.vector.extend(query_vector)
|
87
|
+
|
88
|
+
if parsed.retrieval.query.relation:
|
89
|
+
node_features.inc({"type": "relations"})
|
90
|
+
|
91
|
+
request.relation_subgraph.entry_points.extend(parsed.retrieval.query.relation.detected_entities)
|
92
|
+
request.relation_subgraph.depth = 1
|
93
|
+
request.relation_subgraph.deleted_groups.extend(
|
94
|
+
parsed.retrieval.query.relation.deleted_entity_groups
|
95
|
+
)
|
96
|
+
for group_id, deleted_entities in parsed.retrieval.query.relation.deleted_entities.items():
|
97
|
+
request.relation_subgraph.deleted_entities.append(
|
98
|
+
nodereader_pb2.EntitiesSubgraphRequest.DeletedEntities(
|
99
|
+
node_subtype=group_id, node_values=deleted_entities
|
100
|
+
)
|
101
|
+
)
|
102
|
+
|
103
|
+
# filters
|
104
|
+
|
105
|
+
request.with_duplicates = parsed.retrieval.filters.with_duplicates
|
106
|
+
|
107
|
+
request.faceted.labels.extend([translate_label(facet) for facet in parsed.retrieval.filters.facets])
|
108
|
+
|
109
|
+
if (
|
110
|
+
parsed.retrieval.filters.security is not None
|
111
|
+
and len(parsed.retrieval.filters.security.groups) > 0
|
112
|
+
):
|
113
|
+
security_pb = utils_pb2.Security()
|
114
|
+
for group_id in parsed.retrieval.filters.security.groups:
|
115
|
+
if group_id not in security_pb.access_groups:
|
116
|
+
security_pb.access_groups.append(group_id)
|
117
|
+
request.security.CopyFrom(security_pb)
|
118
|
+
|
119
|
+
if parsed.retrieval.filters.field_expression:
|
120
|
+
request.field_filter.CopyFrom(parsed.retrieval.filters.field_expression)
|
121
|
+
if parsed.retrieval.filters.paragraph_expression:
|
122
|
+
request.paragraph_filter.CopyFrom(parsed.retrieval.filters.paragraph_expression)
|
123
|
+
request.filter_operator = parsed.retrieval.filters.filter_expression_operator
|
124
|
+
|
125
|
+
autofilter = []
|
126
|
+
if parsed.retrieval.filters.autofilter:
|
127
|
+
entity_filters = apply_entities_filter(request, parsed.retrieval.filters.autofilter)
|
128
|
+
autofilter.extend([translate_system_to_alias_label(e) for e in entity_filters])
|
129
|
+
|
130
|
+
if parsed.retrieval.filters.hidden is not None:
|
131
|
+
expr = nodereader_pb2.FilterExpression()
|
132
|
+
if parsed.retrieval.filters.hidden:
|
133
|
+
expr.facet.facet = LABEL_HIDDEN
|
134
|
+
else:
|
135
|
+
expr.bool_not.facet.facet = LABEL_HIDDEN
|
136
|
+
|
137
|
+
add_and_expression(request.field_filter, expr)
|
138
|
+
|
139
|
+
# top_k
|
140
|
+
|
141
|
+
# Adjust requested page size depending on rank fusion and reranking algorithms.
|
142
|
+
#
|
143
|
+
# Some rerankers want more results than the requested by the user so
|
144
|
+
# reranking can have more choices.
|
145
|
+
|
146
|
+
rank_fusion_window = 0
|
147
|
+
if parsed.retrieval.rank_fusion is not None:
|
148
|
+
rank_fusion_window = parsed.retrieval.rank_fusion.window
|
149
|
+
|
150
|
+
reranker_window = 0
|
151
|
+
if parsed.retrieval.reranker is not None and isinstance(parsed.retrieval.reranker, PredictReranker):
|
152
|
+
reranker_window = parsed.retrieval.reranker.window
|
153
|
+
|
154
|
+
request.result_per_page = max(
|
155
|
+
request.result_per_page,
|
156
|
+
rank_fusion_window,
|
157
|
+
reranker_window,
|
158
|
+
)
|
159
|
+
|
160
|
+
# XXX: legacy values that were returned by QueryParser but not always
|
161
|
+
# needed. We should find a better abstraction
|
162
|
+
|
163
|
+
incomplete = is_incomplete(parsed.retrieval)
|
164
|
+
|
165
|
+
rephrased_query = None
|
166
|
+
if parsed.retrieval.query.semantic:
|
167
|
+
rephrased_query = await parsed.fetcher.get_rephrased_query()
|
168
|
+
|
169
|
+
return request, incomplete, autofilter, rephrased_query
|
170
|
+
|
171
|
+
|
172
|
+
def is_incomplete(retrieval: UnitRetrieval) -> bool:
|
173
|
+
if retrieval.query.semantic is None:
|
174
|
+
return False
|
175
|
+
incomplete = retrieval.query.semantic.query is None or len(retrieval.query.semantic.query) == 0
|
176
|
+
return incomplete
|
@@ -178,8 +178,10 @@ def get_reranker(reranker: parser_models.Reranker) -> Reranker:
|
|
178
178
|
elif isinstance(reranker, parser_models.PredictReranker):
|
179
179
|
algorithm = PredictReranker(reranker.window)
|
180
180
|
|
181
|
-
else:
|
182
|
-
|
181
|
+
else: # pragma: nocover
|
182
|
+
# This is a trick so mypy generates an error if this branch can be reached,
|
183
|
+
# that is, if we are missing some ifs
|
184
|
+
_a: int = "a"
|
183
185
|
|
184
186
|
return algorithm
|
185
187
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: nucliadb
|
3
|
-
Version: 6.3.7.
|
3
|
+
Version: 6.3.7.post4068
|
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.7.
|
24
|
-
Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.3.7.
|
25
|
-
Requires-Dist: nucliadb-protos>=6.3.7.
|
26
|
-
Requires-Dist: nucliadb-models>=6.3.7.
|
27
|
-
Requires-Dist: nidx-protos>=6.3.7.
|
23
|
+
Requires-Dist: nucliadb-telemetry[all]>=6.3.7.post4068
|
24
|
+
Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.3.7.post4068
|
25
|
+
Requires-Dist: nucliadb-protos>=6.3.7.post4068
|
26
|
+
Requires-Dist: nucliadb-models>=6.3.7.post4068
|
27
|
+
Requires-Dist: nidx-protos>=6.3.7.post4068
|
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[standard]
|
@@ -216,7 +216,7 @@ nucliadb/search/api/v1/graph.py,sha256=ItVpzJbqfDLjoIo2fTb2mKGCM1Z34sx7CBb3gNmj6
|
|
216
216
|
nucliadb/search/api/v1/knowledgebox.py,sha256=rWhx3PYWryingu19qwwFDbVvVYynq5Ky23FSlzmTutQ,8721
|
217
217
|
nucliadb/search/api/v1/predict_proxy.py,sha256=QrGzo0hKjtmyGZ6pjlJHYAh4hxwVUIOTcVcerRCw7eE,3047
|
218
218
|
nucliadb/search/api/v1/router.py,sha256=mtT07rBZcVfpa49doaw9b1tj3sdi3qLH0gn9Io6NYM0,988
|
219
|
-
nucliadb/search/api/v1/search.py,sha256=
|
219
|
+
nucliadb/search/api/v1/search.py,sha256=9OR4jXryhDkTFCPeeXyxK_VKGKkUMn8i5q41f747AiI,12829
|
220
220
|
nucliadb/search/api/v1/suggest.py,sha256=Pwyxyk3Vu7aKU8vl2_rKhuE40ngnjZwAXS1rAilPDtM,6506
|
221
221
|
nucliadb/search/api/v1/summarize.py,sha256=VAHJvE6V3xUgEBfqNKhgoxmDqCvh30RnrEIBVhMcNLU,2499
|
222
222
|
nucliadb/search/api/v1/utils.py,sha256=5Ve-frn7LAE2jqAgB85F8RSeqxDlyA08--gS-AdOLS4,1434
|
@@ -233,39 +233,43 @@ nucliadb/search/search/cut.py,sha256=ytY0_GY7ocNjfxTb4aosxEp4ZfhQNDP--JkhEMGD298
|
|
233
233
|
nucliadb/search/search/exceptions.py,sha256=klGLgAGGrXcSGix_W6418ZBMqDchAIGjN77ofkOScEI,1039
|
234
234
|
nucliadb/search/search/fetch.py,sha256=XJHIFnZmXM_8Kb37lb4lg1GYG7cZ1plT-qAIb_QziX4,6184
|
235
235
|
nucliadb/search/search/filters.py,sha256=1MkHlJjAQqoRCj7e5cEzK2HvBxGLE17I_omsjiklbtw,6476
|
236
|
-
nucliadb/search/search/find.py,sha256=
|
237
|
-
nucliadb/search/search/find_merge.py,sha256=
|
236
|
+
nucliadb/search/search/find.py,sha256=d3OufK9xPaGgSQ9RzER6VJ_rk-d_uly4ia452wmGiz8,8182
|
237
|
+
nucliadb/search/search/find_merge.py,sha256=sS_0ZeTDs7AiWWuDmYos8mThG5XvaTE92DBoQOPHGTQ,17964
|
238
238
|
nucliadb/search/search/graph_merge.py,sha256=OiUNiXOWwrUVKqStuRcoUJwvDbDYamqIgiAy_FwPdMI,3405
|
239
|
-
nucliadb/search/search/graph_strategy.py,sha256=
|
239
|
+
nucliadb/search/search/graph_strategy.py,sha256=hwof-jxYELI6EYmvccDViDda3urE6E7v24-_-IsEF3E,32916
|
240
240
|
nucliadb/search/search/hydrator.py,sha256=-R37gCrGxkyaiHQalnTWHNG_FCx11Zucd7qA1vQCxuw,6985
|
241
241
|
nucliadb/search/search/ingestion_agents.py,sha256=NeJr4EEX-bvFFMGvXOOwLv8uU7NuQ-ntJnnrhnKfMzY,3174
|
242
|
-
nucliadb/search/search/merge.py,sha256=
|
242
|
+
nucliadb/search/search/merge.py,sha256=4tnTgljD7FKdQYX7frZ3qyu8-n9wNb7f6H6ulqq4sV8,23369
|
243
243
|
nucliadb/search/search/metrics.py,sha256=HJVQPLOIwLuc733G4keqEgx1-Dcg97hyWGKZQTojiSE,2973
|
244
244
|
nucliadb/search/search/paragraphs.py,sha256=pNAEiYqJGGUVcEf7xf-PFMVqz0PX4Qb-WNG-_zPGN2o,7799
|
245
245
|
nucliadb/search/search/pgcatalog.py,sha256=s_J98fsX_RuFXwpejpkGqG-tD9ELuzz4YQ6U3ew5h2g,9313
|
246
246
|
nucliadb/search/search/predict_proxy.py,sha256=IFI3v_ODz2_UU1XZnyaD391fE7-2C0npSmj_HmDvzS4,3123
|
247
|
-
nucliadb/search/search/query.py,sha256=
|
247
|
+
nucliadb/search/search/query.py,sha256=B7KJCG1d4oX4M2WlecCuMc98QCygutsl1R980HyVx3M,11491
|
248
248
|
nucliadb/search/search/rank_fusion.py,sha256=tRGo_KlsFsVx1CQEy1iqQ6f0T1Dq1kf0axDXHuuzvvM,6946
|
249
|
-
nucliadb/search/search/rerankers.py,sha256=
|
249
|
+
nucliadb/search/search/rerankers.py,sha256=PvhExUb8zZYghiFHRgGotw6h6bU--Rft09wE8arvtAw,7424
|
250
250
|
nucliadb/search/search/shards.py,sha256=OEtN1p9WX_cMX8t-myaafpmFAPTpUEOutR7z1sDuNcY,3242
|
251
251
|
nucliadb/search/search/summarize.py,sha256=ksmYPubEQvAQgfPdZHfzB_rR19B2ci4IYZ6jLdHxZo8,4996
|
252
252
|
nucliadb/search/search/utils.py,sha256=iF2tbBA56gRMJH1TlE2hMrqeXqjoeOPt4KgRdp2m9Ek,3313
|
253
253
|
nucliadb/search/search/chat/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
254
|
-
nucliadb/search/search/chat/ask.py,sha256=
|
254
|
+
nucliadb/search/search/chat/ask.py,sha256=nGReEt6MRfBibMxWuH3H7jw5ktK3OmSW9ixzx-CC23Y,37229
|
255
255
|
nucliadb/search/search/chat/exceptions.py,sha256=Siy4GXW2L7oPhIR86H3WHBhE9lkV4A4YaAszuGGUf54,1356
|
256
256
|
nucliadb/search/search/chat/images.py,sha256=PA8VWxT5_HUGfW1ULhKTK46UBsVyINtWWqEM1ulzX1E,3095
|
257
257
|
nucliadb/search/search/chat/prompt.py,sha256=Jnja-Ss7skgnnDY8BymVfdeYsFPnIQFL8tEvcRXTKUE,47356
|
258
|
-
nucliadb/search/search/chat/query.py,sha256=
|
258
|
+
nucliadb/search/search/chat/query.py,sha256=ScZd2-hX9m36A8JGxesN8F5NKZV4FTiF-tN585gxg1M,16806
|
259
259
|
nucliadb/search/search/query_parser/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
260
260
|
nucliadb/search/search/query_parser/exceptions.py,sha256=szAOXUZ27oNY-OSa9t2hQ5HHkQQC0EX1FZz_LluJHJE,1224
|
261
|
-
nucliadb/search/search/query_parser/fetcher.py,sha256=
|
261
|
+
nucliadb/search/search/query_parser/fetcher.py,sha256=SkvBRDfSKmuz-QygNKLAU4AhZhhDo1dnOZmt1zA28RA,16851
|
262
262
|
nucliadb/search/search/query_parser/filter_expression.py,sha256=rws5vsKTofX2iMUK4yvjmLZFxtcbWbyhIcwen4j0rQg,6578
|
263
|
-
nucliadb/search/search/query_parser/models.py,sha256=
|
263
|
+
nucliadb/search/search/query_parser/models.py,sha256=gGE2E8mfzJ49rOkgBtyYrax2O9mZUYoH7iyxP5IhotU,4651
|
264
264
|
nucliadb/search/search/query_parser/old_filters.py,sha256=-zbfN-RsXoj_DRjh3Lfp-wShwFXgkISawzVptVzja-A,9071
|
265
265
|
nucliadb/search/search/query_parser/parsers/__init__.py,sha256=ySCNSdbesLXGZyR88919njulA6UE10_3PhqMG_Yj1o4,1034
|
266
|
+
nucliadb/search/search/query_parser/parsers/ask.py,sha256=eTz8wS-EJHuAagR384h6TT64itymFZRpfZJGX8r6aZM,2771
|
266
267
|
nucliadb/search/search/query_parser/parsers/catalog.py,sha256=XdBiTweGTQkj8m_V_i2xbwp7P5pPO8K1Tud692XKhMw,7149
|
267
|
-
nucliadb/search/search/query_parser/parsers/
|
268
|
+
nucliadb/search/search/query_parser/parsers/common.py,sha256=InUWq5cL_LBDptuibQiSMw-9OeByqymTTqW0dzp7rM0,6265
|
269
|
+
nucliadb/search/search/query_parser/parsers/find.py,sha256=MHEcFcukGUT8UMeq3wmefnv-FIEslrLsGNrDjtSvQ5A,11262
|
268
270
|
nucliadb/search/search/query_parser/parsers/graph.py,sha256=QJs-pybNXPsMSEkIHctb0Q0xQG-aArks8BtUxbJL5rU,9386
|
271
|
+
nucliadb/search/search/query_parser/parsers/search.py,sha256=Qh_xVdLW-jGyD2xDfiRU0K7vDuPu_3JsZEWJn81TLHw,9805
|
272
|
+
nucliadb/search/search/query_parser/parsers/unit_retrieval.py,sha256=2NS11DnSUqj3A58mZVMsVRkH00ah9S1lXgUvJZF8NCI,6773
|
269
273
|
nucliadb/standalone/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
270
274
|
nucliadb/standalone/api_router.py,sha256=hgq9FXpihzgjHkwcVGfGCSwyXy67fqXTfLFHuINzIi0,5567
|
271
275
|
nucliadb/standalone/app.py,sha256=mAApNK_iVsQgJyd-mtwCeZq5csSimwnXmlQGH9a70pE,5586
|
@@ -361,8 +365,8 @@ nucliadb/writer/tus/local.py,sha256=7jYa_w9b-N90jWgN2sQKkNcomqn6JMVBOVeDOVYJHto,
|
|
361
365
|
nucliadb/writer/tus/s3.py,sha256=vF0NkFTXiXhXq3bCVXXVV-ED38ECVoUeeYViP8uMqcU,8357
|
362
366
|
nucliadb/writer/tus/storage.py,sha256=ToqwjoYnjI4oIcwzkhha_MPxi-k4Jk3Lt55zRwaC1SM,2903
|
363
367
|
nucliadb/writer/tus/utils.py,sha256=MSdVbRsRSZVdkaum69_0wku7X3p5wlZf4nr6E0GMKbw,2556
|
364
|
-
nucliadb-6.3.7.
|
365
|
-
nucliadb-6.3.7.
|
366
|
-
nucliadb-6.3.7.
|
367
|
-
nucliadb-6.3.7.
|
368
|
-
nucliadb-6.3.7.
|
368
|
+
nucliadb-6.3.7.post4068.dist-info/METADATA,sha256=5s-XgWMQEi0Ea8TUODlJ7Us6DomG6DTvnWvJneE2I3Y,4301
|
369
|
+
nucliadb-6.3.7.post4068.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
370
|
+
nucliadb-6.3.7.post4068.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
|
371
|
+
nucliadb-6.3.7.post4068.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
|
372
|
+
nucliadb-6.3.7.post4068.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|