deepsights-api 0.2.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.
- deepsights/__init__.py +23 -0
- deepsights/answers/__init__.py +26 -0
- deepsights/answers/answer.py +106 -0
- deepsights/answers/answer_v1.py +55 -0
- deepsights/answers/model.py +107 -0
- deepsights/api/__init__.py +22 -0
- deepsights/api/api.py +231 -0
- deepsights/api/model.py +96 -0
- deepsights/api/quota.py +54 -0
- deepsights/contentstore/__init__.py +24 -0
- deepsights/contentstore/_search.py +229 -0
- deepsights/contentstore/model.py +76 -0
- deepsights/contentstore/news.py +139 -0
- deepsights/contentstore/secondary.py +139 -0
- deepsights/documents/__init__.py +44 -0
- deepsights/documents/_cache.py +39 -0
- deepsights/documents/_segmenter.py +113 -0
- deepsights/documents/delete.py +82 -0
- deepsights/documents/download.py +63 -0
- deepsights/documents/load.py +172 -0
- deepsights/documents/model.py +161 -0
- deepsights/documents/search.py +182 -0
- deepsights/documents/upload.py +130 -0
- deepsights/minions/__init__.py +0 -0
- deepsights/minions/_minions.py +59 -0
- deepsights/reports/__init__.py +24 -0
- deepsights/reports/model.py +141 -0
- deepsights/reports/report.py +95 -0
- deepsights/utils/__init__.py +31 -0
- deepsights/utils/_cache.py +63 -0
- deepsights/utils/_ranking.py +201 -0
- deepsights/utils/_utils.py +45 -0
- deepsights/utils/model.py +91 -0
- deepsights_api-0.2.0.dist-info/LICENSE +201 -0
- deepsights_api-0.2.0.dist-info/METADATA +92 -0
- deepsights_api-0.2.0.dist-info/RECORD +39 -0
- deepsights_api-0.2.0.dist-info/WHEEL +5 -0
- deepsights_api-0.2.0.dist-info/top_level.txt +1 -0
- src/deepsights/__init__.py +23 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Copyright 2024 Market Logic Software AG. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
This module contains the functions to search for documents and document pages based on their vector embeddings.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from typing import List
|
|
20
|
+
from deepsights.api import DeepSights
|
|
21
|
+
from deepsights.utils import rerank_by_recency, promote_exact_matches
|
|
22
|
+
from deepsights.documents.model import DocumentPageSearchResult, DocumentSearchResult
|
|
23
|
+
from deepsights.documents.load import documents_load, document_pages_load
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
#################################################
|
|
27
|
+
def document_pages_search(
|
|
28
|
+
api: DeepSights,
|
|
29
|
+
query_embedding: List,
|
|
30
|
+
min_score: float = 0.7,
|
|
31
|
+
max_results: int = 50,
|
|
32
|
+
load_pages=False,
|
|
33
|
+
):
|
|
34
|
+
"""
|
|
35
|
+
Searches for document pages based on their vector embeddings.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
|
|
39
|
+
api (ds.DeepSights): The DeepSights API instance.
|
|
40
|
+
query_embedding (List): The query vector embedding.
|
|
41
|
+
min_score (float, optional): The minimum score threshold for search results. Defaults to 0.7.
|
|
42
|
+
max_results (int, optional): The maximum number of search results to return. Defaults to 50.
|
|
43
|
+
load_pages (bool, optional): Whether to load the pages associated with the search results. Defaults to False.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
|
|
47
|
+
List[DocumentPageSearchResult]: The list of DocumentPageSearchResult objects representing the search results.
|
|
48
|
+
"""
|
|
49
|
+
assert query_embedding, "The 'query_embedding' argument is required."
|
|
50
|
+
assert len(query_embedding) == 1536, "The 'query_embedding' must be of length 1536."
|
|
51
|
+
assert 0 <= min_score <= 1, "The 'min_score' must be between 0 and 1."
|
|
52
|
+
assert 0 < max_results <= 100, "Maximum results must be between 1 and 100."
|
|
53
|
+
|
|
54
|
+
body = {
|
|
55
|
+
"embeddings": query_embedding,
|
|
56
|
+
"min_score": min_score,
|
|
57
|
+
"limit": max_results,
|
|
58
|
+
}
|
|
59
|
+
params = {"ai_model": "ADA", "search_model": "PAGE"}
|
|
60
|
+
response = api.post(
|
|
61
|
+
"vector-search-service/vectors/_search", params=params, body=body
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# parse
|
|
65
|
+
results = [
|
|
66
|
+
DocumentPageSearchResult(
|
|
67
|
+
document_id=d["artifact_id"], id=p["part_id"], score=p["score"]
|
|
68
|
+
)
|
|
69
|
+
for d in response["results"]
|
|
70
|
+
for p in d["result_parts"]
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
# make sure we are sorted by score
|
|
74
|
+
results.sort(key=lambda x: x.score, reverse=True)
|
|
75
|
+
|
|
76
|
+
# load pages if requested
|
|
77
|
+
if load_pages:
|
|
78
|
+
# make sure pages are loaded
|
|
79
|
+
document_pages_load(api, page_ids=[r.id for r in results])
|
|
80
|
+
|
|
81
|
+
return results
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
#################################################
|
|
85
|
+
def documents_search(
|
|
86
|
+
api: DeepSights,
|
|
87
|
+
query: str = None,
|
|
88
|
+
query_embedding: List = None,
|
|
89
|
+
min_score: float = 0.7,
|
|
90
|
+
max_results: int = 50,
|
|
91
|
+
recency_weight: float = None,
|
|
92
|
+
promote_exact_match: bool = False,
|
|
93
|
+
load_documents=False,
|
|
94
|
+
):
|
|
95
|
+
"""
|
|
96
|
+
Searches for document based on their vector embeddings.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
|
|
100
|
+
api (ds.DeepSights): The DeepSights API instance.
|
|
101
|
+
query (str): The search query; currently only used for promoting exact matches.
|
|
102
|
+
query_embedding (List): The query vector embedding.
|
|
103
|
+
min_score (float, optional): The minimum score threshold for document matches. Defaults to 0.7.
|
|
104
|
+
max_results (int, optional): The maximum number of document matches to return. Defaults to 50.
|
|
105
|
+
recency_weight (float, optional): The weight to apply to the recency factor in ranking. Defaults to None, i.e. no recency weighting.
|
|
106
|
+
promote_exact_match (bool, optional): Whether to promote exact matches to the top of the search results. Defaults to False.
|
|
107
|
+
load_documents (bool, optional): Whether to load documents and matching pages associated with the search results. Defaults to False.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
|
|
111
|
+
List: The DocumentSearchResults.
|
|
112
|
+
"""
|
|
113
|
+
assert query_embedding, "The 'query_embedding' argument is required."
|
|
114
|
+
assert len(query_embedding) == 1536, "The 'query_embedding' must be of length 1536."
|
|
115
|
+
assert 0 <= min_score <= 1, "The 'min_score' must be between 0 and 1."
|
|
116
|
+
assert 0 < max_results <= 100, "Maximum results must be between 1 and 100."
|
|
117
|
+
assert (
|
|
118
|
+
recency_weight is None or 0 <= recency_weight <= 1
|
|
119
|
+
), "Recency weight must be between 0 and 1."
|
|
120
|
+
assert (
|
|
121
|
+
query is None or promote_exact_matches
|
|
122
|
+
), "The 'query' argument is only used when 'promote_exact_match' is set to True."
|
|
123
|
+
|
|
124
|
+
# get the page matches
|
|
125
|
+
page_matches = document_pages_search(
|
|
126
|
+
api,
|
|
127
|
+
query_embedding,
|
|
128
|
+
min_score=min_score,
|
|
129
|
+
max_results=max_results,
|
|
130
|
+
load_pages=load_documents,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# calculate aggregated document rank score
|
|
134
|
+
document_rank_score = {}
|
|
135
|
+
for rank, page in enumerate(page_matches):
|
|
136
|
+
document_rank_score[page.document_id] = document_rank_score.get(
|
|
137
|
+
page.document_id, 0
|
|
138
|
+
) + 1.0 / (rank + max_results / 2)
|
|
139
|
+
|
|
140
|
+
document_rank_score = {
|
|
141
|
+
k: v
|
|
142
|
+
for k, v in sorted(
|
|
143
|
+
document_rank_score.items(), key=lambda item: item[1], reverse=True
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# now construct the document matches in rank order
|
|
148
|
+
results = [
|
|
149
|
+
DocumentSearchResult(
|
|
150
|
+
id=document_id,
|
|
151
|
+
score_rank=rank + 1,
|
|
152
|
+
page_matches=[p for p in page_matches if p.document_id == document_id],
|
|
153
|
+
)
|
|
154
|
+
for rank, document_id in enumerate(document_rank_score)
|
|
155
|
+
]
|
|
156
|
+
|
|
157
|
+
# load documents if requested
|
|
158
|
+
if load_documents or recency_weight:
|
|
159
|
+
# make sure the documents are loaded
|
|
160
|
+
documents_load(api, document_ids=[r.id for r in results])
|
|
161
|
+
|
|
162
|
+
# load pages if requested
|
|
163
|
+
if load_documents:
|
|
164
|
+
page_ids = [p.id for r in results for p in r.page_matches]
|
|
165
|
+
document_pages_load(api, page_ids=page_ids)
|
|
166
|
+
|
|
167
|
+
# order pages by their number
|
|
168
|
+
for r in results:
|
|
169
|
+
r.page_matches.sort(key=lambda x: x.page_number)
|
|
170
|
+
|
|
171
|
+
# apply recency weight
|
|
172
|
+
results = rerank_by_recency(results, recency_weight=recency_weight)
|
|
173
|
+
|
|
174
|
+
# pull exact matches to the top
|
|
175
|
+
if promote_exact_match and query:
|
|
176
|
+
results = promote_exact_matches(query, results)
|
|
177
|
+
|
|
178
|
+
# record rank
|
|
179
|
+
for rank, result in enumerate(results):
|
|
180
|
+
result.rank = rank + 1
|
|
181
|
+
|
|
182
|
+
return results
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Copyright 2024 Market Logic Software AG. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
This module contains the functions to upload documents to the DeepSights API.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import os
|
|
20
|
+
import time
|
|
21
|
+
import requests
|
|
22
|
+
from deepsights.api import DeepSights
|
|
23
|
+
from deepsights.documents.load import documents_load
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
#################################################
|
|
27
|
+
def document_upload(api: DeepSights, document_filename: str):
|
|
28
|
+
"""
|
|
29
|
+
Upload a document to the DeepSights API.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
|
|
33
|
+
document_filename (str): The filename of the document to upload. Must be PDF, PPT(X), DOC(X)
|
|
34
|
+
"""
|
|
35
|
+
# check if document exists
|
|
36
|
+
if not os.path.exists(document_filename):
|
|
37
|
+
raise FileNotFoundError(f"Document {document_filename} does not exist.")
|
|
38
|
+
|
|
39
|
+
# MIME map
|
|
40
|
+
mime_map = {
|
|
41
|
+
"pdf": "application/pdf",
|
|
42
|
+
"ppt": "application/vnd.ms-powerpoint",
|
|
43
|
+
"pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
44
|
+
"doc": "application/msword",
|
|
45
|
+
"docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# check proper file extension: must be PDF, PPT, PPTX, DOC, DOCX
|
|
49
|
+
if not any (document_filename.lower().endswith(extension) for extension in mime_map):
|
|
50
|
+
raise ValueError(
|
|
51
|
+
f"Document {document_filename} is not a valid file type. Only supporting {', '.join(mime_map)}."
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# get file basename
|
|
55
|
+
document_basename = os.path.basename(document_filename)
|
|
56
|
+
|
|
57
|
+
# obtain upload link
|
|
58
|
+
response = api.post(
|
|
59
|
+
"/artifact-service/document-upload-links/_generate",
|
|
60
|
+
body={
|
|
61
|
+
"file_name": document_basename,
|
|
62
|
+
"file_type": document_filename.split(".")[-1].upper(),
|
|
63
|
+
},
|
|
64
|
+
)
|
|
65
|
+
upload_link = response["signed_link"]
|
|
66
|
+
gcs_object_id = response["gcs_object_id"]
|
|
67
|
+
|
|
68
|
+
# upload document
|
|
69
|
+
with open(document_filename, "rb") as f:
|
|
70
|
+
headers = {
|
|
71
|
+
"Content-Type": mime_map[document_filename.split(".")[-1].lower()],
|
|
72
|
+
"x-goog-if-generation-match": "0",
|
|
73
|
+
}
|
|
74
|
+
response = requests.put(upload_link, headers=headers, data=f, timeout=30)
|
|
75
|
+
|
|
76
|
+
# check response
|
|
77
|
+
if response.status_code != 200:
|
|
78
|
+
raise ValueError(
|
|
79
|
+
f"Document {document_filename} failed to upload: {response.text}"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# create artifact
|
|
83
|
+
response = api.post(
|
|
84
|
+
"/artifact-service/artifacts",
|
|
85
|
+
body={"gcs_object_id": gcs_object_id},
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# return artifact ID
|
|
89
|
+
return response["id"]
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
#################################################
|
|
93
|
+
def document_wait_for_processing(api: DeepSights, document_id: str, timeout: int = 300):
|
|
94
|
+
"""
|
|
95
|
+
Wait for the document to be processed and completed.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
|
|
99
|
+
api (DeepSights): An instance of the DeepSights API client.
|
|
100
|
+
document_id (str): The ID of the document to wait for.
|
|
101
|
+
timeout (int, optional): The maximum time to wait for the document to be processed, in seconds. Defaults to 300.
|
|
102
|
+
|
|
103
|
+
Raises:
|
|
104
|
+
|
|
105
|
+
ValueError: If the document fails to process.
|
|
106
|
+
TimeoutError: If the document fails to process within the specified timeout.
|
|
107
|
+
|
|
108
|
+
"""
|
|
109
|
+
# wait for completion
|
|
110
|
+
start = time.time()
|
|
111
|
+
while time.time() - start < timeout:
|
|
112
|
+
response = api.get(f"/artifact-service/artifacts/{document_id}")
|
|
113
|
+
if response["status"] == "COMPLETED":
|
|
114
|
+
break
|
|
115
|
+
|
|
116
|
+
if response["status"].startswith("FAILED"):
|
|
117
|
+
raise ValueError(
|
|
118
|
+
f"Document {document_id} failed to process: {response['error_message']}"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
time.sleep(2)
|
|
122
|
+
|
|
123
|
+
# timeout?
|
|
124
|
+
if time.time() - start >= timeout:
|
|
125
|
+
raise TimeoutError(
|
|
126
|
+
f"Document {document_id} failed to process in {timeout} seconds."
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# now load into cache
|
|
130
|
+
documents_load(api, [document_id])
|
|
File without changes
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Copyright 2024 Market Logic Software AG. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
This module contains functions to interact with minions.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import time
|
|
20
|
+
from deepsights.api import DeepSights
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
#################################################
|
|
24
|
+
def minion_wait_for_completion(
|
|
25
|
+
api: DeepSights, minion_name: str, minion_job_id: str, timeout: int
|
|
26
|
+
):
|
|
27
|
+
"""
|
|
28
|
+
Waits for the completion of a minion job.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
|
|
32
|
+
api (DeepSights): The DeepSights API instance.
|
|
33
|
+
minion_name (str): The name of the minion.
|
|
34
|
+
minion_job_id (str): The ID of the answer set.
|
|
35
|
+
timeout (int, optional): The maximum time to wait for the answer set to complete, in seconds.
|
|
36
|
+
|
|
37
|
+
Raises:
|
|
38
|
+
|
|
39
|
+
ValueError: If the answer set fails to complete.
|
|
40
|
+
"""
|
|
41
|
+
# wait for completion
|
|
42
|
+
start = time.time()
|
|
43
|
+
while time.time() - start < timeout:
|
|
44
|
+
response = api.get(f"/minion-commander-service/{minion_name}/{minion_job_id}")[
|
|
45
|
+
"minion_job"
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
if response["status"] in ("CREATED", "STARTED"):
|
|
49
|
+
time.sleep(2)
|
|
50
|
+
elif response["status"].startswith("FAILED"):
|
|
51
|
+
raise ValueError(
|
|
52
|
+
f"Minion {minion_job_id} failed to complete: {response['error_reason']}"
|
|
53
|
+
)
|
|
54
|
+
else:
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
raise ValueError(
|
|
58
|
+
f"Minion {minion_job_id} failed to complete within {timeout} seconds."
|
|
59
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Copyright 2024 Market Logic Software AG. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
This module contains the functions to retrieve reports from the DeepSights API.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from deepsights.reports.report import (
|
|
21
|
+
report_create,
|
|
22
|
+
report_wait_for_completion,
|
|
23
|
+
report_get,
|
|
24
|
+
)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Copyright 2024 Market Logic Software AG. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
This module contains the model classes for reports.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from typing import Optional, List
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
from pydantic import Field
|
|
23
|
+
from deepsights.utils import DeepSightsIdModel, DeepSightsIdTitleModel
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
#################################################
|
|
27
|
+
class ReportEvidence(DeepSightsIdTitleModel):
|
|
28
|
+
"""
|
|
29
|
+
Represents evidence related to a report.
|
|
30
|
+
|
|
31
|
+
Attributes:
|
|
32
|
+
|
|
33
|
+
summary (Optional[str]): The summary of the evidence with respect to the report's question.
|
|
34
|
+
publication_date (Optional[datetime]): The publication date of the evidence.
|
|
35
|
+
rating (int): The rating of the evidence's relevance on a 1-5 scale with respect to the report's question.
|
|
36
|
+
reference (Optional[str]): The quotation reference code of the evidence.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
evidence_summary: Optional[str] = Field(
|
|
40
|
+
alias="summary",
|
|
41
|
+
description="The summary of the evidence with respect to the report's question.",
|
|
42
|
+
)
|
|
43
|
+
publication_date: Optional[datetime] = Field(
|
|
44
|
+
description="The publication date of the evidence."
|
|
45
|
+
)
|
|
46
|
+
rating: int = Field(
|
|
47
|
+
description="The rating of the evidence's relevance on a 1-5 scale with respect to the report's question."
|
|
48
|
+
)
|
|
49
|
+
reference: Optional[str] = Field(
|
|
50
|
+
alias="reference_id",
|
|
51
|
+
description="The quotation reference code of the evidence.",
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
#################################################
|
|
56
|
+
class DocumentPageReportEvidence(DeepSightsIdModel):
|
|
57
|
+
"""
|
|
58
|
+
Represents a document page in a report evidence.
|
|
59
|
+
|
|
60
|
+
Attributes:
|
|
61
|
+
|
|
62
|
+
page_number (Optional[int], optional): The number of the page.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
page_number: Optional[int] = Field(
|
|
66
|
+
default=None, description="The number of the page (one-based)."
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
#################################################
|
|
71
|
+
class DocumentReportEvidence(ReportEvidence):
|
|
72
|
+
"""
|
|
73
|
+
Represents evidence found in a document for a report.
|
|
74
|
+
|
|
75
|
+
Attributes:
|
|
76
|
+
|
|
77
|
+
description (Optional[str]): The human-readable summary of the document.
|
|
78
|
+
pages (List[DocumentPageSearchResult]): The list of pages in the document where the evidence is found.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
description: Optional[str] = Field(
|
|
82
|
+
alias="artifact_summary",
|
|
83
|
+
description="The human-readable summary of the document.",
|
|
84
|
+
)
|
|
85
|
+
pages: List[DocumentPageReportEvidence] = Field(
|
|
86
|
+
alias="page_references",
|
|
87
|
+
description="The list of pages in the document where the evidence is found.",
|
|
88
|
+
default=[],
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
#################################################
|
|
93
|
+
class NewsReportEvidence(ReportEvidence):
|
|
94
|
+
"""
|
|
95
|
+
Represents evidence for a news report.
|
|
96
|
+
|
|
97
|
+
Attributes:
|
|
98
|
+
|
|
99
|
+
source (Optional[str]): The name of the item's source; may be None.
|
|
100
|
+
description (Optional[str]): The human-readable summary of the news item.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
source: Optional[str] = Field(
|
|
104
|
+
description="The name of the item's source; may be None.", default=None
|
|
105
|
+
)
|
|
106
|
+
description: Optional[str] = Field(
|
|
107
|
+
alias="summary",
|
|
108
|
+
description="The human-readable summary of the news item.",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
#################################################
|
|
113
|
+
class Report(DeepSightsIdModel):
|
|
114
|
+
"""
|
|
115
|
+
Represents a report generated by the DeepSights API.
|
|
116
|
+
|
|
117
|
+
Attributes:
|
|
118
|
+
|
|
119
|
+
status (str): The processing status of the report.
|
|
120
|
+
question (str): The question that the report is answering.
|
|
121
|
+
topic (str, optional): The AI-generated topic of the report.
|
|
122
|
+
summary (str, optional): The summary text of the report in markdown format.
|
|
123
|
+
document_sources (List[ReportEvidence]): List of evidence from documents used in the report.
|
|
124
|
+
news_sources (List[ReportEvidence]): List of evidence from news sources used in the report.
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
status: str = Field(description="The processing status of the report.")
|
|
128
|
+
question: str = Field(description="The question that the report is answering.")
|
|
129
|
+
language: str = Field(description="The language of the report.")
|
|
130
|
+
topic: Optional[str] = Field(
|
|
131
|
+
default=None, description="The AI-generated topic of the report."
|
|
132
|
+
)
|
|
133
|
+
summary: Optional[str] = Field(
|
|
134
|
+
default=None, description="The summary text of the report in markdown format."
|
|
135
|
+
)
|
|
136
|
+
document_sources: List[DocumentReportEvidence] = Field(
|
|
137
|
+
default=[], description="List of evidence from documents used in the report."
|
|
138
|
+
)
|
|
139
|
+
news_sources: List[NewsReportEvidence] = Field(
|
|
140
|
+
default=[], description="List of evidence from news sources used in the report."
|
|
141
|
+
)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Copyright 2024 Market Logic Software AG. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
This module contains the functions to retrieve reports from the DeepSights API.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from ratelimit import sleep_and_retry, limits
|
|
20
|
+
from deepsights.api import DeepSights
|
|
21
|
+
from deepsights.minions._minions import minion_wait_for_completion
|
|
22
|
+
from deepsights.reports.model import Report
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
#################################################
|
|
26
|
+
@sleep_and_retry
|
|
27
|
+
@limits(calls=3, period=60)
|
|
28
|
+
def report_create(api: DeepSights, question: str) -> str:
|
|
29
|
+
"""
|
|
30
|
+
Creates a new report by submitting a question to the DeepSights API.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
|
|
34
|
+
api (DeepSights): An instance of the DeepSights API client.
|
|
35
|
+
question (str): The question to be submitted for the report.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
|
|
39
|
+
str: The ID of the created report's minion job.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
body = {"input": question}
|
|
43
|
+
response = api.post(
|
|
44
|
+
"/minion-commander-service/desk-researches", body=body, timeout=5
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
return response["minion_job"]["id"]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
#################################################
|
|
51
|
+
def report_wait_for_completion(api: DeepSights, report_id: str, timeout=600):
|
|
52
|
+
"""
|
|
53
|
+
Waits for the completion of a report.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
|
|
57
|
+
api (DeepSights): The DeepSights API instance.
|
|
58
|
+
report_id (str): The ID of the report.
|
|
59
|
+
timeout (int, optional): The maximum time to wait for the report to complete, in seconds. Defaults to 600.
|
|
60
|
+
|
|
61
|
+
Raises:
|
|
62
|
+
|
|
63
|
+
ValueError: If the report fails to complete.
|
|
64
|
+
"""
|
|
65
|
+
return minion_wait_for_completion(api, "desk-researches", report_id, timeout)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
#################################################
|
|
69
|
+
def report_get(api: DeepSights, report_id: str) -> Report:
|
|
70
|
+
"""
|
|
71
|
+
Loads a report from the DeepSights API.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
|
|
75
|
+
api (DeepSights): An instance of the DeepSights API client.
|
|
76
|
+
report_id (str): The ID of the report to load.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
|
|
80
|
+
Report: The loaded report.
|
|
81
|
+
"""
|
|
82
|
+
response = api.get(f"/minion-commander-service/desk-researches/{report_id}")
|
|
83
|
+
|
|
84
|
+
return Report(
|
|
85
|
+
**dict(
|
|
86
|
+
id=response["minion_job"]["id"],
|
|
87
|
+
status=response["minion_job"]["status"],
|
|
88
|
+
question=response["context"]["input"],
|
|
89
|
+
language=response["context"]["input_language"],
|
|
90
|
+
topic=response["context"]["topic"],
|
|
91
|
+
summary=response["context"]["summary"],
|
|
92
|
+
document_sources=response["context"]["artifact_vector_search_results"],
|
|
93
|
+
news_sources=response["context"]["scs_news_search_results"],
|
|
94
|
+
)
|
|
95
|
+
)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Copyright 2024 Market Logic Software AG. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
This module contains utility functions and classes used by the DeepSights API.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from deepsights.utils._utils import run_in_parallel
|
|
20
|
+
from deepsights.utils._cache import create_global_lru_cache
|
|
21
|
+
from deepsights.utils._ranking import (
|
|
22
|
+
rrf_merge_multi,
|
|
23
|
+
rrf_merge_single,
|
|
24
|
+
rerank_by_recency,
|
|
25
|
+
promote_exact_matches,
|
|
26
|
+
)
|
|
27
|
+
from deepsights.utils.model import (
|
|
28
|
+
DeepSightsBaseModel,
|
|
29
|
+
DeepSightsIdModel,
|
|
30
|
+
DeepSightsIdTitleModel,
|
|
31
|
+
)
|