reportify-sdk 0.2.8__py3-none-any.whl → 0.2.10__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.
- reportify_sdk/__init__.py +1 -1
- reportify_sdk/agent.py +213 -0
- reportify_sdk/channels.py +126 -0
- reportify_sdk/chat.py +107 -0
- reportify_sdk/client.py +62 -180
- reportify_sdk/docs.py +351 -8
- reportify_sdk/kb.py +15 -0
- reportify_sdk/search.py +357 -0
- reportify_sdk/stock.py +203 -121
- reportify_sdk/timeline.py +34 -0
- reportify_sdk/user.py +44 -0
- {reportify_sdk-0.2.8.dist-info → reportify_sdk-0.2.10.dist-info}/METADATA +1 -1
- reportify_sdk-0.2.10.dist-info/RECORD +19 -0
- {reportify_sdk-0.2.8.dist-info → reportify_sdk-0.2.10.dist-info}/WHEEL +1 -1
- reportify_sdk-0.2.8.dist-info/RECORD +0 -14
- {reportify_sdk-0.2.8.dist-info → reportify_sdk-0.2.10.dist-info}/licenses/LICENSE +0 -0
- {reportify_sdk-0.2.8.dist-info → reportify_sdk-0.2.10.dist-info}/top_level.txt +0 -0
reportify_sdk/kb.py
CHANGED
|
@@ -3,8 +3,13 @@ Knowledge Base Module
|
|
|
3
3
|
|
|
4
4
|
Provides access to user's personal knowledge base for searching
|
|
5
5
|
uploaded documents and folders.
|
|
6
|
+
|
|
7
|
+
NOTE: This module uses internal APIs that are not documented in the public OpenAPI spec.
|
|
8
|
+
These endpoints may change without notice. For production use, consider using
|
|
9
|
+
the documented docs.search_chunks() method instead.
|
|
6
10
|
"""
|
|
7
11
|
|
|
12
|
+
import warnings
|
|
8
13
|
from typing import TYPE_CHECKING, Any
|
|
9
14
|
|
|
10
15
|
if TYPE_CHECKING:
|
|
@@ -39,6 +44,10 @@ class KBModule:
|
|
|
39
44
|
"""
|
|
40
45
|
Search user's knowledge base
|
|
41
46
|
|
|
47
|
+
.. deprecated::
|
|
48
|
+
This method uses an internal API not documented in the public OpenAPI spec.
|
|
49
|
+
Consider using client.docs.search_chunks() instead.
|
|
50
|
+
|
|
42
51
|
Performs semantic search across documents the user has uploaded
|
|
43
52
|
to their personal knowledge base.
|
|
44
53
|
|
|
@@ -59,6 +68,12 @@ class KBModule:
|
|
|
59
68
|
... print(chunk["content"][:100])
|
|
60
69
|
... print(f"From: {chunk['doc']['title']}")
|
|
61
70
|
"""
|
|
71
|
+
warnings.warn(
|
|
72
|
+
"kb.search() uses an internal API not documented in the public OpenAPI spec. "
|
|
73
|
+
"Consider using docs.search_chunks() instead.",
|
|
74
|
+
DeprecationWarning,
|
|
75
|
+
stacklevel=2,
|
|
76
|
+
)
|
|
62
77
|
data: dict[str, Any] = {
|
|
63
78
|
"query": query,
|
|
64
79
|
"num": num,
|
reportify_sdk/search.py
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Search Module
|
|
3
|
+
|
|
4
|
+
Provides document search functionality across various categories.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from reportify_sdk.client import Reportify
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SearchModule:
|
|
14
|
+
"""
|
|
15
|
+
Search module for document search functionality.
|
|
16
|
+
|
|
17
|
+
Access via client.search:
|
|
18
|
+
>>> results = client.search.all("Tesla earnings")
|
|
19
|
+
>>> news = client.search.news("Apple iPhone")
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, client: "Reportify"):
|
|
23
|
+
self._client = client
|
|
24
|
+
|
|
25
|
+
def _post(self, path: str, json: dict[str, Any] | None = None) -> dict[str, Any]:
|
|
26
|
+
return self._client._post(path, json=json)
|
|
27
|
+
|
|
28
|
+
def all(
|
|
29
|
+
self,
|
|
30
|
+
query: str,
|
|
31
|
+
*,
|
|
32
|
+
num: int = 10,
|
|
33
|
+
categories: list[str] | None = None,
|
|
34
|
+
symbols: list[str] | None = None,
|
|
35
|
+
industries: list[str] | None = None,
|
|
36
|
+
channel_ids: list[str] | None = None,
|
|
37
|
+
start_datetime: str | None = None,
|
|
38
|
+
end_datetime: str | None = None,
|
|
39
|
+
) -> list[dict[str, Any]]:
|
|
40
|
+
"""
|
|
41
|
+
Search documents across all categories
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
query: Search query string
|
|
45
|
+
num: Number of results to return (default: 10, max: 100)
|
|
46
|
+
categories: Filter by categories (news, reports, filings, transcripts, socials)
|
|
47
|
+
symbols: Filter by stock symbols (e.g., ["US:AAPL", "HK:0700"])
|
|
48
|
+
industries: Filter by industries
|
|
49
|
+
channel_ids: Filter by channel IDs
|
|
50
|
+
start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
|
|
51
|
+
end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
List of matching documents
|
|
55
|
+
"""
|
|
56
|
+
data: dict[str, Any] = {"query": query, "num": num}
|
|
57
|
+
if categories:
|
|
58
|
+
data["categories"] = categories
|
|
59
|
+
if symbols:
|
|
60
|
+
data["symbols"] = symbols
|
|
61
|
+
if industries:
|
|
62
|
+
data["industries"] = industries
|
|
63
|
+
if channel_ids:
|
|
64
|
+
data["channel_ids"] = channel_ids
|
|
65
|
+
if start_datetime:
|
|
66
|
+
data["start_datetime"] = start_datetime
|
|
67
|
+
if end_datetime:
|
|
68
|
+
data["end_datetime"] = end_datetime
|
|
69
|
+
|
|
70
|
+
response = self._post("/v2/search", json=data)
|
|
71
|
+
return response.get("docs", [])
|
|
72
|
+
|
|
73
|
+
def news(
|
|
74
|
+
self,
|
|
75
|
+
query: str,
|
|
76
|
+
*,
|
|
77
|
+
num: int = 10,
|
|
78
|
+
symbols: list[str] | None = None,
|
|
79
|
+
channel_ids: list[str] | None = None,
|
|
80
|
+
start_datetime: str | None = None,
|
|
81
|
+
end_datetime: str | None = None,
|
|
82
|
+
) -> list[dict[str, Any]]:
|
|
83
|
+
"""
|
|
84
|
+
Search news articles
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
query: Search query string
|
|
88
|
+
num: Number of results to return
|
|
89
|
+
symbols: Filter by stock symbols
|
|
90
|
+
channel_ids: Filter by channel IDs
|
|
91
|
+
start_datetime: Start datetime filter
|
|
92
|
+
end_datetime: End datetime filter
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
List of news documents
|
|
96
|
+
"""
|
|
97
|
+
data: dict[str, Any] = {"query": query, "num": num}
|
|
98
|
+
if symbols:
|
|
99
|
+
data["symbols"] = symbols
|
|
100
|
+
if channel_ids:
|
|
101
|
+
data["channel_ids"] = channel_ids
|
|
102
|
+
if start_datetime:
|
|
103
|
+
data["start_datetime"] = start_datetime
|
|
104
|
+
if end_datetime:
|
|
105
|
+
data["end_datetime"] = end_datetime
|
|
106
|
+
|
|
107
|
+
response = self._post("/v2/search/news", json=data)
|
|
108
|
+
return response.get("docs", [])
|
|
109
|
+
|
|
110
|
+
def reports(
|
|
111
|
+
self,
|
|
112
|
+
query: str,
|
|
113
|
+
*,
|
|
114
|
+
num: int = 10,
|
|
115
|
+
symbols: list[str] | None = None,
|
|
116
|
+
industries: list[str] | None = None,
|
|
117
|
+
channel_ids: list[str] | None = None,
|
|
118
|
+
start_datetime: str | None = None,
|
|
119
|
+
end_datetime: str | None = None,
|
|
120
|
+
) -> list[dict[str, Any]]:
|
|
121
|
+
"""
|
|
122
|
+
Search research reports
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
query: Search query string
|
|
126
|
+
num: Number of results to return
|
|
127
|
+
symbols: Filter by stock symbols
|
|
128
|
+
industries: Filter by industries
|
|
129
|
+
channel_ids: Filter by channel IDs
|
|
130
|
+
start_datetime: Start datetime filter
|
|
131
|
+
end_datetime: End datetime filter
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
List of research reports
|
|
135
|
+
"""
|
|
136
|
+
data: dict[str, Any] = {"query": query, "num": num}
|
|
137
|
+
if symbols:
|
|
138
|
+
data["symbols"] = symbols
|
|
139
|
+
if industries:
|
|
140
|
+
data["industries"] = industries
|
|
141
|
+
if channel_ids:
|
|
142
|
+
data["channel_ids"] = channel_ids
|
|
143
|
+
if start_datetime:
|
|
144
|
+
data["start_datetime"] = start_datetime
|
|
145
|
+
if end_datetime:
|
|
146
|
+
data["end_datetime"] = end_datetime
|
|
147
|
+
|
|
148
|
+
response = self._post("/v2/search/reports", json=data)
|
|
149
|
+
return response.get("docs", [])
|
|
150
|
+
|
|
151
|
+
def filings(
|
|
152
|
+
self,
|
|
153
|
+
query: str,
|
|
154
|
+
symbols: list[str],
|
|
155
|
+
*,
|
|
156
|
+
num: int = 10,
|
|
157
|
+
start_datetime: str | None = None,
|
|
158
|
+
end_datetime: str | None = None,
|
|
159
|
+
) -> list[dict[str, Any]]:
|
|
160
|
+
"""
|
|
161
|
+
Search company filings
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
query: Search query string
|
|
165
|
+
symbols: Stock symbols to filter by (required)
|
|
166
|
+
num: Number of results to return
|
|
167
|
+
start_datetime: Start datetime filter
|
|
168
|
+
end_datetime: End datetime filter
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
List of filing documents
|
|
172
|
+
"""
|
|
173
|
+
data: dict[str, Any] = {"query": query, "symbols": symbols, "num": num}
|
|
174
|
+
if start_datetime:
|
|
175
|
+
data["start_datetime"] = start_datetime
|
|
176
|
+
if end_datetime:
|
|
177
|
+
data["end_datetime"] = end_datetime
|
|
178
|
+
|
|
179
|
+
response = self._post("/v2/search/filings", json=data)
|
|
180
|
+
return response.get("docs", [])
|
|
181
|
+
|
|
182
|
+
def conference_calls(
|
|
183
|
+
self,
|
|
184
|
+
query: str,
|
|
185
|
+
symbols: list[str],
|
|
186
|
+
*,
|
|
187
|
+
num: int = 10,
|
|
188
|
+
start_datetime: str | None = None,
|
|
189
|
+
end_datetime: str | None = None,
|
|
190
|
+
fiscal_year: str | None = None,
|
|
191
|
+
fiscal_quarter: str | None = None,
|
|
192
|
+
) -> list[dict[str, Any]]:
|
|
193
|
+
"""
|
|
194
|
+
Search earnings call transcripts and slides
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
query: Search query string
|
|
198
|
+
symbols: Stock symbols to filter by (required)
|
|
199
|
+
num: Number of results to return
|
|
200
|
+
start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
|
|
201
|
+
end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
|
|
202
|
+
fiscal_year: Fiscal year filter (e.g., '2025', '2026')
|
|
203
|
+
fiscal_quarter: Fiscal quarter filter (e.g., 'Q1', 'Q2', 'Q3', 'Q4')
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
List of conference call documents
|
|
207
|
+
"""
|
|
208
|
+
data: dict[str, Any] = {"query": query, "symbols": symbols, "num": num}
|
|
209
|
+
if start_datetime:
|
|
210
|
+
data["start_datetime"] = start_datetime
|
|
211
|
+
if end_datetime:
|
|
212
|
+
data["end_datetime"] = end_datetime
|
|
213
|
+
if fiscal_year:
|
|
214
|
+
data["fiscal_year"] = fiscal_year
|
|
215
|
+
if fiscal_quarter:
|
|
216
|
+
data["fiscal_quarter"] = fiscal_quarter
|
|
217
|
+
|
|
218
|
+
response = self._post("/v2/search/conference-calls", json=data)
|
|
219
|
+
return response.get("docs", [])
|
|
220
|
+
|
|
221
|
+
def earnings_pack(
|
|
222
|
+
self,
|
|
223
|
+
query: str,
|
|
224
|
+
symbols: list[str],
|
|
225
|
+
*,
|
|
226
|
+
num: int = 10,
|
|
227
|
+
start_datetime: str | None = None,
|
|
228
|
+
end_datetime: str | None = None,
|
|
229
|
+
fiscal_year: str | None = None,
|
|
230
|
+
fiscal_quarter: str | None = None,
|
|
231
|
+
) -> list[dict[str, Any]]:
|
|
232
|
+
"""
|
|
233
|
+
Search earnings financial reports
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
query: Search query string
|
|
237
|
+
symbols: Stock symbols to filter by (required)
|
|
238
|
+
num: Number of results to return
|
|
239
|
+
start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
|
|
240
|
+
end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
|
|
241
|
+
fiscal_year: Fiscal year filter (e.g., '2025', '2026')
|
|
242
|
+
fiscal_quarter: Fiscal quarter filter (e.g., 'Q1', 'Q2', 'Q3', 'Q4')
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
List of earnings pack documents
|
|
246
|
+
"""
|
|
247
|
+
data: dict[str, Any] = {"query": query, "symbols": symbols, "num": num}
|
|
248
|
+
if start_datetime:
|
|
249
|
+
data["start_datetime"] = start_datetime
|
|
250
|
+
if end_datetime:
|
|
251
|
+
data["end_datetime"] = end_datetime
|
|
252
|
+
if fiscal_year:
|
|
253
|
+
data["fiscal_year"] = fiscal_year
|
|
254
|
+
if fiscal_quarter:
|
|
255
|
+
data["fiscal_quarter"] = fiscal_quarter
|
|
256
|
+
|
|
257
|
+
response = self._post("/v2/search/earnings-pack", json=data)
|
|
258
|
+
return response.get("docs", [])
|
|
259
|
+
|
|
260
|
+
def minutes(
|
|
261
|
+
self,
|
|
262
|
+
query: str,
|
|
263
|
+
*,
|
|
264
|
+
num: int = 10,
|
|
265
|
+
symbols: list[str] | None = None,
|
|
266
|
+
start_datetime: str | None = None,
|
|
267
|
+
end_datetime: str | None = None,
|
|
268
|
+
) -> list[dict[str, Any]]:
|
|
269
|
+
"""
|
|
270
|
+
Search conference calls and IR (Investor Relations) meetings
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
query: Search query string
|
|
274
|
+
num: Number of results to return
|
|
275
|
+
symbols: Filter by stock symbols
|
|
276
|
+
start_datetime: Start datetime filter
|
|
277
|
+
end_datetime: End datetime filter
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
List of minutes documents
|
|
281
|
+
"""
|
|
282
|
+
data: dict[str, Any] = {"query": query, "num": num}
|
|
283
|
+
if symbols:
|
|
284
|
+
data["symbols"] = symbols
|
|
285
|
+
if start_datetime:
|
|
286
|
+
data["start_datetime"] = start_datetime
|
|
287
|
+
if end_datetime:
|
|
288
|
+
data["end_datetime"] = end_datetime
|
|
289
|
+
|
|
290
|
+
response = self._post("/v2/search/minutes", json=data)
|
|
291
|
+
return response.get("docs", [])
|
|
292
|
+
|
|
293
|
+
def socials(
|
|
294
|
+
self,
|
|
295
|
+
query: str,
|
|
296
|
+
*,
|
|
297
|
+
num: int = 10,
|
|
298
|
+
symbols: list[str] | None = None,
|
|
299
|
+
channel_ids: list[str] | None = None,
|
|
300
|
+
start_datetime: str | None = None,
|
|
301
|
+
end_datetime: str | None = None,
|
|
302
|
+
) -> list[dict[str, Any]]:
|
|
303
|
+
"""
|
|
304
|
+
Search social media content
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
query: Search query string
|
|
308
|
+
num: Number of results to return
|
|
309
|
+
symbols: Filter by stock symbols
|
|
310
|
+
channel_ids: Filter by channel IDs
|
|
311
|
+
start_datetime: Start datetime filter
|
|
312
|
+
end_datetime: End datetime filter
|
|
313
|
+
|
|
314
|
+
Returns:
|
|
315
|
+
List of social media documents
|
|
316
|
+
"""
|
|
317
|
+
data: dict[str, Any] = {"query": query, "num": num}
|
|
318
|
+
if symbols:
|
|
319
|
+
data["symbols"] = symbols
|
|
320
|
+
if channel_ids:
|
|
321
|
+
data["channel_ids"] = channel_ids
|
|
322
|
+
if start_datetime:
|
|
323
|
+
data["start_datetime"] = start_datetime
|
|
324
|
+
if end_datetime:
|
|
325
|
+
data["end_datetime"] = end_datetime
|
|
326
|
+
|
|
327
|
+
response = self._post("/v2/search/socials", json=data)
|
|
328
|
+
return response.get("docs", [])
|
|
329
|
+
|
|
330
|
+
def webpages(
|
|
331
|
+
self,
|
|
332
|
+
query: str,
|
|
333
|
+
*,
|
|
334
|
+
num: int = 10,
|
|
335
|
+
start_datetime: str | None = None,
|
|
336
|
+
end_datetime: str | None = None,
|
|
337
|
+
) -> list[dict[str, Any]]:
|
|
338
|
+
"""
|
|
339
|
+
Search webpage content
|
|
340
|
+
|
|
341
|
+
Args:
|
|
342
|
+
query: Search query string
|
|
343
|
+
num: Number of results to return
|
|
344
|
+
start_datetime: Start datetime filter
|
|
345
|
+
end_datetime: End datetime filter
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
List of webpage content
|
|
349
|
+
"""
|
|
350
|
+
data: dict[str, Any] = {"query": query, "num": num}
|
|
351
|
+
if start_datetime:
|
|
352
|
+
data["start_datetime"] = start_datetime
|
|
353
|
+
if end_datetime:
|
|
354
|
+
data["end_datetime"] = end_datetime
|
|
355
|
+
|
|
356
|
+
response = self._post("/v2/search/webpages", json=data)
|
|
357
|
+
return response.get("docs", [])
|