nuclia 4.8.10__py3-none-any.whl → 4.9.0__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.
- nuclia/lib/models.py +2 -2
- nuclia/sdk/search.py +56 -0
- nuclia/tests/fixtures.py +2 -2
- nuclia/tests/test_kb/test_conversation.py +0 -5
- nuclia/tests/test_kb/test_graph.py +40 -0
- {nuclia-4.8.10.dist-info → nuclia-4.9.0.dist-info}/METADATA +3 -3
- {nuclia-4.8.10.dist-info → nuclia-4.9.0.dist-info}/RECORD +11 -11
- {nuclia-4.8.10.dist-info → nuclia-4.9.0.dist-info}/WHEEL +0 -0
- {nuclia-4.8.10.dist-info → nuclia-4.9.0.dist-info}/entry_points.txt +0 -0
- {nuclia-4.8.10.dist-info → nuclia-4.9.0.dist-info}/licenses/LICENSE +0 -0
- {nuclia-4.8.10.dist-info → nuclia-4.9.0.dist-info}/top_level.txt +0 -0
nuclia/lib/models.py
CHANGED
@@ -48,7 +48,7 @@ class GraphRelation(BaseModel):
|
|
48
48
|
destination: GraphEntity
|
49
49
|
|
50
50
|
def to_relation(self) -> Relation:
|
51
|
-
return Relation.
|
51
|
+
return Relation.model_validate(
|
52
52
|
{
|
53
53
|
"from": self.source.to_dict(),
|
54
54
|
"to": self.destination.to_dict(),
|
@@ -60,6 +60,6 @@ class GraphRelation(BaseModel):
|
|
60
60
|
|
61
61
|
def get_relation(relation: Union[GraphRelation, dict]) -> GraphRelation:
|
62
62
|
if isinstance(relation, dict):
|
63
|
-
return GraphRelation.
|
63
|
+
return GraphRelation.model_validate(relation)
|
64
64
|
else:
|
65
65
|
return relation
|
nuclia/sdk/search.py
CHANGED
@@ -20,6 +20,8 @@ from nucliadb_models.search import (
|
|
20
20
|
SyncAskResponse,
|
21
21
|
ChatModel,
|
22
22
|
)
|
23
|
+
from nucliadb_models.graph.requests import GraphSearchRequest
|
24
|
+
from nucliadb_models.graph.responses import GraphSearchResponse
|
23
25
|
from pydantic import ValidationError
|
24
26
|
|
25
27
|
from nuclia.data import get_async_auth, get_auth
|
@@ -331,6 +333,33 @@ class NucliaSearch:
|
|
331
333
|
result.tokens = ask_response.metadata.tokens.model_dump()
|
332
334
|
return result
|
333
335
|
|
336
|
+
@kb
|
337
|
+
def graph(
|
338
|
+
self,
|
339
|
+
*,
|
340
|
+
query: Union[dict, GraphSearchRequest],
|
341
|
+
**kwargs,
|
342
|
+
) -> GraphSearchResponse:
|
343
|
+
"""
|
344
|
+
Perform a graph path query.
|
345
|
+
|
346
|
+
See https://docs.nuclia.dev/docs/api#tag/Search/operation/graph_search_knowledgebox_kb__kbid__graph_post
|
347
|
+
"""
|
348
|
+
ndb: NucliaDBClient = kwargs["ndb"]
|
349
|
+
|
350
|
+
if isinstance(query, GraphSearchRequest):
|
351
|
+
req = query
|
352
|
+
elif isinstance(query, dict):
|
353
|
+
try:
|
354
|
+
req = GraphSearchRequest.model_validate(query)
|
355
|
+
except ValidationError:
|
356
|
+
logger.exception("Error validating query")
|
357
|
+
raise
|
358
|
+
else:
|
359
|
+
raise Exception(f"Invalid query: '{query}'")
|
360
|
+
|
361
|
+
return ndb.ndb.graph_search(req, kbid=ndb.kbid)
|
362
|
+
|
334
363
|
|
335
364
|
class AsyncNucliaSearch:
|
336
365
|
"""
|
@@ -659,3 +688,30 @@ class AsyncNucliaSearch:
|
|
659
688
|
else: # pragma: no cover
|
660
689
|
warnings.warn(f"Unknown ask stream item type: {ask_response_item.type}")
|
661
690
|
return result
|
691
|
+
|
692
|
+
@kb
|
693
|
+
async def graph(
|
694
|
+
self,
|
695
|
+
*,
|
696
|
+
query: Union[dict, GraphSearchRequest],
|
697
|
+
**kwargs,
|
698
|
+
) -> GraphSearchResponse:
|
699
|
+
"""
|
700
|
+
Perform a graph path query.
|
701
|
+
|
702
|
+
See https://docs.nuclia.dev/docs/api#tag/Search/operation/graph_search_knowledgebox_kb__kbid__graph_post
|
703
|
+
"""
|
704
|
+
ndb: AsyncNucliaDBClient = kwargs["ndb"]
|
705
|
+
|
706
|
+
if isinstance(query, GraphSearchRequest):
|
707
|
+
req = query
|
708
|
+
elif isinstance(query, dict):
|
709
|
+
try:
|
710
|
+
req = GraphSearchRequest.model_validate(query)
|
711
|
+
except ValidationError:
|
712
|
+
logger.exception("Error validating query")
|
713
|
+
raise
|
714
|
+
else:
|
715
|
+
raise Exception(f"Invalid query: '{query}'")
|
716
|
+
|
717
|
+
return await ndb.ndb.graph_search(req, kbid=ndb.kbid)
|
nuclia/tests/fixtures.py
CHANGED
@@ -49,8 +49,8 @@ def testing_config(testing_kb, testing_nua, testing_user):
|
|
49
49
|
nuclia_auth._config.set_default_kb(TESTING_KBID)
|
50
50
|
nuclia_auth._config.set_default_nua(client_id)
|
51
51
|
|
52
|
-
|
53
|
-
|
52
|
+
yield
|
53
|
+
reset_config_file()
|
54
54
|
|
55
55
|
|
56
56
|
@pytest.fixture(autouse=True)
|
@@ -2,7 +2,6 @@ import os
|
|
2
2
|
|
3
3
|
from nucliadb_sdk.v2.exceptions import NotFoundError
|
4
4
|
|
5
|
-
from nuclia.sdk.kb import NucliaKB
|
6
5
|
from nuclia.sdk.resource import NucliaResource
|
7
6
|
from nuclia.sdk.upload import NucliaUpload
|
8
7
|
|
@@ -10,7 +9,6 @@ path = f"{os.path.dirname(__file__)}/../assets/conversation.json"
|
|
10
9
|
|
11
10
|
|
12
11
|
def test_conversation(testing_config):
|
13
|
-
nkb = NucliaKB()
|
14
12
|
nresource = NucliaResource()
|
15
13
|
try:
|
16
14
|
res = nresource.get(slug="conversation1")
|
@@ -18,9 +16,6 @@ def test_conversation(testing_config):
|
|
18
16
|
except NotFoundError:
|
19
17
|
pass
|
20
18
|
|
21
|
-
res = nkb.list()
|
22
|
-
assert len(res.resources) == 2
|
23
|
-
|
24
19
|
nu = NucliaUpload()
|
25
20
|
nu.conversation(path=path, slug="conversation1", field="c1")
|
26
21
|
|
@@ -6,6 +6,13 @@ from time import sleep
|
|
6
6
|
|
7
7
|
def test_graph(testing_config):
|
8
8
|
nkb = NucliaKB()
|
9
|
+
|
10
|
+
# ensure KB is clean
|
11
|
+
try:
|
12
|
+
nkb.delete_graph(slug="graph1")
|
13
|
+
except NotFoundError:
|
14
|
+
pass
|
15
|
+
|
9
16
|
nkb.add_graph(
|
10
17
|
slug="graph1",
|
11
18
|
graph=[
|
@@ -28,6 +35,25 @@ def test_graph(testing_config):
|
|
28
35
|
)
|
29
36
|
relations = nkb.get_graph(slug="graph1")
|
30
37
|
assert len(relations) == 3
|
38
|
+
|
39
|
+
# XXX: sometimes, nucliadb needs some more time to index the graph. We retry
|
40
|
+
# some times and fail if that keeps hapenning
|
41
|
+
RETRIES = 5
|
42
|
+
DELAY = 0.5
|
43
|
+
for _ in range(RETRIES):
|
44
|
+
paths = nkb.search.graph(
|
45
|
+
query={"query": {"prop": "path", "source": {"value": "Alice"}}}
|
46
|
+
)
|
47
|
+
try:
|
48
|
+
assert len(paths.paths) == 2
|
49
|
+
except AssertionError:
|
50
|
+
# wait for a bit before retrying
|
51
|
+
print("Graph was not indexed yet, waiting a bit...")
|
52
|
+
sleep(DELAY)
|
53
|
+
else:
|
54
|
+
break
|
55
|
+
assert len(paths.paths) == 2
|
56
|
+
|
31
57
|
nkb.update_graph(
|
32
58
|
slug="graph1",
|
33
59
|
graph=[
|
@@ -40,6 +66,20 @@ def test_graph(testing_config):
|
|
40
66
|
)
|
41
67
|
relations = nkb.get_graph(slug="graph1")
|
42
68
|
assert len(relations) == 4
|
69
|
+
|
70
|
+
for _ in range(RETRIES):
|
71
|
+
paths = nkb.search.graph(
|
72
|
+
query={"query": {"prop": "path", "source": {"value": "Victor"}}}
|
73
|
+
)
|
74
|
+
try:
|
75
|
+
assert len(paths.paths) == 1
|
76
|
+
except AssertionError:
|
77
|
+
print("Graph was not indexed yet, waiting a bit...")
|
78
|
+
sleep(DELAY)
|
79
|
+
else:
|
80
|
+
break
|
81
|
+
assert len(paths.paths) == 1
|
82
|
+
|
43
83
|
nkb.delete_graph(slug="graph1")
|
44
84
|
try:
|
45
85
|
sleep(0.5)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: nuclia
|
3
|
-
Version: 4.
|
3
|
+
Version: 4.9.0
|
4
4
|
Summary: Nuclia Python SDK
|
5
5
|
Author-email: Nuclia <info@nuclia.com>
|
6
6
|
License-Expression: MIT
|
@@ -24,8 +24,8 @@ Requires-Dist: requests
|
|
24
24
|
Requires-Dist: httpx
|
25
25
|
Requires-Dist: httpcore>=1.0.0
|
26
26
|
Requires-Dist: prompt_toolkit
|
27
|
-
Requires-Dist: nucliadb_sdk<7,>=6.
|
28
|
-
Requires-Dist: nucliadb_models<7,>=6.
|
27
|
+
Requires-Dist: nucliadb_sdk<7,>=6.5
|
28
|
+
Requires-Dist: nucliadb_models<7,>=6.5
|
29
29
|
Requires-Dist: nuclia-models>=0.41.1
|
30
30
|
Requires-Dist: tqdm
|
31
31
|
Requires-Dist: aiofiles
|
@@ -10,7 +10,7 @@ nuclia/cli/utils.py,sha256=iZ3P8juBdAGvaRUd2BGz7bpUXNDHdPrC5p876yyZ2Cs,1223
|
|
10
10
|
nuclia/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
11
|
nuclia/lib/conversations.py,sha256=M6qhL9NPEKroYF767S-Q2XWokRrjX02kpYTzRvZKwUE,149
|
12
12
|
nuclia/lib/kb.py,sha256=jV-L8-a5oFVHIbFfeGO17hXf2IQk9UuW-9fq5D3LO6Y,28508
|
13
|
-
nuclia/lib/models.py,sha256=
|
13
|
+
nuclia/lib/models.py,sha256=ekEQrVIFU3aFvt60yQh-zpWkGNORBMSc7c5Hd_VzPzI,1564
|
14
14
|
nuclia/lib/nua.py,sha256=sUVFdCjvLigTqUUhILywdHpiC0qKCtKPABn5kUXfuxQ,27064
|
15
15
|
nuclia/lib/nua_chat.py,sha256=ApL1Y1FWvAVUt-Y9a_8TUSJIhg8-UmBSy8TlDPn6tD8,3874
|
16
16
|
nuclia/lib/nua_responses.py,sha256=9WRGpvvhA2ZOyOv9kzX1zI7C3ypM8ySqciVYCSibUjo,12724
|
@@ -31,18 +31,18 @@ nuclia/sdk/predict.py,sha256=KF7iT2aasaB9DIEAwqktXbOl2H_Y_ne-6-SEErN7YOk,9095
|
|
31
31
|
nuclia/sdk/process.py,sha256=WuNnqaWprp-EABWDC_z7O2woesGIlYWnDUKozh7Ibr4,2241
|
32
32
|
nuclia/sdk/remi.py,sha256=BEb3O9R2jOFlOda4vjFucKKGO1c2eTkqYZdFlIy3Zmo,4357
|
33
33
|
nuclia/sdk/resource.py,sha256=0lSvD4e1FpN5iM9W295dOKLJ8hsXfIe8HKdo0HsVg20,13976
|
34
|
-
nuclia/sdk/search.py,sha256=
|
34
|
+
nuclia/sdk/search.py,sha256=1mLJzDO-W3ObReDL1xK8zgjIxkdpuIhyf87-L4bISKQ,25180
|
35
35
|
nuclia/sdk/task.py,sha256=UawH-7IneRIGVOiLdDQ2vDBwe5eI51UXRbLRRVeu3C4,6095
|
36
36
|
nuclia/sdk/upload.py,sha256=ZBzYROF3yP-77HcaR06OBsFjJAbTOCvF-nlxaqQZsT4,22720
|
37
37
|
nuclia/sdk/zones.py,sha256=1ARWrTsTuzj8zguanpX3OaIw-3Qq_ULS_g4GG2mHxOA,342
|
38
38
|
nuclia/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
39
|
nuclia/tests/conftest.py,sha256=-Gv9Q20tBVQNNWqWHGNmzkXJpijmgTdcvNnaRAUluGk,115
|
40
|
-
nuclia/tests/fixtures.py,sha256=
|
40
|
+
nuclia/tests/fixtures.py,sha256=rcGGbtxQbGK9vR9efL7BsE1ugJl15QQDIxUyFZLfv-E,1795
|
41
41
|
nuclia/tests/assets/conversation.json,sha256=jLmVngHEW8QdAzSMa-MYgbJgYxOO8tHq6Ia029-CD0E,348
|
42
42
|
nuclia/tests/test_kb/test_backup.py,sha256=67fAw1C_NB363G-wuI9LnSH6nG_YrYs-uBcFyBx6Peg,2932
|
43
|
-
nuclia/tests/test_kb/test_conversation.py,sha256=
|
43
|
+
nuclia/tests/test_kb/test_conversation.py,sha256=plsWY_gEhK3P4CsIO9jkBmimZk3UDGeMYPu7YVFeuIQ,727
|
44
44
|
nuclia/tests/test_kb/test_export_import.py,sha256=lQEww2jFNHZYcudFJqcHhoWAPrmtvvnPvcFqrijxLbo,1019
|
45
|
-
nuclia/tests/test_kb/test_graph.py,sha256=
|
45
|
+
nuclia/tests/test_kb/test_graph.py,sha256=ecAB-lWqm3_796HUuF-fSpGzlhsXV9NGZnAjvxXANps,2540
|
46
46
|
nuclia/tests/test_kb/test_labels.py,sha256=IUdTq4mzv0OrOkwBWWy4UwKGKyJybtoHrgvXr676vyY,961
|
47
47
|
nuclia/tests/test_kb/test_logs.py,sha256=Z9ELtiiU9NniITJzeWt92GCcERKYy9Nwc_fUVPboRU0,3121
|
48
48
|
nuclia/tests/test_kb/test_remi.py,sha256=OX5N-MHbgcwpLg6fBjrAK_KhqkMspJo_VKQHCBCayZ8,2080
|
@@ -61,9 +61,9 @@ nuclia/tests/test_nucliadb/test_crud.py,sha256=GuY76HRvt2DFaNgioKm5n0Aco1HnG7zzV
|
|
61
61
|
nuclia/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
62
62
|
nuclia/tests/unit/test_export_import.py,sha256=xo_wVbjUnNlVV65ZGH7LtZ38qy39EkJp2hjOuTHC1nU,980
|
63
63
|
nuclia/tests/unit/test_nua_responses.py,sha256=t_hIdVztTi27RWvpfTJUYcCL0lpKdZFegZIwLdaPNh8,319
|
64
|
-
nuclia-4.
|
65
|
-
nuclia-4.
|
66
|
-
nuclia-4.
|
67
|
-
nuclia-4.
|
68
|
-
nuclia-4.
|
69
|
-
nuclia-4.
|
64
|
+
nuclia-4.9.0.dist-info/licenses/LICENSE,sha256=Ops2LTti_HJtpmWcanuUTdTY3vKDR1myJ0gmGBKC0FA,1063
|
65
|
+
nuclia-4.9.0.dist-info/METADATA,sha256=ZHT0wCR1AhZtfnWdcD-uSmfNkb8QznVDuWRt_2f6yP8,2337
|
66
|
+
nuclia-4.9.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
67
|
+
nuclia-4.9.0.dist-info/entry_points.txt,sha256=iZHOyXPNS54r3eQmdi5So20xO1gudI9K2oP4sQsCJRw,46
|
68
|
+
nuclia-4.9.0.dist-info/top_level.txt,sha256=cqn_EitXOoXOSUvZnd4q6QGrhm04pg8tLAZtem-Zfdo,7
|
69
|
+
nuclia-4.9.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|