nucliadb 6.3.1.post3584__py3-none-any.whl → 6.3.1.post3590__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/backups/create.py +1 -2
- nucliadb/backups/utils.py +3 -8
- nucliadb/common/nidx.py +1 -0
- nucliadb/search/api/v1/__init__.py +16 -13
- nucliadb/search/api/v1/catalog.py +1 -1
- nucliadb/search/api/v1/graph.py +130 -0
- nucliadb/search/requesters/utils.py +16 -1
- nucliadb/search/search/find.py +1 -1
- nucliadb/search/search/graph_merge.py +90 -0
- nucliadb/search/search/pgcatalog.py +24 -18
- nucliadb/search/search/query_parser/models.py +9 -0
- nucliadb/search/search/query_parser/parsers/__init__.py +23 -0
- nucliadb/search/search/query_parser/{catalog.py → parsers/catalog.py} +1 -3
- nucliadb/search/search/query_parser/{parser.py → parsers/find.py} +0 -1
- nucliadb/search/search/query_parser/parsers/graph.py +177 -0
- nucliadb/search/search/shards.py +15 -0
- {nucliadb-6.3.1.post3584.dist-info → nucliadb-6.3.1.post3590.dist-info}/METADATA +6 -6
- {nucliadb-6.3.1.post3584.dist-info → nucliadb-6.3.1.post3590.dist-info}/RECORD +21 -17
- {nucliadb-6.3.1.post3584.dist-info → nucliadb-6.3.1.post3590.dist-info}/WHEEL +0 -0
- {nucliadb-6.3.1.post3584.dist-info → nucliadb-6.3.1.post3590.dist-info}/entry_points.txt +0 -0
- {nucliadb-6.3.1.post3584.dist-info → nucliadb-6.3.1.post3590.dist-info}/top_level.txt +0 -0
nucliadb/backups/create.py
CHANGED
@@ -30,7 +30,6 @@ from nucliadb.backups.const import (
|
|
30
30
|
)
|
31
31
|
from nucliadb.backups.models import BackupMetadata, CreateBackupRequest
|
32
32
|
from nucliadb.backups.settings import settings
|
33
|
-
from nucliadb.backups.utils import exists_in_storge
|
34
33
|
from nucliadb.common import datamanagers
|
35
34
|
from nucliadb.common.context import ApplicationContext
|
36
35
|
from nucliadb.export_import.utils import (
|
@@ -261,7 +260,7 @@ async def delete_metadata(context: ApplicationContext, kbid: str, backup_id: str
|
|
261
260
|
|
262
261
|
|
263
262
|
async def exists_cf(context: ApplicationContext, cf: resources_pb2.CloudFile) -> bool:
|
264
|
-
return await
|
263
|
+
return await context.blob_storage.exists_object(bucket=cf.bucket_name, key=cf.uri)
|
265
264
|
|
266
265
|
|
267
266
|
async def upload_to_bucket(context: ApplicationContext, bytes_iterator: AsyncIterator[bytes], key: str):
|
nucliadb/backups/utils.py
CHANGED
@@ -24,12 +24,7 @@ from nucliadb_utils.storages.storage import Storage
|
|
24
24
|
|
25
25
|
|
26
26
|
async def exists_backup(storage: Storage, backup_id: str) -> bool:
|
27
|
-
|
28
|
-
|
27
|
+
# As the labels file is always created, we use it to check if the backup exists
|
28
|
+
return await storage.exists_object(
|
29
|
+
settings.backups_bucket, StorageKeys.LABELS.format(backup_id=backup_id)
|
29
30
|
)
|
30
|
-
|
31
|
-
|
32
|
-
async def exists_in_storge(storage: Storage, bucket: str, key: str) -> bool:
|
33
|
-
async for _ in storage.iterate_objects(bucket=bucket, prefix=key):
|
34
|
-
return True
|
35
|
-
return False
|
nucliadb/common/nidx.py
CHANGED
@@ -262,6 +262,7 @@ class NodeNidxAdapter:
|
|
262
262
|
# Searcher methods
|
263
263
|
self.Search = searcher_client.Search
|
264
264
|
self.Suggest = searcher_client.Suggest
|
265
|
+
self.GraphSearch = searcher_client.GraphSearch
|
265
266
|
self.Paragraphs = searcher_client.Paragraphs
|
266
267
|
self.Documents = searcher_client.Documents
|
267
268
|
|
@@ -17,16 +17,19 @@
|
|
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 . import
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
from .
|
20
|
+
from . import ( # noqa: F401
|
21
|
+
ask,
|
22
|
+
catalog,
|
23
|
+
feedback,
|
24
|
+
find,
|
25
|
+
graph,
|
26
|
+
knowledgebox,
|
27
|
+
predict_proxy,
|
28
|
+
search,
|
29
|
+
suggest,
|
30
|
+
summarize,
|
31
|
+
)
|
32
|
+
from .resource import ask as ask_resource # noqa: F401
|
33
|
+
from .resource import ingestion_agents as ingestion_agents_resource # noqa: F401
|
34
|
+
from .resource import search as search_resource # noqa: F401
|
35
|
+
from .router import api # noqa: F401
|
@@ -36,7 +36,7 @@ from nucliadb.search.search import cache
|
|
36
36
|
from nucliadb.search.search.exceptions import InvalidQueryError
|
37
37
|
from nucliadb.search.search.merge import fetch_resources
|
38
38
|
from nucliadb.search.search.pgcatalog import pgcatalog_search
|
39
|
-
from nucliadb.search.search.query_parser.
|
39
|
+
from nucliadb.search.search.query_parser.parsers import parse_catalog
|
40
40
|
from nucliadb.search.search.utils import (
|
41
41
|
maybe_log_request_payload,
|
42
42
|
)
|
@@ -0,0 +1,130 @@
|
|
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 fastapi import Header, Request, Response
|
21
|
+
from fastapi_versioning import version
|
22
|
+
|
23
|
+
from nucliadb.search.api.v1.router import KB_PREFIX, api
|
24
|
+
from nucliadb.search.requesters.utils import Method, node_query
|
25
|
+
from nucliadb.search.search.graph_merge import (
|
26
|
+
build_graph_nodes_response,
|
27
|
+
build_graph_relations_response,
|
28
|
+
build_graph_response,
|
29
|
+
)
|
30
|
+
from nucliadb.search.search.query_parser.parsers import (
|
31
|
+
parse_graph_node_search,
|
32
|
+
parse_graph_relation_search,
|
33
|
+
parse_graph_search,
|
34
|
+
)
|
35
|
+
from nucliadb_models.graph.requests import (
|
36
|
+
GraphNodesSearchRequest,
|
37
|
+
GraphRelationsSearchRequest,
|
38
|
+
GraphSearchRequest,
|
39
|
+
)
|
40
|
+
from nucliadb_models.graph.responses import (
|
41
|
+
GraphNodesSearchResponse,
|
42
|
+
GraphRelationsSearchResponse,
|
43
|
+
GraphSearchResponse,
|
44
|
+
)
|
45
|
+
from nucliadb_models.resource import NucliaDBRoles
|
46
|
+
from nucliadb_models.search import (
|
47
|
+
NucliaDBClientType,
|
48
|
+
)
|
49
|
+
from nucliadb_utils.authentication import requires
|
50
|
+
|
51
|
+
|
52
|
+
@api.post(
|
53
|
+
f"/{KB_PREFIX}/{{kbid}}/graph",
|
54
|
+
status_code=200,
|
55
|
+
summary="Search Knowledge Box graph",
|
56
|
+
description="Search on the Knowledge Box graph and retrieve triplets of vertex-edge-vertex",
|
57
|
+
response_model_exclude_unset=True,
|
58
|
+
include_in_schema=False,
|
59
|
+
tags=["Search"],
|
60
|
+
)
|
61
|
+
@requires(NucliaDBRoles.READER)
|
62
|
+
@version(1)
|
63
|
+
async def graph_search_knowledgebox(
|
64
|
+
request: Request,
|
65
|
+
response: Response,
|
66
|
+
kbid: str,
|
67
|
+
item: GraphSearchRequest,
|
68
|
+
x_ndb_client: NucliaDBClientType = Header(NucliaDBClientType.API),
|
69
|
+
x_nucliadb_user: str = Header(""),
|
70
|
+
x_forwarded_for: str = Header(""),
|
71
|
+
) -> GraphSearchResponse:
|
72
|
+
pb_query = parse_graph_search(item)
|
73
|
+
|
74
|
+
results, _, _ = await node_query(kbid, Method.GRAPH, pb_query)
|
75
|
+
|
76
|
+
return build_graph_response(results)
|
77
|
+
|
78
|
+
|
79
|
+
@api.post(
|
80
|
+
f"/{KB_PREFIX}/{{kbid}}/graph/nodes",
|
81
|
+
status_code=200,
|
82
|
+
summary="Search Knowledge Box graph nodes",
|
83
|
+
description="Search on the Knowledge Box graph and retrieve nodes (vertices)",
|
84
|
+
response_model_exclude_unset=True,
|
85
|
+
include_in_schema=False,
|
86
|
+
tags=["Search"],
|
87
|
+
)
|
88
|
+
@requires(NucliaDBRoles.READER)
|
89
|
+
@version(1)
|
90
|
+
async def graph_nodes_search_knowledgebox(
|
91
|
+
request: Request,
|
92
|
+
response: Response,
|
93
|
+
kbid: str,
|
94
|
+
item: GraphNodesSearchRequest,
|
95
|
+
x_ndb_client: NucliaDBClientType = Header(NucliaDBClientType.API),
|
96
|
+
x_nucliadb_user: str = Header(""),
|
97
|
+
x_forwarded_for: str = Header(""),
|
98
|
+
) -> GraphNodesSearchResponse:
|
99
|
+
pb_query = parse_graph_node_search(item)
|
100
|
+
|
101
|
+
results, _, _ = await node_query(kbid, Method.GRAPH, pb_query)
|
102
|
+
|
103
|
+
return build_graph_nodes_response(results)
|
104
|
+
|
105
|
+
|
106
|
+
@api.post(
|
107
|
+
f"/{KB_PREFIX}/{{kbid}}/graph/relations",
|
108
|
+
status_code=200,
|
109
|
+
summary="Search Knowledge Box graph relations",
|
110
|
+
description="Search on the Knowledge Box graph and retrieve relations (edges)",
|
111
|
+
response_model_exclude_unset=True,
|
112
|
+
include_in_schema=False,
|
113
|
+
tags=["Search"],
|
114
|
+
)
|
115
|
+
@requires(NucliaDBRoles.READER)
|
116
|
+
@version(1)
|
117
|
+
async def graph_relations_search_knowledgebox(
|
118
|
+
request: Request,
|
119
|
+
response: Response,
|
120
|
+
kbid: str,
|
121
|
+
item: GraphRelationsSearchRequest,
|
122
|
+
x_ndb_client: NucliaDBClientType = Header(NucliaDBClientType.API),
|
123
|
+
x_nucliadb_user: str = Header(""),
|
124
|
+
x_forwarded_for: str = Header(""),
|
125
|
+
) -> GraphRelationsSearchResponse:
|
126
|
+
pb_query = parse_graph_relation_search(item)
|
127
|
+
|
128
|
+
results, _, _ = await node_query(kbid, Method.GRAPH, pb_query)
|
129
|
+
|
130
|
+
return build_graph_relations_response(results)
|
@@ -33,11 +33,14 @@ from nucliadb.common.cluster.exceptions import ShardsNotFound
|
|
33
33
|
from nucliadb.common.cluster.utils import get_shard_manager
|
34
34
|
from nucliadb.search import logger
|
35
35
|
from nucliadb.search.search.shards import (
|
36
|
+
graph_search_shard,
|
36
37
|
query_shard,
|
37
38
|
suggest_shard,
|
38
39
|
)
|
39
40
|
from nucliadb.search.settings import settings
|
40
41
|
from nucliadb_protos.nodereader_pb2 import (
|
42
|
+
GraphSearchRequest,
|
43
|
+
GraphSearchResponse,
|
41
44
|
SearchRequest,
|
42
45
|
SearchResponse,
|
43
46
|
SuggestRequest,
|
@@ -50,19 +53,22 @@ from nucliadb_telemetry import errors
|
|
50
53
|
class Method(Enum):
|
51
54
|
SEARCH = auto()
|
52
55
|
SUGGEST = auto()
|
56
|
+
GRAPH = auto()
|
53
57
|
|
54
58
|
|
55
59
|
METHODS = {
|
56
60
|
Method.SEARCH: query_shard,
|
57
61
|
Method.SUGGEST: suggest_shard,
|
62
|
+
Method.GRAPH: graph_search_shard,
|
58
63
|
}
|
59
64
|
|
60
|
-
REQUEST_TYPE = Union[SuggestRequest, SearchRequest]
|
65
|
+
REQUEST_TYPE = Union[SuggestRequest, SearchRequest, GraphSearchRequest]
|
61
66
|
|
62
67
|
T = TypeVar(
|
63
68
|
"T",
|
64
69
|
SuggestResponse,
|
65
70
|
SearchResponse,
|
71
|
+
GraphSearchResponse,
|
66
72
|
)
|
67
73
|
|
68
74
|
|
@@ -84,6 +90,15 @@ async def node_query(
|
|
84
90
|
) -> tuple[list[SearchResponse], bool, list[tuple[AbstractIndexNode, str]]]: ...
|
85
91
|
|
86
92
|
|
93
|
+
@overload
|
94
|
+
async def node_query(
|
95
|
+
kbid: str,
|
96
|
+
method: Method,
|
97
|
+
pb_query: GraphSearchRequest,
|
98
|
+
timeout: Optional[float] = None,
|
99
|
+
) -> tuple[list[GraphSearchResponse], bool, list[tuple[AbstractIndexNode, str]]]: ...
|
100
|
+
|
101
|
+
|
87
102
|
async def node_query(
|
88
103
|
kbid: str,
|
89
104
|
method: Method,
|
nucliadb/search/search/find.py
CHANGED
@@ -40,7 +40,7 @@ from nucliadb.search.search.metrics import (
|
|
40
40
|
)
|
41
41
|
from nucliadb.search.search.query import QueryParser
|
42
42
|
from nucliadb.search.search.query_parser.old_filters import OldFilterParams
|
43
|
-
from nucliadb.search.search.query_parser.
|
43
|
+
from nucliadb.search.search.query_parser.parsers import parse_find
|
44
44
|
from nucliadb.search.search.rank_fusion import (
|
45
45
|
RankFusionAlgorithm,
|
46
46
|
get_rank_fusion,
|
@@ -0,0 +1,90 @@
|
|
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
|
+
|
21
|
+
|
22
|
+
from nucliadb.common.models_utils.from_proto import RelationNodeTypePbMap
|
23
|
+
from nucliadb_models.graph import responses as graph_responses
|
24
|
+
from nucliadb_models.graph.responses import (
|
25
|
+
GraphNodesSearchResponse,
|
26
|
+
GraphRelationsSearchResponse,
|
27
|
+
GraphSearchResponse,
|
28
|
+
)
|
29
|
+
from nucliadb_protos import nodereader_pb2
|
30
|
+
|
31
|
+
|
32
|
+
def build_graph_response(results: list[nodereader_pb2.GraphSearchResponse]) -> GraphSearchResponse:
|
33
|
+
paths = []
|
34
|
+
for shard_results in results:
|
35
|
+
for pb_path in shard_results.graph:
|
36
|
+
source = shard_results.nodes[pb_path.source]
|
37
|
+
relation = shard_results.relations[pb_path.relation]
|
38
|
+
destination = shard_results.nodes[pb_path.destination]
|
39
|
+
|
40
|
+
path = graph_responses.GraphPath(
|
41
|
+
source=graph_responses.GraphNode(
|
42
|
+
value=source.value,
|
43
|
+
type=RelationNodeTypePbMap[source.ntype],
|
44
|
+
group=source.subtype,
|
45
|
+
),
|
46
|
+
relation=graph_responses.GraphRelation(
|
47
|
+
label=relation.label,
|
48
|
+
),
|
49
|
+
destination=graph_responses.GraphNode(
|
50
|
+
value=destination.value,
|
51
|
+
type=RelationNodeTypePbMap[destination.ntype],
|
52
|
+
group=destination.subtype,
|
53
|
+
),
|
54
|
+
)
|
55
|
+
paths.append(path)
|
56
|
+
|
57
|
+
response = GraphSearchResponse(paths=paths)
|
58
|
+
return response
|
59
|
+
|
60
|
+
|
61
|
+
def build_graph_nodes_response(
|
62
|
+
results: list[nodereader_pb2.GraphSearchResponse],
|
63
|
+
) -> GraphNodesSearchResponse:
|
64
|
+
nodes = []
|
65
|
+
for shard_results in results:
|
66
|
+
for node in shard_results.nodes:
|
67
|
+
nodes.append(
|
68
|
+
graph_responses.GraphNode(
|
69
|
+
value=node.value,
|
70
|
+
type=RelationNodeTypePbMap[node.ntype],
|
71
|
+
group=node.subtype,
|
72
|
+
)
|
73
|
+
)
|
74
|
+
response = GraphNodesSearchResponse(nodes=nodes)
|
75
|
+
return response
|
76
|
+
|
77
|
+
|
78
|
+
def build_graph_relations_response(
|
79
|
+
results: list[nodereader_pb2.GraphSearchResponse],
|
80
|
+
) -> GraphRelationsSearchResponse:
|
81
|
+
relations = []
|
82
|
+
for shard_results in results:
|
83
|
+
for relation in shard_results.relations:
|
84
|
+
relations.append(
|
85
|
+
graph_responses.GraphRelation(
|
86
|
+
label=relation.label,
|
87
|
+
)
|
88
|
+
)
|
89
|
+
response = GraphRelationsSearchResponse(relations=relations)
|
90
|
+
return response
|
@@ -111,7 +111,7 @@ def _convert_date_filter(date: CatalogExpression.Date, filter_params: dict[str,
|
|
111
111
|
raise ValueError(f"Invalid date operator")
|
112
112
|
|
113
113
|
|
114
|
-
def
|
114
|
+
def _prepare_query_filters(catalog_query: CatalogQuery) -> tuple[str, dict[str, Any]]:
|
115
115
|
filter_sql = ["kbid = %(kbid)s"]
|
116
116
|
filter_params: dict[str, Any] = {"kbid": catalog_query.kbid}
|
117
117
|
|
@@ -127,7 +127,17 @@ def _prepare_query(catalog_query: CatalogQuery):
|
|
127
127
|
if catalog_query.filters:
|
128
128
|
filter_sql.append(_convert_filter(catalog_query.filters, filter_params))
|
129
129
|
|
130
|
-
|
130
|
+
return (
|
131
|
+
f"SELECT * FROM catalog WHERE {' AND '.join(filter_sql)}",
|
132
|
+
filter_params,
|
133
|
+
)
|
134
|
+
|
135
|
+
|
136
|
+
def _prepare_query(catalog_query: CatalogQuery) -> tuple[str, dict[str, Any]]:
|
137
|
+
# Base query with all the filters
|
138
|
+
query, filter_params = _prepare_query_filters(catalog_query)
|
139
|
+
|
140
|
+
# Sort
|
131
141
|
if catalog_query.sort:
|
132
142
|
if catalog_query.sort.field == SortField.CREATED:
|
133
143
|
order_field = "created_at"
|
@@ -144,12 +154,15 @@ def _prepare_query(catalog_query: CatalogQuery):
|
|
144
154
|
else:
|
145
155
|
order_dir = "DESC"
|
146
156
|
|
147
|
-
|
157
|
+
query += f" ORDER BY {order_field} {order_dir}"
|
148
158
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
159
|
+
# Pagination
|
160
|
+
offset = catalog_query.page_size * catalog_query.page_number
|
161
|
+
query += f" LIMIT %(page_size)s OFFSET %(offset)s"
|
162
|
+
filter_params["page_size"] = catalog_query.page_size
|
163
|
+
filter_params["offset"] = offset
|
164
|
+
|
165
|
+
return query, filter_params
|
153
166
|
|
154
167
|
|
155
168
|
def _pg_driver() -> PGDriver:
|
@@ -159,7 +172,7 @@ def _pg_driver() -> PGDriver:
|
|
159
172
|
@observer.wrap({"op": "search"})
|
160
173
|
async def pgcatalog_search(catalog_query: CatalogQuery) -> Resources:
|
161
174
|
# Prepare SQL query
|
162
|
-
query, query_params =
|
175
|
+
query, query_params = _prepare_query_filters(catalog_query)
|
163
176
|
|
164
177
|
async with _pg_driver()._get_connection() as conn, conn.cursor(row_factory=dict_row) as cur:
|
165
178
|
facets = {}
|
@@ -210,15 +223,8 @@ async def pgcatalog_search(catalog_query: CatalogQuery) -> Resources:
|
|
210
223
|
|
211
224
|
# Query
|
212
225
|
with observer({"op": "query"}):
|
213
|
-
|
214
|
-
await cur.execute(
|
215
|
-
f"{query} LIMIT %(page_size)s OFFSET %(offset)s",
|
216
|
-
{
|
217
|
-
**query_params,
|
218
|
-
"page_size": catalog_query.page_size,
|
219
|
-
"offset": offset,
|
220
|
-
},
|
221
|
-
)
|
226
|
+
query, query_params = _prepare_query(catalog_query)
|
227
|
+
await cur.execute(query, query_params)
|
222
228
|
data = await cur.fetchall()
|
223
229
|
|
224
230
|
return Resources(
|
@@ -237,6 +243,6 @@ async def pgcatalog_search(catalog_query: CatalogQuery) -> Resources:
|
|
237
243
|
total=total,
|
238
244
|
page_number=catalog_query.page_number,
|
239
245
|
page_size=catalog_query.page_size,
|
240
|
-
next_page=(
|
246
|
+
next_page=(catalog_query.page_size * catalog_query.page_number + len(data) < total),
|
241
247
|
min_score=0,
|
242
248
|
)
|
@@ -28,6 +28,7 @@ from pydantic import (
|
|
28
28
|
)
|
29
29
|
|
30
30
|
from nucliadb_models import search as search_models
|
31
|
+
from nucliadb_protos import nodereader_pb2
|
31
32
|
|
32
33
|
### Retrieval
|
33
34
|
|
@@ -101,3 +102,11 @@ class CatalogQuery(BaseModel):
|
|
101
102
|
faceted: list[str]
|
102
103
|
page_size: int
|
103
104
|
page_number: int
|
105
|
+
|
106
|
+
|
107
|
+
### Graph
|
108
|
+
|
109
|
+
|
110
|
+
# Right now, we don't need a more generic model for graph queries, we can
|
111
|
+
# directly use the protobuffer directly
|
112
|
+
GraphRetrieval = nodereader_pb2.GraphSearchRequest
|
@@ -0,0 +1,23 @@
|
|
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
|
+
|
21
|
+
from .catalog import parse_catalog # noqa: F401
|
22
|
+
from .find import parse_find # noqa: F401
|
23
|
+
from .graph import parse_graph_node_search, parse_graph_relation_search, parse_graph_search # noqa: F401
|
@@ -18,10 +18,10 @@
|
|
18
18
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
19
|
#
|
20
20
|
|
21
|
-
|
22
21
|
from nucliadb.common import datamanagers
|
23
22
|
from nucliadb.search.search.exceptions import InvalidQueryError
|
24
23
|
from nucliadb.search.search.filters import translate_label
|
24
|
+
from nucliadb.search.search.query_parser.filter_expression import FacetFilterTypes, facet_from_filter
|
25
25
|
from nucliadb.search.search.query_parser.models import (
|
26
26
|
CatalogExpression,
|
27
27
|
CatalogQuery,
|
@@ -44,8 +44,6 @@ from nucliadb_models.search import (
|
|
44
44
|
SortOrder,
|
45
45
|
)
|
46
46
|
|
47
|
-
from .filter_expression import FacetFilterTypes, facet_from_filter
|
48
|
-
|
49
47
|
|
50
48
|
async def parse_catalog(kbid: str, item: search_models.CatalogRequest) -> CatalogQuery:
|
51
49
|
has_old_filters = (
|
@@ -0,0 +1,177 @@
|
|
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
|
+
|
21
|
+
|
22
|
+
from nucliadb.common.models_utils.from_proto import RelationNodeTypeMap
|
23
|
+
from nucliadb.search.search.query_parser.models import GraphRetrieval
|
24
|
+
from nucliadb_models.graph import requests as graph_requests
|
25
|
+
from nucliadb_protos import nodereader_pb2
|
26
|
+
|
27
|
+
|
28
|
+
def parse_graph_search(item: graph_requests.GraphSearchRequest) -> GraphRetrieval:
|
29
|
+
pb = nodereader_pb2.GraphSearchRequest()
|
30
|
+
pb.query.path.CopyFrom(_parse_path_query(item.query))
|
31
|
+
pb.top_k = item.top_k
|
32
|
+
return pb
|
33
|
+
|
34
|
+
|
35
|
+
def parse_graph_node_search(item: graph_requests.GraphNodesSearchRequest) -> GraphRetrieval:
|
36
|
+
pb = nodereader_pb2.GraphSearchRequest()
|
37
|
+
pb.query.path.CopyFrom(_parse_node_query(item.query))
|
38
|
+
pb.top_k = item.top_k
|
39
|
+
return pb
|
40
|
+
|
41
|
+
|
42
|
+
def parse_graph_relation_search(item: graph_requests.GraphRelationsSearchRequest) -> GraphRetrieval:
|
43
|
+
pb = nodereader_pb2.GraphSearchRequest()
|
44
|
+
pb.query.path.CopyFrom(_parse_relation_query(item.query))
|
45
|
+
pb.top_k = item.top_k
|
46
|
+
return pb
|
47
|
+
|
48
|
+
|
49
|
+
def _parse_path_query(expr: graph_requests.GraphPathQuery) -> nodereader_pb2.GraphQuery.PathQuery:
|
50
|
+
pb = nodereader_pb2.GraphQuery.PathQuery()
|
51
|
+
|
52
|
+
if isinstance(expr, graph_requests.And):
|
53
|
+
for op in expr.operands:
|
54
|
+
pb.bool_and.operands.append(_parse_path_query(op))
|
55
|
+
|
56
|
+
elif isinstance(expr, graph_requests.Or):
|
57
|
+
for op in expr.operands:
|
58
|
+
pb.bool_or.operands.append(_parse_path_query(op))
|
59
|
+
|
60
|
+
elif isinstance(expr, graph_requests.Not):
|
61
|
+
pb.bool_not.CopyFrom(_parse_path_query(expr.operand))
|
62
|
+
|
63
|
+
elif isinstance(expr, graph_requests.GraphPath):
|
64
|
+
if expr.source is not None:
|
65
|
+
_set_node_to_pb(expr.source, pb.path.source)
|
66
|
+
|
67
|
+
if expr.destination is not None:
|
68
|
+
_set_node_to_pb(expr.destination, pb.path.destination)
|
69
|
+
|
70
|
+
if expr.relation is not None:
|
71
|
+
relation = expr.relation
|
72
|
+
if relation.label is not None:
|
73
|
+
pb.path.relation.value = relation.label
|
74
|
+
|
75
|
+
pb.path.undirected = expr.undirected
|
76
|
+
|
77
|
+
elif isinstance(expr, graph_requests.SourceNode):
|
78
|
+
_set_node_to_pb(expr, pb.path.source)
|
79
|
+
|
80
|
+
elif isinstance(expr, graph_requests.DestinationNode):
|
81
|
+
_set_node_to_pb(expr, pb.path.destination)
|
82
|
+
|
83
|
+
elif isinstance(expr, graph_requests.AnyNode):
|
84
|
+
_set_node_to_pb(expr, pb.path.source)
|
85
|
+
pb.path.undirected = True
|
86
|
+
|
87
|
+
elif isinstance(expr, graph_requests.Relation):
|
88
|
+
if expr.label is not None:
|
89
|
+
pb.path.relation.value = expr.label
|
90
|
+
|
91
|
+
else: # pragma: nocover
|
92
|
+
# This is a trick so mypy generates an error if this branch can be reached,
|
93
|
+
# that is, if we are missing some ifs
|
94
|
+
_a: int = "a"
|
95
|
+
|
96
|
+
return pb
|
97
|
+
|
98
|
+
|
99
|
+
def _parse_node_query(expr: graph_requests.GraphNodesQuery) -> nodereader_pb2.GraphQuery.PathQuery:
|
100
|
+
pb = nodereader_pb2.GraphQuery.PathQuery()
|
101
|
+
|
102
|
+
if isinstance(expr, graph_requests.And):
|
103
|
+
for op in expr.operands:
|
104
|
+
pb.bool_and.operands.append(_parse_node_query(op))
|
105
|
+
|
106
|
+
elif isinstance(expr, graph_requests.Or):
|
107
|
+
for op in expr.operands:
|
108
|
+
pb.bool_or.operands.append(_parse_node_query(op))
|
109
|
+
|
110
|
+
elif isinstance(expr, graph_requests.Not):
|
111
|
+
pb.bool_not.CopyFrom(_parse_node_query(expr.operand))
|
112
|
+
|
113
|
+
elif isinstance(expr, graph_requests.SourceNode):
|
114
|
+
_set_node_to_pb(expr, pb.path.source)
|
115
|
+
|
116
|
+
elif isinstance(expr, graph_requests.DestinationNode):
|
117
|
+
_set_node_to_pb(expr, pb.path.destination)
|
118
|
+
|
119
|
+
elif isinstance(expr, graph_requests.AnyNode):
|
120
|
+
_set_node_to_pb(expr, pb.path.source)
|
121
|
+
pb.path.undirected = True
|
122
|
+
|
123
|
+
else: # pragma: nocover
|
124
|
+
# This is a trick so mypy generates an error if this branch can be reached,
|
125
|
+
# that is, if we are missing some ifs
|
126
|
+
_a: int = "a"
|
127
|
+
|
128
|
+
return pb
|
129
|
+
|
130
|
+
|
131
|
+
def _parse_relation_query(
|
132
|
+
expr: graph_requests.GraphRelationsQuery,
|
133
|
+
) -> nodereader_pb2.GraphQuery.PathQuery:
|
134
|
+
pb = nodereader_pb2.GraphQuery.PathQuery()
|
135
|
+
|
136
|
+
if isinstance(expr, graph_requests.And):
|
137
|
+
for op in expr.operands:
|
138
|
+
pb.bool_and.operands.append(_parse_relation_query(op))
|
139
|
+
|
140
|
+
elif isinstance(expr, graph_requests.Or):
|
141
|
+
for op in expr.operands:
|
142
|
+
pb.bool_or.operands.append(_parse_relation_query(op))
|
143
|
+
|
144
|
+
elif isinstance(expr, graph_requests.Not):
|
145
|
+
pb.bool_not.CopyFrom(_parse_relation_query(expr.operand))
|
146
|
+
|
147
|
+
elif isinstance(expr, graph_requests.Relation):
|
148
|
+
if expr.label is not None:
|
149
|
+
pb.path.relation.value = expr.label
|
150
|
+
|
151
|
+
else: # pragma: nocover
|
152
|
+
# This is a trick so mypy generates an error if this branch can be reached,
|
153
|
+
# that is, if we are missing some ifs
|
154
|
+
_a: int = "a"
|
155
|
+
|
156
|
+
return pb
|
157
|
+
|
158
|
+
|
159
|
+
def _set_node_to_pb(node: graph_requests.GraphNode, pb: nodereader_pb2.GraphQuery.Node):
|
160
|
+
if node.value is not None:
|
161
|
+
pb.value = node.value
|
162
|
+
if node.match == graph_requests.NodeMatchKind.EXACT:
|
163
|
+
pb.match_kind = nodereader_pb2.GraphQuery.Node.MatchKind.EXACT
|
164
|
+
|
165
|
+
elif node.match == graph_requests.NodeMatchKind.FUZZY:
|
166
|
+
pb.match_kind = nodereader_pb2.GraphQuery.Node.MatchKind.FUZZY
|
167
|
+
|
168
|
+
else: # pragma: nocover
|
169
|
+
# This is a trick so mypy generates an error if this branch can be reached,
|
170
|
+
# that is, if we are missing some ifs
|
171
|
+
_a: int = "a"
|
172
|
+
|
173
|
+
if node.type is not None:
|
174
|
+
pb.node_type = RelationNodeTypeMap[node.type]
|
175
|
+
|
176
|
+
if node.group is not None:
|
177
|
+
pb.node_subtype = node.group
|
nucliadb/search/search/shards.py
CHANGED
@@ -26,6 +26,8 @@ from grpc.aio import AioRpcError
|
|
26
26
|
from nucliadb.common.cluster.base import AbstractIndexNode
|
27
27
|
from nucliadb_protos.nodereader_pb2 import (
|
28
28
|
GetShardRequest,
|
29
|
+
GraphSearchRequest,
|
30
|
+
GraphSearchResponse,
|
29
31
|
SearchRequest,
|
30
32
|
SearchResponse,
|
31
33
|
SuggestRequest,
|
@@ -79,3 +81,16 @@ async def suggest_shard(node: AbstractIndexNode, shard: str, query: SuggestReque
|
|
79
81
|
req.shard = shard
|
80
82
|
with node_observer({"type": "suggest", "node_id": node.id}):
|
81
83
|
return await node.reader.Suggest(req) # type: ignore
|
84
|
+
|
85
|
+
|
86
|
+
@backoff.on_exception(
|
87
|
+
backoff.expo, Exception, jitter=None, factor=0.1, max_tries=3, giveup=should_giveup
|
88
|
+
)
|
89
|
+
async def graph_search_shard(
|
90
|
+
node: AbstractIndexNode, shard: str, query: GraphSearchRequest
|
91
|
+
) -> GraphSearchResponse:
|
92
|
+
req = GraphSearchRequest()
|
93
|
+
req.CopyFrom(query)
|
94
|
+
req.shard = shard
|
95
|
+
with node_observer({"type": "graph_search", "node_id": node.id}):
|
96
|
+
return await node.reader.GraphSearch(req) # type: ignore
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: nucliadb
|
3
|
-
Version: 6.3.1.
|
3
|
+
Version: 6.3.1.post3590
|
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.
|
24
|
-
Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.3.1.
|
25
|
-
Requires-Dist: nucliadb-protos>=6.3.1.
|
26
|
-
Requires-Dist: nucliadb-models>=6.3.1.
|
27
|
-
Requires-Dist: nidx-protos>=6.3.1.
|
23
|
+
Requires-Dist: nucliadb-telemetry[all]>=6.3.1.post3590
|
24
|
+
Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.3.1.post3590
|
25
|
+
Requires-Dist: nucliadb-protos>=6.3.1.post3590
|
26
|
+
Requires-Dist: nucliadb-models>=6.3.1.post3590
|
27
|
+
Requires-Dist: nidx-protos>=6.3.1.post3590
|
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
|
@@ -41,19 +41,19 @@ nucliadb/openapi.py,sha256=wDiw0dVEvTpJvbatkJ0JZLkKm9RItZT5PWRHjqRfqTA,2272
|
|
41
41
|
nucliadb/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
42
42
|
nucliadb/backups/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
43
43
|
nucliadb/backups/const.py,sha256=9vPAhLxQO_gNAjSdPxWuv3V66s9WcdpjOQ89CZlfmuk,1894
|
44
|
-
nucliadb/backups/create.py,sha256=
|
44
|
+
nucliadb/backups/create.py,sha256=w6KpjkTOpIoPVrtOZrxB99oMdWp6jYkyIJ1-qo_k4Mw,11230
|
45
45
|
nucliadb/backups/delete.py,sha256=1rnBhVUGYYZJXSZUrrgYMDZ5NyswEWkIA-G-crRCyHk,2404
|
46
46
|
nucliadb/backups/models.py,sha256=-hITU4Mv6AxePu12toBu_fjpEv6vVGcwNVxV22O9jQA,1273
|
47
47
|
nucliadb/backups/restore.py,sha256=wepEgv4vBN5yeiZU-f17PbuFV4xT4_SVKplNr8xSJrE,10001
|
48
48
|
nucliadb/backups/settings.py,sha256=SyzsInj1BRbBI0atg5IXWbMbOZ_eVg4eSQ3IcnUhCxQ,1357
|
49
49
|
nucliadb/backups/tasks.py,sha256=4_kOVJ2yCwMvDEpzJgTuTt75TNlpq5woyw9sTAcaSkw,4194
|
50
|
-
nucliadb/backups/utils.py,sha256=
|
50
|
+
nucliadb/backups/utils.py,sha256=_Vogjqcru5oqNZM-bZ0q7Ju79Bv1PD-LVFEa7Z-Q13I,1261
|
51
51
|
nucliadb/common/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
52
52
|
nucliadb/common/constants.py,sha256=QpigxJh_CtD85Evy0PtV5cVq6x0U_f9xfIcXz1ymkUg,869
|
53
53
|
nucliadb/common/counters.py,sha256=8lOi3A2HeLDDlcNaS2QT1SfD3350VPBjiY3FkmHH1V8,977
|
54
54
|
nucliadb/common/ids.py,sha256=4QjoIofes_vtKj2HsFWZf8VVIVWXxdkYtLpx1n618Us,8239
|
55
55
|
nucliadb/common/locking.py,sha256=RL0CabZVPzxHZyUjYeUyLvsJTm7W3J9o4fEgsY_ufNc,5896
|
56
|
-
nucliadb/common/nidx.py,sha256=
|
56
|
+
nucliadb/common/nidx.py,sha256=Xuh7qT3fTDiyBlXe40gXtk3URE0EoJHoi0BsSA5fNZU,10240
|
57
57
|
nucliadb/common/cluster/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
58
58
|
nucliadb/common/cluster/base.py,sha256=kklDqyvsubNX0W494ttl9f3E58lGaX6AXqAd8XX8ZHE,5522
|
59
59
|
nucliadb/common/cluster/exceptions.py,sha256=t7v_l93t44l2tQpdQXgO_w-c4YZRcaayOz1A2i0w4RQ,1258
|
@@ -197,11 +197,12 @@ nucliadb/search/run.py,sha256=aFb-CXRi_C8YMpP_ivNj8KW1BYhADj88y8K9Lr_nUPI,1402
|
|
197
197
|
nucliadb/search/settings.py,sha256=vem3EcyYlTPSim0kEK-xe-erF4BZg0CT_LAb8ZRQAE8,1684
|
198
198
|
nucliadb/search/utilities.py,sha256=9SsRDw0rJVXVoLBfF7rBb6q080h-thZc7u8uRcTiBeY,1037
|
199
199
|
nucliadb/search/api/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
200
|
-
nucliadb/search/api/v1/__init__.py,sha256=
|
200
|
+
nucliadb/search/api/v1/__init__.py,sha256=DH16OYnw9jQ38OpKlmdXeoq2j40ZPXZRtGvClKOkMhw,1239
|
201
201
|
nucliadb/search/api/v1/ask.py,sha256=F2dR3-swb3Xz8MfZPYL3G65KY2R_mgef4YVBbu8kLi4,4352
|
202
|
-
nucliadb/search/api/v1/catalog.py,sha256=
|
202
|
+
nucliadb/search/api/v1/catalog.py,sha256=MRiuawjKoWXdd-tptw8r8HyBhZ1JgdUYpau__69oij0,7709
|
203
203
|
nucliadb/search/api/v1/feedback.py,sha256=kNLc4dHz2SXHzV0PwC1WiRAwY88fDptPcP-kO0q-FrQ,2620
|
204
204
|
nucliadb/search/api/v1/find.py,sha256=l2dRg0eYngq52vyn9_z9iK7bdO7ufHQDnJWBZgMVrqY,9628
|
205
|
+
nucliadb/search/api/v1/graph.py,sha256=5APs0-W-jNQfH-mRLrdRkk6B_mnsJxLb68t0NE_KZUk,4238
|
205
206
|
nucliadb/search/api/v1/knowledgebox.py,sha256=rWhx3PYWryingu19qwwFDbVvVYynq5Ky23FSlzmTutQ,8721
|
206
207
|
nucliadb/search/api/v1/predict_proxy.py,sha256=QrGzo0hKjtmyGZ6pjlJHYAh4hxwVUIOTcVcerRCw7eE,3047
|
207
208
|
nucliadb/search/api/v1/router.py,sha256=mtT07rBZcVfpa49doaw9b1tj3sdi3qLH0gn9Io6NYM0,988
|
@@ -215,27 +216,28 @@ nucliadb/search/api/v1/resource/ingestion_agents.py,sha256=fqqRCd8Wc9GciS5P98lcn
|
|
215
216
|
nucliadb/search/api/v1/resource/search.py,sha256=s_si6iilqhmopEQ5GG5c7C_4QV3X8QneQyS5zP0d22I,5228
|
216
217
|
nucliadb/search/api/v1/resource/utils.py,sha256=-NjZqAQtFEXKpIh8ui5S26ItnJ5rzmmG0BHxGSS9QPw,1141
|
217
218
|
nucliadb/search/requesters/__init__.py,sha256=itSI7dtTwFP55YMX4iK7JzdMHS5CQVUiB1XzQu4UBh8,833
|
218
|
-
nucliadb/search/requesters/utils.py,sha256=
|
219
|
+
nucliadb/search/requesters/utils.py,sha256=BIJjfjJt3qClA6XRtqA7E5am5Re29CaY_R6QOuTG-24,7082
|
219
220
|
nucliadb/search/search/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
220
221
|
nucliadb/search/search/cache.py,sha256=n9vkN6Y6Xnr2RBJyoH0WzjzGTJOMfKekU9tfPTWWCPc,6810
|
221
222
|
nucliadb/search/search/cut.py,sha256=ytY0_GY7ocNjfxTb4aosxEp4ZfhQNDP--JkhEMGD298,1153
|
222
223
|
nucliadb/search/search/exceptions.py,sha256=klGLgAGGrXcSGix_W6418ZBMqDchAIGjN77ofkOScEI,1039
|
223
224
|
nucliadb/search/search/fetch.py,sha256=XJHIFnZmXM_8Kb37lb4lg1GYG7cZ1plT-qAIb_QziX4,6184
|
224
225
|
nucliadb/search/search/filters.py,sha256=1MkHlJjAQqoRCj7e5cEzK2HvBxGLE17I_omsjiklbtw,6476
|
225
|
-
nucliadb/search/search/find.py,sha256=
|
226
|
+
nucliadb/search/search/find.py,sha256=p7Odx3hjPwTsHEhQrVYsR_ufq0meMmCnQV0YihfOmlg,10237
|
226
227
|
nucliadb/search/search/find_merge.py,sha256=3FnzKFEnVemg6FO_6zveulbAU7klvsiPEBvLrpBBMg8,17450
|
228
|
+
nucliadb/search/search/graph_merge.py,sha256=7LzzU09HCFu6wm3LfgJ3Lm6Uuh_qPDmM2tWZS-fHmw8,3250
|
227
229
|
nucliadb/search/search/graph_strategy.py,sha256=gisL2GpbSIa_SucyOwEt7TWdqURyAQqxvD_-PkXQct8,32339
|
228
230
|
nucliadb/search/search/hydrator.py,sha256=-R37gCrGxkyaiHQalnTWHNG_FCx11Zucd7qA1vQCxuw,6985
|
229
231
|
nucliadb/search/search/ingestion_agents.py,sha256=NeJr4EEX-bvFFMGvXOOwLv8uU7NuQ-ntJnnrhnKfMzY,3174
|
230
232
|
nucliadb/search/search/merge.py,sha256=aUn6f5XnwWzUFhVC6uBqHE8NKdlfgw_xcTo57rS23U8,22950
|
231
233
|
nucliadb/search/search/metrics.py,sha256=GGGtXHLhK79_ESV277xkBVjcaMURXHCxYG0EdGamUd8,2886
|
232
234
|
nucliadb/search/search/paragraphs.py,sha256=pNAEiYqJGGUVcEf7xf-PFMVqz0PX4Qb-WNG-_zPGN2o,7799
|
233
|
-
nucliadb/search/search/pgcatalog.py,sha256=
|
235
|
+
nucliadb/search/search/pgcatalog.py,sha256=s_J98fsX_RuFXwpejpkGqG-tD9ELuzz4YQ6U3ew5h2g,9313
|
234
236
|
nucliadb/search/search/predict_proxy.py,sha256=IFI3v_ODz2_UU1XZnyaD391fE7-2C0npSmj_HmDvzS4,3123
|
235
237
|
nucliadb/search/search/query.py,sha256=CCz58Cs_VKxbwGO6VdhOzl9HXwKny2hfH2llJVR9emM,29859
|
236
238
|
nucliadb/search/search/rank_fusion.py,sha256=tRGo_KlsFsVx1CQEy1iqQ6f0T1Dq1kf0axDXHuuzvvM,6946
|
237
239
|
nucliadb/search/search/rerankers.py,sha256=3vep4EOVNeDJGsMdx-1g6Ar4ZGJG3IHym3HkxnbwtAQ,7321
|
238
|
-
nucliadb/search/search/shards.py,sha256=
|
240
|
+
nucliadb/search/search/shards.py,sha256=OEtN1p9WX_cMX8t-myaafpmFAPTpUEOutR7z1sDuNcY,3242
|
239
241
|
nucliadb/search/search/summarize.py,sha256=ksmYPubEQvAQgfPdZHfzB_rR19B2ci4IYZ6jLdHxZo8,4996
|
240
242
|
nucliadb/search/search/utils.py,sha256=iF2tbBA56gRMJH1TlE2hMrqeXqjoeOPt4KgRdp2m9Ek,3313
|
241
243
|
nucliadb/search/search/chat/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
@@ -245,13 +247,15 @@ nucliadb/search/search/chat/images.py,sha256=PA8VWxT5_HUGfW1ULhKTK46UBsVyINtWWqE
|
|
245
247
|
nucliadb/search/search/chat/prompt.py,sha256=Jnja-Ss7skgnnDY8BymVfdeYsFPnIQFL8tEvcRXTKUE,47356
|
246
248
|
nucliadb/search/search/chat/query.py,sha256=0IoeW-JNaRBe2d9C3bXNfkYpzmsN_IIg3U4Vqb8eOEk,16485
|
247
249
|
nucliadb/search/search/query_parser/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
248
|
-
nucliadb/search/search/query_parser/catalog.py,sha256=PtH5nb6UTzH8l7Lmdd1RgLVFsn9CN5M5-JkVq9YeR4k,7116
|
249
250
|
nucliadb/search/search/query_parser/exceptions.py,sha256=szAOXUZ27oNY-OSa9t2hQ5HHkQQC0EX1FZz_LluJHJE,1224
|
250
251
|
nucliadb/search/search/query_parser/fetcher.py,sha256=jhr__J0KmAzjdsTTadWQmD9qf6lZvqlKAfZdYjZH_UY,15742
|
251
252
|
nucliadb/search/search/query_parser/filter_expression.py,sha256=rws5vsKTofX2iMUK4yvjmLZFxtcbWbyhIcwen4j0rQg,6578
|
252
|
-
nucliadb/search/search/query_parser/models.py,sha256=
|
253
|
+
nucliadb/search/search/query_parser/models.py,sha256=7czH-jHskl9axEnZV5XnQY8cyN_fs14Cpivzd5aaSxc,2686
|
253
254
|
nucliadb/search/search/query_parser/old_filters.py,sha256=-zbfN-RsXoj_DRjh3Lfp-wShwFXgkISawzVptVzja-A,9071
|
254
|
-
nucliadb/search/search/query_parser/
|
255
|
+
nucliadb/search/search/query_parser/parsers/__init__.py,sha256=ySCNSdbesLXGZyR88919njulA6UE10_3PhqMG_Yj1o4,1034
|
256
|
+
nucliadb/search/search/query_parser/parsers/catalog.py,sha256=XdBiTweGTQkj8m_V_i2xbwp7P5pPO8K1Tud692XKhMw,7149
|
257
|
+
nucliadb/search/search/query_parser/parsers/find.py,sha256=q3wH_i0DGceeKckYEH3c5MqM5EvRiMCL7r-6nCAId9Q,4666
|
258
|
+
nucliadb/search/search/query_parser/parsers/graph.py,sha256=4cR-Y_ZUX-QNYhL6DV2tanmBlSb0ducf4J3hb9VXLh8,6261
|
255
259
|
nucliadb/standalone/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
256
260
|
nucliadb/standalone/api_router.py,sha256=hgq9FXpihzgjHkwcVGfGCSwyXy67fqXTfLFHuINzIi0,5567
|
257
261
|
nucliadb/standalone/app.py,sha256=mAApNK_iVsQgJyd-mtwCeZq5csSimwnXmlQGH9a70pE,5586
|
@@ -347,8 +351,8 @@ nucliadb/writer/tus/local.py,sha256=7jYa_w9b-N90jWgN2sQKkNcomqn6JMVBOVeDOVYJHto,
|
|
347
351
|
nucliadb/writer/tus/s3.py,sha256=vF0NkFTXiXhXq3bCVXXVV-ED38ECVoUeeYViP8uMqcU,8357
|
348
352
|
nucliadb/writer/tus/storage.py,sha256=ToqwjoYnjI4oIcwzkhha_MPxi-k4Jk3Lt55zRwaC1SM,2903
|
349
353
|
nucliadb/writer/tus/utils.py,sha256=MSdVbRsRSZVdkaum69_0wku7X3p5wlZf4nr6E0GMKbw,2556
|
350
|
-
nucliadb-6.3.1.
|
351
|
-
nucliadb-6.3.1.
|
352
|
-
nucliadb-6.3.1.
|
353
|
-
nucliadb-6.3.1.
|
354
|
-
nucliadb-6.3.1.
|
354
|
+
nucliadb-6.3.1.post3590.dist-info/METADATA,sha256=cnyGLiXObJPzQkmY-I7Ilyq2TvPG9l48K1TrnPhqreQ,4291
|
355
|
+
nucliadb-6.3.1.post3590.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
356
|
+
nucliadb-6.3.1.post3590.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
|
357
|
+
nucliadb-6.3.1.post3590.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
|
358
|
+
nucliadb-6.3.1.post3590.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|