nuclia 4.8.9__tar.gz → 4.8.10__tar.gz
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-4.8.9 → nuclia-4.8.10}/CHANGELOG.md +6 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/PKG-INFO +2 -2
- nuclia-4.8.10/VERSION +1 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/11-activity-log.md +13 -15
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/lib/kb.py +6 -90
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/logs.py +25 -59
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_kb/test_logs.py +35 -20
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia.egg-info/PKG-INFO +2 -2
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia.egg-info/requires.txt +1 -1
- {nuclia-4.8.9 → nuclia-4.8.10}/pyproject.toml +1 -1
- {nuclia-4.8.9 → nuclia-4.8.10}/uv.lock +4 -4
- nuclia-4.8.9/VERSION +0 -1
- {nuclia-4.8.9 → nuclia-4.8.10}/.gitignore +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/LICENSE +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/MANIFEST.in +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/Makefile +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/README.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/01-README.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/02-auth.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/03-kb.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/04-upload.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/05-search.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/06-read.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/07-nua.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/08-import-export.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/09-kb-backup.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/10-manage.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/12-da-agents.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/docs/13-ai-agents.md +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/__init__.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/cli/__init__.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/cli/run.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/cli/utils.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/config.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/data.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/decorators.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/exceptions.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/lib/__init__.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/lib/conversations.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/lib/models.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/lib/nua.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/lib/nua_chat.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/lib/nua_responses.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/lib/utils.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/py.typed +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/__init__.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/accounts.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/agent.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/auth.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/backup.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/export_import.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/kb.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/kbs.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/logger.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/nua.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/nucliadb.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/predict.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/process.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/remi.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/resource.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/search.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/task.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/upload.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/sdk/zones.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/__init__.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/assets/conversation.json +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/conftest.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/fixtures.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_kb/test_backup.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_kb/test_conversation.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_kb/test_export_import.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_kb/test_graph.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_kb/test_labels.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_kb/test_remi.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_kb/test_resource.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_kb/test_search.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_kb/test_tasks.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_manage/__init__.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_manage/test_account.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_manage/test_auth.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_manage/test_kb.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_nua/__init__.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_nua/test_agent.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_nua/test_predict.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_nucliadb/__init__.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/test_nucliadb/test_crud.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/unit/__init__.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/unit/test_export_import.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia/tests/unit/test_nua_responses.py +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia.egg-info/SOURCES.txt +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia.egg-info/dependency_links.txt +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia.egg-info/entry_points.txt +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/nuclia.egg-info/top_level.txt +0 -0
- {nuclia-4.8.9 → nuclia-4.8.10}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: nuclia
|
3
|
-
Version: 4.8.
|
3
|
+
Version: 4.8.10
|
4
4
|
Summary: Nuclia Python SDK
|
5
5
|
Author-email: Nuclia <info@nuclia.com>
|
6
6
|
License-Expression: MIT
|
@@ -26,7 +26,7 @@ Requires-Dist: httpcore>=1.0.0
|
|
26
26
|
Requires-Dist: prompt_toolkit
|
27
27
|
Requires-Dist: nucliadb_sdk<7,>=6.4
|
28
28
|
Requires-Dist: nucliadb_models<7,>=6.4
|
29
|
-
Requires-Dist: nuclia-models>=0.
|
29
|
+
Requires-Dist: nuclia-models>=0.41.1
|
30
30
|
Requires-Dist: tqdm
|
31
31
|
Requires-Dist: aiofiles
|
32
32
|
Requires-Dist: backoff
|
nuclia-4.8.10/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
4.8.10
|
@@ -35,7 +35,7 @@ See the examples for more information
|
|
35
35
|
|
36
36
|
#### Event-Specific Fields
|
37
37
|
- `SEARCH` events: Common fields + `question`, `resources_count`, `filter`, `learning_id`
|
38
|
-
- `
|
38
|
+
- `ASK` events: Common fields + Search fields + `rephrased_question`, `answer`, `retrieved_context`, `chat_history`, `feedback_good`, `feedback_comment`, `model`, `rag_strategies_names`, `rag_strategies`, `status`, `time_to_first_char`
|
39
39
|
|
40
40
|
|
41
41
|
### Query Examples
|
@@ -43,7 +43,7 @@ See the examples for more information
|
|
43
43
|
#### CLI Example
|
44
44
|
|
45
45
|
```bash
|
46
|
-
nuclia kb logs query --type=
|
46
|
+
nuclia kb logs query --type=ASK --query='{
|
47
47
|
"year_month": "2024-10",
|
48
48
|
"show": ["id", "date", "question", "answer", "feedback_good"],
|
49
49
|
"filters": {
|
@@ -58,11 +58,10 @@ nuclia kb logs query --type=CHAT --query='{
|
|
58
58
|
|
59
59
|
```python
|
60
60
|
from nuclia import sdk
|
61
|
-
from
|
62
|
-
from nuclia_models.events.activity_logs import ActivityLogsChatQuery, Pagination
|
61
|
+
from nuclia_models.events.activity_logs import ActivityLogsAskQuery, EventType, Pagination
|
63
62
|
|
64
63
|
kb = sdk.NucliaKB()
|
65
|
-
query =
|
64
|
+
query = ActivityLogsAskQuery(
|
66
65
|
year_month="2024-10",
|
67
66
|
show=["id", "date", "question", "answer"],
|
68
67
|
filters={
|
@@ -71,7 +70,7 @@ query = ActivityLogsChatQuery(
|
|
71
70
|
},
|
72
71
|
pagination=Pagination(limit=10)
|
73
72
|
)
|
74
|
-
kb.logs.query(type=
|
73
|
+
kb.logs.query(type=EventType.ASK, query=query)
|
75
74
|
```
|
76
75
|
### Special Field: `audit_metadata`
|
77
76
|
The `audit_metadata` field is a customizable dictionary. Use the `key` operator to target specific keys within the dictionary.
|
@@ -103,7 +102,7 @@ The `audit_metadata` field is a customizable dictionary. Use the `key` operator
|
|
103
102
|
Request download and wait until the download url is generated
|
104
103
|
|
105
104
|
```bash
|
106
|
-
>>> nuclia kb logs download --wait --type=
|
105
|
+
>>> nuclia kb logs download --wait --type=ASK --format=NDJSON --query='{
|
107
106
|
"year_month": "2024-10",
|
108
107
|
"show": ["id", "date", "question", "answer", "feedback_good"],
|
109
108
|
"filters": {
|
@@ -119,7 +118,7 @@ download_url=https://your-download-url
|
|
119
118
|
|
120
119
|
Request download and ask to be notified
|
121
120
|
```bash
|
122
|
-
>>> nuclia kb logs download --type=
|
121
|
+
>>> nuclia kb logs download --type=ASK --format=NDJSON --query='{
|
123
122
|
"year_month": "2024-10",
|
124
123
|
"show": ["id", "date", "question", "answer", "feedback_good"],
|
125
124
|
"filters": {
|
@@ -136,7 +135,7 @@ download_url=null
|
|
136
135
|
```
|
137
136
|
Request download and poll for the status
|
138
137
|
```bash
|
139
|
-
>>> nuclia kb logs download --type=
|
138
|
+
>>> nuclia kb logs download --type=ASK --format=NDJSON --query='{
|
140
139
|
"year_month": "2024-10",
|
141
140
|
"show": ["id", "date", "question", "answer", "feedback_good"],
|
142
141
|
"filters": {
|
@@ -159,11 +158,10 @@ download_url=https://your-download-url
|
|
159
158
|
|
160
159
|
```python
|
161
160
|
from nuclia import sdk
|
162
|
-
from
|
163
|
-
from nuclia_models.events.activity_logs import DownloadActivityLogsChatQuery
|
161
|
+
from nuclia_models.events.activity_logs import DownloadActivityLogsAskQuery, EventType
|
164
162
|
|
165
163
|
kb = sdk.NucliaKB()
|
166
|
-
query =
|
164
|
+
query = DownloadActivityLogsAskQuery(
|
167
165
|
year_month="2024-10",
|
168
166
|
show=["id", "date", "question", "answer"],
|
169
167
|
filters={
|
@@ -171,7 +169,7 @@ query = DownloadActivityLogsChatQuery(
|
|
171
169
|
"feedback_good": {"eq": True}
|
172
170
|
},
|
173
171
|
)
|
174
|
-
request = kb.logs.download(type=
|
172
|
+
request = kb.logs.download(type=EventType.ASK, query=query, wait=True)
|
175
173
|
return request.download_url
|
176
174
|
```
|
177
175
|
|
@@ -182,7 +180,7 @@ The REMi module provides tools to monitor the quality of your RAG pipeline to ge
|
|
182
180
|
|
183
181
|
## REMi Query
|
184
182
|
|
185
|
-
Use `remi query` to retrieve a list of
|
183
|
+
Use `remi query` to retrieve a list of ask activity logs that match specified criteria for REMi scores.
|
186
184
|
|
187
185
|
### Basic Query
|
188
186
|
|
@@ -284,7 +282,7 @@ kb.remi.query(
|
|
284
282
|
|
285
283
|
### REMi Get
|
286
284
|
|
287
|
-
Use `remi get_event` to fetch detailed information for a specific
|
285
|
+
Use `remi get_event` to fetch detailed information for a specific ask activity log. This command is useful for retrieving full context and score details of an entry obtained from a previous REMi query.
|
288
286
|
|
289
287
|
#### CLI Example
|
290
288
|
```bash
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import base64
|
2
|
-
import csv
|
3
2
|
import os
|
4
3
|
from enum import Enum
|
5
4
|
from typing import Dict, Optional, Union
|
@@ -15,10 +14,10 @@ from tqdm import tqdm
|
|
15
14
|
from nuclia_models.events.activity_logs import ( # type: ignore
|
16
15
|
ActivityLogsQuery,
|
17
16
|
ActivityLogsSearchQuery,
|
18
|
-
|
17
|
+
ActivityLogsAskQuery,
|
19
18
|
DownloadActivityLogsQuery,
|
20
19
|
DownloadActivityLogsSearchQuery,
|
21
|
-
|
20
|
+
DownloadActivityLogsAskQuery,
|
22
21
|
EventType,
|
23
22
|
DownloadFormat,
|
24
23
|
)
|
@@ -46,11 +45,9 @@ DOWNLOAD_EXPORT_URL = "/export/{export_id}"
|
|
46
45
|
DOWNLOAD_URL = "/{uri}"
|
47
46
|
TUS_UPLOAD_RESOURCE_URL = "/resource/{rid}/file/{field}/tusupload"
|
48
47
|
TUS_UPLOAD_URL = "/tusupload"
|
49
|
-
LEGACY_ACTIVITY_LOG_URL = "/activity/download?type={type}&month={month}"
|
50
48
|
ACTIVITY_LOG_URL = "/activity/{type}/query/download"
|
51
49
|
ACTIVITY_LOG_DOWNLOAD_REQUEST_URL = "/activity/download_request/{request_id}"
|
52
50
|
ACTIVITY_LOG_QUERY_URL = "/activity/{type}/query"
|
53
|
-
FEEDBACK_LOG_URL = "/feedback/{month}"
|
54
51
|
NOTIFICATIONS = "/notifications"
|
55
52
|
REMI_QUERY_URL = "/remi/query"
|
56
53
|
REMI_EVENT_URL = "/remi/events/{event_id}"
|
@@ -73,23 +70,6 @@ class Environment(str, Enum):
|
|
73
70
|
OSS = "OSS"
|
74
71
|
|
75
72
|
|
76
|
-
class LogType(str, Enum):
|
77
|
-
# Nucliadb
|
78
|
-
VISITED = "visited"
|
79
|
-
MODIFIED = "modified"
|
80
|
-
DELETED = "deleted"
|
81
|
-
NEW = "new"
|
82
|
-
SEARCH = "search"
|
83
|
-
SUGGEST = "suggest"
|
84
|
-
INDEXED = "indexed"
|
85
|
-
CHAT = "chat"
|
86
|
-
# Tasks
|
87
|
-
STARTED = "started"
|
88
|
-
STOPPED = "stopped"
|
89
|
-
# Processor
|
90
|
-
PROCESSED = "processed"
|
91
|
-
|
92
|
-
|
93
73
|
class BaseNucliaDBClient:
|
94
74
|
environment: Environment
|
95
75
|
base_url: str
|
@@ -352,41 +332,10 @@ class NucliaDBClient(BaseNucliaDBClient):
|
|
352
332
|
handle_http_sync_errors(response)
|
353
333
|
return response
|
354
334
|
|
355
|
-
def logs(self, type: LogType, month: str) -> list[list[str]]:
|
356
|
-
if self.reader_session is None:
|
357
|
-
raise Exception("KB not configured")
|
358
|
-
|
359
|
-
if type != "feedback":
|
360
|
-
url = LEGACY_ACTIVITY_LOG_URL.format(type=type.value, month=month)
|
361
|
-
response: httpx.Response = self.reader_session.get(url)
|
362
|
-
handle_http_sync_errors(response)
|
363
|
-
return [row for row in csv.reader(response.iter_lines())]
|
364
|
-
else:
|
365
|
-
feedback_url = f"{self.url}{FEEDBACK_LOG_URL.format(month=month)}"
|
366
|
-
feedback_response: httpx.Response = self.reader_session.get(feedback_url)
|
367
|
-
handle_http_sync_errors(feedback_response)
|
368
|
-
feedbacks = [row for row in csv.reader(feedback_response.iter_lines())]
|
369
|
-
answers = self.logs(type=LogType.CHAT, month=month)
|
370
|
-
# first row with the columns headers
|
371
|
-
results = [[*feedbacks[0], *answers[0][:-1]]]
|
372
|
-
for feedback in feedbacks[1:]:
|
373
|
-
learning_id = feedback[1]
|
374
|
-
# search for the corresponding question/answer
|
375
|
-
# (the learning id is the same for both question/answer and feedback,
|
376
|
-
# and is the second column in the Q/A csv)
|
377
|
-
matching_answers = [
|
378
|
-
answer for answer in answers if answer[1] == learning_id
|
379
|
-
]
|
380
|
-
if len(matching_answers) > 0:
|
381
|
-
results.append([*feedback, *matching_answers[0][:-1]])
|
382
|
-
else:
|
383
|
-
results.append(feedback)
|
384
|
-
return results
|
385
|
-
|
386
335
|
def logs_query(
|
387
336
|
self,
|
388
337
|
type: EventType,
|
389
|
-
query: Union[ActivityLogsQuery, ActivityLogsSearchQuery,
|
338
|
+
query: Union[ActivityLogsQuery, ActivityLogsSearchQuery, ActivityLogsAskQuery],
|
390
339
|
) -> requests.Response:
|
391
340
|
if self.stream_session is None:
|
392
341
|
raise Exception("KB not configured")
|
@@ -405,7 +354,7 @@ class NucliaDBClient(BaseNucliaDBClient):
|
|
405
354
|
query: Union[
|
406
355
|
DownloadActivityLogsQuery,
|
407
356
|
DownloadActivityLogsSearchQuery,
|
408
|
-
|
357
|
+
DownloadActivityLogsAskQuery,
|
409
358
|
],
|
410
359
|
download_format: DownloadFormat,
|
411
360
|
):
|
@@ -709,43 +658,10 @@ class AsyncNucliaDBClient(BaseNucliaDBClient):
|
|
709
658
|
await handle_http_async_errors(response)
|
710
659
|
return response
|
711
660
|
|
712
|
-
async def logs(self, type: LogType, month: str) -> list[list[str]]:
|
713
|
-
if self.reader_session is None:
|
714
|
-
raise Exception("KB not configured")
|
715
|
-
|
716
|
-
if type != "feedback":
|
717
|
-
url = LEGACY_ACTIVITY_LOG_URL.format(type=type.value, month=month)
|
718
|
-
response: httpx.Response = await self.reader_session.get(url)
|
719
|
-
await handle_http_async_errors(response)
|
720
|
-
return [row for row in csv.reader(response.iter_lines())]
|
721
|
-
else:
|
722
|
-
feedback_url = f"{self.url}{FEEDBACK_LOG_URL.format(month=month)}"
|
723
|
-
feedback_response: httpx.Response = await self.reader_session.get(
|
724
|
-
feedback_url
|
725
|
-
)
|
726
|
-
await handle_http_async_errors(feedback_response)
|
727
|
-
feedbacks = [row for row in csv.reader(feedback_response.iter_lines())]
|
728
|
-
answers = await self.logs(type=LogType.CHAT, month=month)
|
729
|
-
# first row with the columns headers
|
730
|
-
results = [[*feedbacks[0], *answers[0][:-1]]]
|
731
|
-
for feedback in feedbacks[1:]:
|
732
|
-
learning_id = feedback[1]
|
733
|
-
# search for the corresponding question/answer
|
734
|
-
# (the learning id is the same for both question/answer and feedback,
|
735
|
-
# and is the second column in the Q/A csv)
|
736
|
-
matching_answers = [
|
737
|
-
answer for answer in answers if answer[1] == learning_id
|
738
|
-
]
|
739
|
-
if len(matching_answers) > 0:
|
740
|
-
results.append([*feedback, *matching_answers[0][:-1]])
|
741
|
-
else:
|
742
|
-
results.append(feedback)
|
743
|
-
return results
|
744
|
-
|
745
661
|
async def logs_query(
|
746
662
|
self,
|
747
663
|
type: EventType,
|
748
|
-
query: Union[ActivityLogsQuery, ActivityLogsSearchQuery,
|
664
|
+
query: Union[ActivityLogsQuery, ActivityLogsSearchQuery, ActivityLogsAskQuery],
|
749
665
|
) -> httpx.Response:
|
750
666
|
if self.reader_session is None:
|
751
667
|
raise Exception("KB not configured")
|
@@ -763,7 +679,7 @@ class AsyncNucliaDBClient(BaseNucliaDBClient):
|
|
763
679
|
query: Union[
|
764
680
|
DownloadActivityLogsQuery,
|
765
681
|
DownloadActivityLogsSearchQuery,
|
766
|
-
|
682
|
+
DownloadActivityLogsAskQuery,
|
767
683
|
],
|
768
684
|
download_format: DownloadFormat,
|
769
685
|
):
|
@@ -1,11 +1,11 @@
|
|
1
1
|
from nuclia.decorators import kb
|
2
|
-
from nuclia.lib.kb import
|
2
|
+
from nuclia.lib.kb import NucliaDBClient, AsyncNucliaDBClient
|
3
3
|
from nuclia_models.events.activity_logs import ( # type: ignore
|
4
4
|
ActivityLogsQuery,
|
5
|
-
|
5
|
+
ActivityLogsAskQuery,
|
6
6
|
ActivityLogsSearchQuery,
|
7
7
|
DownloadActivityLogsQuery,
|
8
|
-
|
8
|
+
DownloadActivityLogsAskQuery,
|
9
9
|
DownloadActivityLogsSearchQuery,
|
10
10
|
DownloadFormat,
|
11
11
|
EventType,
|
@@ -25,23 +25,6 @@ WAIT_FOR_DOWNLOAD_TIMEOUT = 120
|
|
25
25
|
|
26
26
|
|
27
27
|
class NucliaLogs:
|
28
|
-
@kb
|
29
|
-
def get(
|
30
|
-
self, *args, type: Union[LogType, str], month: str, **kwargs
|
31
|
-
) -> list[list[str]]:
|
32
|
-
"""
|
33
|
-
Download activity logs.
|
34
|
-
|
35
|
-
:param type: VISITED, MODIFIED, DELETED, NEW, SEARCH, SUGGEST, INDEXED, CHAT, STARTED, STOPPED, PROCESSED
|
36
|
-
:param month: YYYY-MM
|
37
|
-
"""
|
38
|
-
if isinstance(type, str):
|
39
|
-
type = LogType[type.upper()]
|
40
|
-
|
41
|
-
ndb: NucliaDBClient = kwargs["ndb"]
|
42
|
-
resp = ndb.logs(type=type, month=month)
|
43
|
-
return resp
|
44
|
-
|
45
28
|
@kb
|
46
29
|
def query(
|
47
30
|
self,
|
@@ -51,25 +34,25 @@ class NucliaLogs:
|
|
51
34
|
dict,
|
52
35
|
ActivityLogsQuery,
|
53
36
|
ActivityLogsSearchQuery,
|
54
|
-
|
37
|
+
ActivityLogsAskQuery,
|
55
38
|
],
|
56
39
|
**kwargs,
|
57
40
|
) -> ActivityLogsOutput:
|
58
41
|
"""
|
59
42
|
Query activity logs.
|
60
43
|
|
61
|
-
:param type: VISITED, MODIFIED, DELETED, NEW, SEARCH, SUGGEST, INDEXED, CHAT, STARTED, STOPPED, PROCESSED
|
44
|
+
:param type: VISITED, MODIFIED, DELETED, NEW, SEARCH, SUGGEST, INDEXED, CHAT, ASK, STARTED, STOPPED, PROCESSED
|
62
45
|
:param query: ActivityLogsQuery
|
63
46
|
"""
|
64
47
|
_type = EventType[type.upper()] if isinstance(type, str) else type
|
65
48
|
_query: Union[
|
66
49
|
ActivityLogsQuery,
|
67
50
|
ActivityLogsSearchQuery,
|
68
|
-
|
51
|
+
ActivityLogsAskQuery,
|
69
52
|
]
|
70
53
|
if isinstance(query, dict):
|
71
|
-
if _type
|
72
|
-
_query =
|
54
|
+
if _type in (EventType.ASK, EventType.CHAT): # TODO: deprecate chat event
|
55
|
+
_query = ActivityLogsAskQuery.model_validate(query)
|
73
56
|
elif type is EventType.SEARCH:
|
74
57
|
_query = ActivityLogsSearchQuery.model_validate(query)
|
75
58
|
else:
|
@@ -95,7 +78,7 @@ class NucliaLogs:
|
|
95
78
|
dict,
|
96
79
|
DownloadActivityLogsQuery,
|
97
80
|
DownloadActivityLogsSearchQuery,
|
98
|
-
|
81
|
+
DownloadActivityLogsAskQuery,
|
99
82
|
],
|
100
83
|
download_format: Union[DownloadFormat, str],
|
101
84
|
wait: bool = False,
|
@@ -104,8 +87,8 @@ class NucliaLogs:
|
|
104
87
|
"""
|
105
88
|
Download activity logs.
|
106
89
|
|
107
|
-
:param type:
|
108
|
-
:param
|
90
|
+
:param type: VISITED, MODIFIED, DELETED, NEW, SEARCH, SUGGEST, INDEXED, CHAT, ASK, STARTED, STOPPED, PROCESSED
|
91
|
+
:param download_format: NDJSON, CSV
|
109
92
|
:param query: DownloadActivityLogsQuery
|
110
93
|
"""
|
111
94
|
_type = EventType[type.upper()] if isinstance(type, str) else type
|
@@ -119,11 +102,11 @@ class NucliaLogs:
|
|
119
102
|
dict,
|
120
103
|
DownloadActivityLogsQuery,
|
121
104
|
DownloadActivityLogsSearchQuery,
|
122
|
-
|
105
|
+
DownloadActivityLogsAskQuery,
|
123
106
|
]
|
124
107
|
if isinstance(query, dict):
|
125
|
-
if _type
|
126
|
-
_query =
|
108
|
+
if _type in (EventType.ASK, EventType.CHAT): # TODO: deprecate chat event
|
109
|
+
_query = DownloadActivityLogsAskQuery.model_validate(query)
|
127
110
|
elif type is EventType.SEARCH:
|
128
111
|
_query = DownloadActivityLogsSearchQuery.model_validate(query)
|
129
112
|
else:
|
@@ -168,23 +151,6 @@ class NucliaLogs:
|
|
168
151
|
|
169
152
|
|
170
153
|
class AsyncNucliaLogs:
|
171
|
-
@kb
|
172
|
-
async def get(
|
173
|
-
self, *args, type: Union[LogType, str], month: str, **kwargs
|
174
|
-
) -> list[list[str]]:
|
175
|
-
"""
|
176
|
-
Download activity logs.
|
177
|
-
|
178
|
-
:param type: VISITED, MODIFIED, DELETED, NEW, SEARCH, SUGGEST, INDEXED, CHAT, STARTED, STOPPED, PROCESSED
|
179
|
-
:param month: YYYY-MM
|
180
|
-
"""
|
181
|
-
if isinstance(type, str):
|
182
|
-
type = LogType[type.upper()]
|
183
|
-
|
184
|
-
ndb: AsyncNucliaDBClient = kwargs["ndb"]
|
185
|
-
resp = await ndb.logs(type=type, month=month)
|
186
|
-
return resp
|
187
|
-
|
188
154
|
@kb
|
189
155
|
async def query(
|
190
156
|
self,
|
@@ -194,25 +160,25 @@ class AsyncNucliaLogs:
|
|
194
160
|
dict,
|
195
161
|
ActivityLogsQuery,
|
196
162
|
ActivityLogsSearchQuery,
|
197
|
-
|
163
|
+
ActivityLogsAskQuery,
|
198
164
|
],
|
199
165
|
**kwargs,
|
200
166
|
) -> ActivityLogsOutput:
|
201
167
|
"""
|
202
168
|
Query activity logs.
|
203
169
|
|
204
|
-
:param type: VISITED, MODIFIED, DELETED, NEW, SEARCH, SUGGEST, INDEXED, CHAT, STARTED, STOPPED, PROCESSED
|
170
|
+
:param type: VISITED, MODIFIED, DELETED, NEW, SEARCH, SUGGEST, INDEXED, CHAT, ASK, STARTED, STOPPED, PROCESSED
|
205
171
|
:param query: ActivityLogsQuery
|
206
172
|
"""
|
207
173
|
_type = EventType[type.upper()] if isinstance(type, str) else type
|
208
174
|
_query: Union[
|
209
175
|
ActivityLogsQuery,
|
210
176
|
ActivityLogsSearchQuery,
|
211
|
-
|
177
|
+
ActivityLogsAskQuery,
|
212
178
|
]
|
213
179
|
if isinstance(query, dict):
|
214
|
-
if _type
|
215
|
-
_query =
|
180
|
+
if _type in (EventType.ASK, EventType.CHAT): # TODO: deprecate chat event
|
181
|
+
_query = ActivityLogsAskQuery.model_validate(query)
|
216
182
|
elif type is EventType.SEARCH:
|
217
183
|
_query = ActivityLogsSearchQuery.model_validate(query)
|
218
184
|
else:
|
@@ -238,7 +204,7 @@ class AsyncNucliaLogs:
|
|
238
204
|
dict,
|
239
205
|
DownloadActivityLogsQuery,
|
240
206
|
DownloadActivityLogsSearchQuery,
|
241
|
-
|
207
|
+
DownloadActivityLogsAskQuery,
|
242
208
|
],
|
243
209
|
download_format: Union[DownloadFormat, str],
|
244
210
|
wait: bool = False,
|
@@ -247,8 +213,8 @@ class AsyncNucliaLogs:
|
|
247
213
|
"""
|
248
214
|
Download activity logs.
|
249
215
|
|
250
|
-
:param type:
|
251
|
-
:param
|
216
|
+
:param type: VISITED, MODIFIED, DELETED, NEW, SEARCH, SUGGEST, INDEXED, CHAT, ASK, STARTED, STOPPED, PROCESSED
|
217
|
+
:param download_format: NDJSON, CSV
|
252
218
|
:param query: DownloadActivityLogsQuery
|
253
219
|
"""
|
254
220
|
_type = EventType[type.upper()] if isinstance(type, str) else type
|
@@ -262,11 +228,11 @@ class AsyncNucliaLogs:
|
|
262
228
|
dict,
|
263
229
|
DownloadActivityLogsQuery,
|
264
230
|
DownloadActivityLogsSearchQuery,
|
265
|
-
|
231
|
+
DownloadActivityLogsAskQuery,
|
266
232
|
]
|
267
233
|
if isinstance(query, dict):
|
268
|
-
if _type
|
269
|
-
_query =
|
234
|
+
if _type in (EventType.ASK, EventType.CHAT): # TODO: deprecate chat event
|
235
|
+
_query = DownloadActivityLogsAskQuery.model_validate(query)
|
270
236
|
elif type is EventType.SEARCH:
|
271
237
|
_query = DownloadActivityLogsSearchQuery.model_validate(query)
|
272
238
|
else:
|
@@ -1,24 +1,15 @@
|
|
1
1
|
from nuclia.sdk.kb import NucliaKB, AsyncNucliaKB
|
2
2
|
from nuclia.tests.fixtures import IS_PROD
|
3
|
-
from nuclia.lib.kb import LogType
|
4
3
|
from nuclia_models.events.activity_logs import (
|
5
4
|
ActivityLogsQuery,
|
6
5
|
Pagination,
|
7
6
|
DownloadActivityLogsQuery,
|
8
7
|
DownloadFormat,
|
8
|
+
EventType,
|
9
9
|
)
|
10
10
|
import pytest
|
11
11
|
|
12
12
|
|
13
|
-
def test_logs(testing_config):
|
14
|
-
if not IS_PROD:
|
15
|
-
assert True
|
16
|
-
return
|
17
|
-
nkb = NucliaKB()
|
18
|
-
logs = nkb.logs.get(type=LogType.NEW, month="2024-06")
|
19
|
-
assert len(logs) == 23
|
20
|
-
|
21
|
-
|
22
13
|
def test_activity_logs_query(testing_config):
|
23
14
|
if not IS_PROD:
|
24
15
|
assert True
|
@@ -30,7 +21,7 @@ def test_activity_logs_query(testing_config):
|
|
30
21
|
pagination=Pagination(limit=10),
|
31
22
|
)
|
32
23
|
nkb = NucliaKB()
|
33
|
-
output = nkb.logs.query(type=
|
24
|
+
output = nkb.logs.query(type=EventType.CHAT, query=query)
|
34
25
|
assert len(output.data) == 10
|
35
26
|
assert output.has_more
|
36
27
|
|
@@ -46,24 +37,48 @@ def test_activity_logs_download(testing_config):
|
|
46
37
|
)
|
47
38
|
nkb = NucliaKB()
|
48
39
|
output = nkb.logs.download(
|
49
|
-
type=
|
40
|
+
type=EventType.CHAT, query=query, download_format=DownloadFormat.NDJSON
|
50
41
|
)
|
51
42
|
assert output.request_id
|
52
43
|
assert output.download_url is None
|
53
44
|
|
54
45
|
|
55
46
|
@pytest.mark.asyncio
|
56
|
-
async def
|
47
|
+
async def test_activity_logs_query_async(testing_config):
|
57
48
|
if not IS_PROD:
|
58
49
|
assert True
|
59
50
|
return
|
51
|
+
query = ActivityLogsQuery(
|
52
|
+
year_month="2024-10",
|
53
|
+
show=["id", "date", "client_type", "total_duration"],
|
54
|
+
filters={},
|
55
|
+
pagination=Pagination(limit=10),
|
56
|
+
)
|
60
57
|
nkb = AsyncNucliaKB()
|
61
|
-
|
62
|
-
assert len(
|
58
|
+
output = await nkb.logs.query(type=EventType.CHAT, query=query)
|
59
|
+
assert len(output.data) == 10
|
60
|
+
assert output.has_more
|
63
61
|
|
64
62
|
|
65
63
|
@pytest.mark.asyncio
|
66
|
-
async def
|
64
|
+
async def test_activity_logs_download_async(testing_config):
|
65
|
+
if not IS_PROD:
|
66
|
+
assert True
|
67
|
+
return
|
68
|
+
query = DownloadActivityLogsQuery(
|
69
|
+
year_month="2024-10",
|
70
|
+
show=["id", "date", "client_type", "total_duration"],
|
71
|
+
filters={},
|
72
|
+
)
|
73
|
+
nkb = AsyncNucliaKB()
|
74
|
+
output = await nkb.logs.download(
|
75
|
+
type=EventType.CHAT, query=query, download_format=DownloadFormat.NDJSON
|
76
|
+
)
|
77
|
+
assert output.request_id
|
78
|
+
assert output.download_url is None
|
79
|
+
|
80
|
+
|
81
|
+
def test_activity_logs_ask_query(testing_config):
|
67
82
|
if not IS_PROD:
|
68
83
|
assert True
|
69
84
|
return
|
@@ -73,14 +88,14 @@ async def test_activity_logs_query_async(testing_config):
|
|
73
88
|
filters={},
|
74
89
|
pagination=Pagination(limit=10),
|
75
90
|
)
|
76
|
-
nkb =
|
77
|
-
output =
|
91
|
+
nkb = NucliaKB()
|
92
|
+
output = nkb.logs.query(type=EventType.ASK, query=query)
|
78
93
|
assert len(output.data) == 10
|
79
94
|
assert output.has_more
|
80
95
|
|
81
96
|
|
82
97
|
@pytest.mark.asyncio
|
83
|
-
async def
|
98
|
+
async def test_activity_logs_ask_download_async(testing_config):
|
84
99
|
if not IS_PROD:
|
85
100
|
assert True
|
86
101
|
return
|
@@ -91,7 +106,7 @@ async def test_activity_logs_download_async(testing_config):
|
|
91
106
|
)
|
92
107
|
nkb = AsyncNucliaKB()
|
93
108
|
output = await nkb.logs.download(
|
94
|
-
type=
|
109
|
+
type=EventType.ASK, query=query, download_format=DownloadFormat.NDJSON
|
95
110
|
)
|
96
111
|
assert output.request_id
|
97
112
|
assert output.download_url is None
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: nuclia
|
3
|
-
Version: 4.8.
|
3
|
+
Version: 4.8.10
|
4
4
|
Summary: Nuclia Python SDK
|
5
5
|
Author-email: Nuclia <info@nuclia.com>
|
6
6
|
License-Expression: MIT
|
@@ -26,7 +26,7 @@ Requires-Dist: httpcore>=1.0.0
|
|
26
26
|
Requires-Dist: prompt_toolkit
|
27
27
|
Requires-Dist: nucliadb_sdk<7,>=6.4
|
28
28
|
Requires-Dist: nucliadb_models<7,>=6.4
|
29
|
-
Requires-Dist: nuclia-models>=0.
|
29
|
+
Requires-Dist: nuclia-models>=0.41.1
|
30
30
|
Requires-Dist: tqdm
|
31
31
|
Requires-Dist: aiofiles
|
32
32
|
Requires-Dist: backoff
|
@@ -1361,7 +1361,7 @@ requires-dist = [
|
|
1361
1361
|
{ name = "httpcore", specifier = ">=1.0.0" },
|
1362
1362
|
{ name = "httpx" },
|
1363
1363
|
{ name = "litellm", marker = "extra == 'litellm'" },
|
1364
|
-
{ name = "nuclia-models", specifier = ">=0.
|
1364
|
+
{ name = "nuclia-models", specifier = ">=0.41.1" },
|
1365
1365
|
{ name = "nucliadb-models", specifier = ">=6.4,<7" },
|
1366
1366
|
{ name = "nucliadb-protos", marker = "extra == 'protos'", specifier = ">=6.4,<7" },
|
1367
1367
|
{ name = "nucliadb-sdk", specifier = ">=6.4,<7" },
|
@@ -1392,14 +1392,14 @@ dev = [
|
|
1392
1392
|
|
1393
1393
|
[[package]]
|
1394
1394
|
name = "nuclia-models"
|
1395
|
-
version = "0.
|
1395
|
+
version = "0.41.1"
|
1396
1396
|
source = { registry = "https://pypi.org/simple" }
|
1397
1397
|
dependencies = [
|
1398
1398
|
{ name = "pydantic", extra = ["email"] },
|
1399
1399
|
]
|
1400
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
1400
|
+
sdist = { url = "https://files.pythonhosted.org/packages/90/fb/fa638f4732d4dbd2308ec5c2d7684133a51e24607b85d9fc39b264430a15/nuclia_models-0.41.1.tar.gz", hash = "sha256:726cc7974bcffd2329fc3fbd17e14b0b7f79bfcd5f88131764d94b931fe9c873", size = 21608 }
|
1401
1401
|
wheels = [
|
1402
|
-
{ url = "https://files.pythonhosted.org/packages/
|
1402
|
+
{ url = "https://files.pythonhosted.org/packages/0c/38/fdfd9c05377bca3955790a367b73e1fbfeef0054a43f855a38fbd79d753a/nuclia_models-0.41.1-py3-none-any.whl", hash = "sha256:25ca89d1c688ad0351e0f9f8b8b3e6a92109bc4505757453570e08cf6ee3db82", size = 25677 },
|
1403
1403
|
]
|
1404
1404
|
|
1405
1405
|
[[package]]
|
nuclia-4.8.9/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
4.8.9
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|