reportify-sdk 0.2.9__py3-none-any.whl → 0.3.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.
reportify_sdk/__init__.py CHANGED
@@ -20,7 +20,7 @@ from reportify_sdk.exceptions import (
20
20
  APIError,
21
21
  )
22
22
 
23
- __version__ = "0.2.9"
23
+ __version__ = "0.3.0"
24
24
  __all__ = [
25
25
  "Reportify",
26
26
  "ReportifyError",
reportify_sdk/chat.py CHANGED
@@ -54,7 +54,7 @@ class ChatModule:
54
54
  categories: Filter by document categories
55
55
  markets: Filter by markets (cn, hk, us)
56
56
  institutions: Filter by institutions
57
- symbols: Filter by stock symbols
57
+ symbols: Stock symbols in market:ticker format (e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
58
58
  tags: Filter by tags
59
59
  start_date: Start date filter (YYYY-MM-DD)
60
60
  end_date: End date filter (YYYY-MM-DD)
reportify_sdk/client.py CHANGED
@@ -67,13 +67,14 @@ class Reportify:
67
67
  self._chat = None
68
68
  self._agent = None
69
69
  self._user = None
70
+ self._search = None
70
71
 
71
72
  def _get_headers(self) -> dict[str, str]:
72
73
  """Get default headers for API requests"""
73
74
  return {
74
75
  "Authorization": f"Bearer {self.api_key}",
75
76
  "Content-Type": "application/json",
76
- "User-Agent": "reportify-sdk-python/0.2.9",
77
+ "User-Agent": "reportify-sdk-python/0.3.0",
77
78
  }
78
79
 
79
80
  def _request(
@@ -157,338 +158,19 @@ class Reportify:
157
158
  else:
158
159
  raise APIError(f"API error: {status_code}")
159
160
 
160
- # -------------------------------------------------------------------------
161
- # Search Methods
162
- # -------------------------------------------------------------------------
163
-
164
- def search(
165
- self,
166
- query: str,
167
- *,
168
- num: int = 10,
169
- symbols: list[str] | None = None,
170
- industries: list[str] | None = None,
171
- channel_ids: list[str] | None = None,
172
- start_datetime: str | None = None,
173
- end_datetime: str | None = None,
174
- ) -> list[dict[str, Any]]:
175
- """
176
- Search documents across all categories
177
-
178
- Args:
179
- query: Search query string
180
- num: Number of results to return (default: 10, max: 100)
181
- symbols: Filter by stock symbols (e.g., ["US:AAPL", "HK:0700"])
182
- industries: Filter by industries
183
- channel_ids: Filter by channel IDs
184
- start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
185
- end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
186
-
187
- Returns:
188
- List of matching documents
189
-
190
- Example:
191
- >>> docs = client.search("Tesla earnings", num=10)
192
- >>> for doc in docs:
193
- ... print(doc["title"])
194
- """
195
- data: dict[str, Any] = {
196
- "query": query,
197
- "num": num,
198
- }
199
- if symbols:
200
- data["symbols"] = symbols
201
- if industries:
202
- data["industries"] = industries
203
- if channel_ids:
204
- data["channel_ids"] = channel_ids
205
- if start_datetime:
206
- data["start_datetime"] = start_datetime
207
- if end_datetime:
208
- data["end_datetime"] = end_datetime
209
-
210
- response = self._post("/v2/search", json=data)
211
- return response.get("docs", [])
212
-
213
- def search_news(
214
- self,
215
- query: str,
216
- *,
217
- num: int = 10,
218
- symbols: list[str] | None = None,
219
- channel_ids: list[str] | None = None,
220
- start_datetime: str | None = None,
221
- end_datetime: str | None = None,
222
- ) -> list[dict[str, Any]]:
223
- """
224
- Search news articles
225
-
226
- Args:
227
- query: Search query string
228
- num: Number of results to return
229
- symbols: Filter by stock symbols
230
- channel_ids: Filter by channel IDs
231
- start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
232
- end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
233
-
234
- Returns:
235
- List of news articles
236
- """
237
- data: dict[str, Any] = {"query": query, "num": num}
238
- if symbols:
239
- data["symbols"] = symbols
240
- if channel_ids:
241
- data["channel_ids"] = channel_ids
242
- if start_datetime:
243
- data["start_datetime"] = start_datetime
244
- if end_datetime:
245
- data["end_datetime"] = end_datetime
246
-
247
- response = self._post("/v2/search/news", json=data)
248
- return response.get("docs", [])
249
-
250
- def search_reports(
251
- self,
252
- query: str,
253
- *,
254
- num: int = 10,
255
- symbols: list[str] | None = None,
256
- industries: list[str] | None = None,
257
- channel_ids: list[str] | None = None,
258
- start_datetime: str | None = None,
259
- end_datetime: str | None = None,
260
- ) -> list[dict[str, Any]]:
261
- """
262
- Search research reports
263
-
264
- Args:
265
- query: Search query string
266
- num: Number of results to return
267
- symbols: Filter by stock symbols
268
- industries: Filter by industries
269
- channel_ids: Filter by channel IDs
270
- start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
271
- end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
272
-
273
- Returns:
274
- List of research reports
275
- """
276
- data: dict[str, Any] = {"query": query, "num": num}
277
- if symbols:
278
- data["symbols"] = symbols
279
- if industries:
280
- data["industries"] = industries
281
- if channel_ids:
282
- data["channel_ids"] = channel_ids
283
- if start_datetime:
284
- data["start_datetime"] = start_datetime
285
- if end_datetime:
286
- data["end_datetime"] = end_datetime
287
-
288
- response = self._post("/v2/search/reports", json=data)
289
- return response.get("docs", [])
290
-
291
- def search_filings(
292
- self,
293
- query: str,
294
- symbols: list[str],
295
- *,
296
- num: int = 10,
297
- start_datetime: str | None = None,
298
- end_datetime: str | None = None,
299
- ) -> list[dict[str, Any]]:
300
- """
301
- Search company filings and announcements
302
-
303
- Args:
304
- query: Search query string
305
- symbols: Stock symbols to filter by (required)
306
- num: Number of results to return
307
- start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
308
- end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
309
-
310
- Returns:
311
- List of filings
312
- """
313
- data: dict[str, Any] = {"query": query, "symbols": symbols, "num": num}
314
- if start_datetime:
315
- data["start_datetime"] = start_datetime
316
- if end_datetime:
317
- data["end_datetime"] = end_datetime
318
-
319
- response = self._post("/v2/search/filings", json=data)
320
- return response.get("docs", [])
321
-
322
- def search_transcripts(
323
- self,
324
- query: str,
325
- symbols: list[str],
326
- *,
327
- num: int = 10,
328
- start_datetime: str | None = None,
329
- end_datetime: str | None = None,
330
- ) -> list[dict[str, Any]]:
331
- """
332
- Search earnings call transcripts (conference calls)
333
-
334
- Args:
335
- query: Search query string
336
- symbols: Stock symbols to filter by (required)
337
- num: Number of results to return
338
- start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
339
- end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
340
-
341
- Returns:
342
- List of transcripts
343
- """
344
- data: dict[str, Any] = {"query": query, "symbols": symbols, "num": num}
345
- if start_datetime:
346
- data["start_datetime"] = start_datetime
347
- if end_datetime:
348
- data["end_datetime"] = end_datetime
349
-
350
- response = self._post("/v2/search/conference-calls", json=data)
351
- return response.get("docs", [])
352
-
353
- def search_earnings_pack(
354
- self,
355
- query: str,
356
- symbols: list[str],
357
- *,
358
- num: int = 10,
359
- start_datetime: str | None = None,
360
- end_datetime: str | None = None,
361
- ) -> list[dict[str, Any]]:
362
- """
363
- Search earnings pack documents
364
-
365
- Includes financial reports, earnings call transcripts,
366
- presentation materials, and press releases.
367
-
368
- Args:
369
- query: Search query string
370
- symbols: Stock symbols to filter by (required)
371
- num: Number of results to return
372
- start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
373
- end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
374
-
375
- Returns:
376
- List of earnings pack documents
377
- """
378
- data: dict[str, Any] = {"query": query, "symbols": symbols, "num": num}
379
- if start_datetime:
380
- data["start_datetime"] = start_datetime
381
- if end_datetime:
382
- data["end_datetime"] = end_datetime
383
-
384
- response = self._post("/v2/search/earnings-pack", json=data)
385
- return response.get("docs", [])
386
-
387
- def search_minutes(
388
- self,
389
- query: str,
390
- *,
391
- num: int = 10,
392
- symbols: list[str] | None = None,
393
- start_datetime: str | None = None,
394
- end_datetime: str | None = None,
395
- ) -> list[dict[str, Any]]:
396
- """
397
- Search minutes transcripts
398
-
399
- Includes conference calls and IR (Investor Relations) meetings.
400
-
401
- Args:
402
- query: Search query string
403
- num: Number of results to return
404
- symbols: Filter by stock symbols
405
- start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
406
- end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
407
-
408
- Returns:
409
- List of minutes transcripts
410
- """
411
- data: dict[str, Any] = {"query": query, "num": num}
412
- if symbols:
413
- data["symbols"] = symbols
414
- if start_datetime:
415
- data["start_datetime"] = start_datetime
416
- if end_datetime:
417
- data["end_datetime"] = end_datetime
418
-
419
- response = self._post("/v2/search/minutes", json=data)
420
- return response.get("docs", [])
421
-
422
- def search_socials(
423
- self,
424
- query: str,
425
- *,
426
- num: int = 10,
427
- symbols: list[str] | None = None,
428
- channel_ids: list[str] | None = None,
429
- start_datetime: str | None = None,
430
- end_datetime: str | None = None,
431
- ) -> list[dict[str, Any]]:
432
- """
433
- Search social media content and market sentiment
434
-
435
- Args:
436
- query: Search query string
437
- num: Number of results to return
438
- symbols: Filter by stock symbols
439
- channel_ids: Filter by channel IDs
440
- start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
441
- end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
442
-
443
- Returns:
444
- List of social media content
445
- """
446
- data: dict[str, Any] = {"query": query, "num": num}
447
- if symbols:
448
- data["symbols"] = symbols
449
- if channel_ids:
450
- data["channel_ids"] = channel_ids
451
- if start_datetime:
452
- data["start_datetime"] = start_datetime
453
- if end_datetime:
454
- data["end_datetime"] = end_datetime
455
-
456
- response = self._post("/v2/search/socials", json=data)
457
- return response.get("docs", [])
458
-
459
- def search_webpages(
460
- self,
461
- query: str,
462
- *,
463
- num: int = 10,
464
- start_datetime: str | None = None,
465
- end_datetime: str | None = None,
466
- ) -> list[dict[str, Any]]:
467
- """
468
- Search webpage content
469
-
470
- Args:
471
- query: Search query string
472
- num: Number of results to return
473
- start_datetime: Start datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
474
- end_datetime: End datetime filter (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
475
-
476
- Returns:
477
- List of webpage content
478
- """
479
- data: dict[str, Any] = {"query": query, "num": num}
480
- if start_datetime:
481
- data["start_datetime"] = start_datetime
482
- if end_datetime:
483
- data["end_datetime"] = end_datetime
484
-
485
- response = self._post("/v2/search/webpages", json=data)
486
- return response.get("docs", [])
487
161
 
488
162
  # -------------------------------------------------------------------------
489
163
  # Sub-modules (lazy loading)
490
164
  # -------------------------------------------------------------------------
491
165
 
166
+ @property
167
+ def search(self):
168
+ """Search module for document search across all categories"""
169
+ if self._search is None:
170
+ from reportify_sdk.search import SearchModule
171
+ self._search = SearchModule(self)
172
+ return self._search
173
+
492
174
  @property
493
175
  def stock(self):
494
176
  """Stock data module for financial statements, prices, etc."""
reportify_sdk/docs.py CHANGED
@@ -101,7 +101,7 @@ class DocsModule:
101
101
  List documents with filters
102
102
 
103
103
  Args:
104
- symbols: Filter by stock symbols
104
+ symbols: Stock symbols in market:ticker format (e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
105
105
  categories: Filter by document categories (financials, transcripts, reports, news, files, filings, socials)
106
106
  markets: Filter by markets (cn, hk, us)
107
107
  institutions: Filter by institutions
@@ -176,7 +176,7 @@ class DocsModule:
176
176
 
177
177
  Args:
178
178
  query: Search query string
179
- symbols: Filter by stock symbols
179
+ symbols: Stock symbols in market:ticker format (e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
180
180
  categories: Filter by document categories (financials, transcripts, reports, news, filings, socials)
181
181
  markets: Filter by markets (cn, hk, us)
182
182
  institutions: Filter by institutions
@@ -251,7 +251,7 @@ class DocsModule:
251
251
  Query documents by stock symbols
252
252
 
253
253
  Args:
254
- symbols: Stock symbols to filter by (required)
254
+ symbols: Stock symbols in market:ticker format (required, e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
255
255
  categories: Filter by document categories
256
256
  markets: Filter by markets (cn, hk, us)
257
257
  start_date: Start date filter (YYYY-MM-DD)
@@ -345,7 +345,7 @@ class DocsModule:
345
345
 
346
346
  Args:
347
347
  query: Search query string
348
- symbols: Filter by stock symbols
348
+ symbols: Stock symbols in market:ticker format (e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
349
349
  categories: Filter by document categories
350
350
  markets: Filter by markets (cn, hk, us)
351
351
  institutions: Filter by institutions
@@ -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: Stock symbols in market:ticker format (e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
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: Stock symbols in market:ticker format (e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
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: Stock symbols in market:ticker format (e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
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 in market:ticker format (required, e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
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 in market:ticker format (required, e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
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 in market:ticker format (required, e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
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: Stock symbols in market:ticker format (e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
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: Stock symbols in market:ticker format (e.g., US:AAPL, HK:00700, SH:600519, SZ:000001)
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", [])
reportify_sdk/stock.py CHANGED
@@ -118,7 +118,7 @@ class StockModule:
118
118
  Get income statement data
119
119
 
120
120
  Args:
121
- symbol: Stock symbol (e.g., "US:AAPL")
121
+ symbol: Stock symbol
122
122
  period: Report cycle ("annual", "quarterly", "cumulative quarterly")
123
123
  limit: Return latest N records (default: 8)
124
124
  start_date: Start date (YYYY-MM-DD)
@@ -329,7 +329,7 @@ class StockModule:
329
329
  Get real-time stock quote
330
330
 
331
331
  Args:
332
- symbol: Stock symbol (e.g., "US:AAPL", "688001", "00700")
332
+ symbol: Stock symbol
333
333
 
334
334
  Returns:
335
335
  DataFrame with real-time quote data
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reportify-sdk
3
- Version: 0.2.9
3
+ Version: 0.3.0
4
4
  Summary: Python SDK for Reportify API - Financial data and document search
5
5
  Author-email: Reportify <support@reportify.cn>
6
6
  License-Expression: MIT
@@ -75,19 +75,18 @@ balance = client.stock.balance_sheet("US:AAPL")
75
75
  cashflow = client.stock.cashflow_statement("US:AAPL")
76
76
 
77
77
  # Price data
78
- prices = client.stock.prices("US:AAPL", limit=30)
79
- kline = client.stock.kline("US:TSLA", interval="1d", limit=100)
78
+ prices = client.stock.prices("US:AAPL", start_date="2024-01-01")
80
79
 
81
- # Real-time quotes
82
- quotes = client.stock.quote(["US:AAPL", "US:MSFT"])
80
+ # Real-time quote
81
+ quote = client.stock.quote("US:AAPL")
83
82
 
84
83
  # Company info
85
84
  overview = client.stock.overview("US:AAPL")
86
85
  shareholders = client.stock.shareholders("US:AAPL")
87
86
 
88
87
  # Screening and calendar
89
- stocks = client.stock.screener(market="US", min_market_cap=1e10)
90
- earnings = client.stock.earnings_calendar(area="us", start_date="2024-01-01")
88
+ stocks = client.stock.screener(country="US", market_cap_more_than=1e10)
89
+ earnings = client.stock.earnings_calendar(market="us", start_date="2024-01-01", end_date="2024-01-31")
91
90
  ```
92
91
 
93
92
  ### Timeline
@@ -118,6 +117,102 @@ summary = client.docs.summary("doc_id")
118
117
  # List and search documents
119
118
  docs = client.docs.list(symbols=["US:AAPL"], page_size=10)
120
119
  chunks = client.docs.search_chunks("revenue breakdown", num=5)
120
+
121
+ # Upload documents
122
+ result = client.docs.upload([
123
+ {"url": "https://example.com/report.pdf", "name": "Annual Report"}
124
+ ])
125
+ ```
126
+
127
+ ### Quant (Quantitative Analysis)
128
+
129
+ ```python
130
+ # Compute technical indicators
131
+ df = client.quant.compute_indicators(["000001"], "RSI(14)")
132
+ df = client.quant.compute_indicators(["000001"], "MACD()")
133
+
134
+ # Screen stocks by formula
135
+ stocks = client.quant.screen(formula="RSI(14) < 30")
136
+ stocks = client.quant.screen(formula="CROSS(MA(5), MA(20))")
137
+
138
+ # Get OHLCV data
139
+ ohlcv = client.quant.ohlcv("000001", start_date="2024-01-01")
140
+ ohlcv_batch = client.quant.ohlcv_batch(["000001", "600519"])
141
+
142
+ # Backtest strategy
143
+ result = client.quant.backtest(
144
+ start_date="2023-01-01",
145
+ end_date="2024-01-01",
146
+ symbol="000001",
147
+ entry_formula="CROSS(MA(5), MA(20))",
148
+ exit_formula="CROSSDOWN(MA(5), MA(20))"
149
+ )
150
+ print(f"Total Return: {result['total_return_pct']:.2%}")
151
+ ```
152
+
153
+ ### Concepts
154
+
155
+ ```python
156
+ # Get latest concepts
157
+ concepts = client.concepts.latest()
158
+ for c in concepts:
159
+ print(c["concept_name"])
160
+
161
+ # Get today's concept feeds
162
+ feeds = client.concepts.today()
163
+ ```
164
+
165
+ ### Channels
166
+
167
+ ```python
168
+ # Search channels
169
+ result = client.channels.search("Goldman Sachs")
170
+
171
+ # Get followed channels
172
+ followings = client.channels.followings()
173
+
174
+ # Follow/unfollow a channel
175
+ client.channels.follow("channel_id")
176
+ client.channels.unfollow("channel_id")
177
+ ```
178
+
179
+ ### Chat
180
+
181
+ ```python
182
+ # Chat completion based on documents
183
+ response = client.chat.completion(
184
+ "What are Tesla's revenue projections?",
185
+ symbols=["US:TSLA"],
186
+ mode="comprehensive" # concise, comprehensive, deepresearch
187
+ )
188
+ print(response["message"])
189
+ ```
190
+
191
+ ### Agent
192
+
193
+ ```python
194
+ # Create agent conversation
195
+ conv = client.agent.create_conversation(agent_id=11887655289749510)
196
+
197
+ # Chat with agent
198
+ response = client.agent.chat(
199
+ conversation_id=conv["id"],
200
+ message="Analyze NVIDIA's latest earnings"
201
+ )
202
+
203
+ # Get agent-generated file
204
+ file_content = client.agent.get_file("file_id")
205
+ with open("output.xlsx", "wb") as f:
206
+ f.write(file_content)
207
+ ```
208
+
209
+ ### User
210
+
211
+ ```python
212
+ # Get followed companies
213
+ companies = client.user.followed_companies()
214
+ for company in companies:
215
+ print(f"{company['symbol']}: {company['name']}")
121
216
  ```
122
217
 
123
218
  ## Error Handling
@@ -0,0 +1,19 @@
1
+ reportify_sdk/__init__.py,sha256=l7E4ELvxQ8qSEpgDK3-I3JfhBBKmLS8RP4hpbxieVac,662
2
+ reportify_sdk/agent.py,sha256=y1iP4Jq7-ESMxeCWB_vxkAvwCjUCWT8K-ZSeJswU6nQ,6358
3
+ reportify_sdk/channels.py,sha256=VbBCispCiP2Mzqn5lmBWVNWog4ElVni46mK2zg7KKzg,3518
4
+ reportify_sdk/chat.py,sha256=GQVfre4p2H9Kb0imX1-LvGqMrtnsuGhjQskBNUqUI_I,3613
5
+ reportify_sdk/client.py,sha256=RqJusEisy7-bWC35gTByb3E6BaD5DlDsTP7VmZ9zFQ0,8206
6
+ reportify_sdk/concepts.py,sha256=XlHPuuZacFFUccMthyeb5R2OTayFYxXgIODKNfJLa_c,1891
7
+ reportify_sdk/docs.py,sha256=PsOJrm-tFvvfHyVOWUptLC6wHhze5AMizD8MkcktEBo,16814
8
+ reportify_sdk/exceptions.py,sha256=r2_C_kTh6tCrQnfA3UozSqMMA-2OBnoP3pGpgYeqcdU,1049
9
+ reportify_sdk/kb.py,sha256=3e82_56hvnGQ2fI404g3DAem9javPY7OpE5B8goYOB8,2895
10
+ reportify_sdk/quant.py,sha256=9rWKWo2UlG3GfsQC-jpEgXUl25ojEabpvOGISyGMamM,15110
11
+ reportify_sdk/search.py,sha256=rzleME8_DwdiJ-__0qPjXkQZmaJ6JXH-ycJ_mUlkkNw,11866
12
+ reportify_sdk/stock.py,sha256=sBUYmbj3nz5HaOGF5HakRF5Qt9Y5veZA1U2vDRau2vw,21473
13
+ reportify_sdk/timeline.py,sha256=7ZbF5-0eGoF_N5h9swEyYgZSaMb54PMwLDXlaqFS4ns,5396
14
+ reportify_sdk/user.py,sha256=lsdhvaovllEwYiz4fhhSwl8PMX8tKswzABAvZbB0iJw,1261
15
+ reportify_sdk-0.3.0.dist-info/licenses/LICENSE,sha256=zBUq4DL4lE-fZU_PMkr0gnxkYS1LhdRHFw8_LmCb-ek,1066
16
+ reportify_sdk-0.3.0.dist-info/METADATA,sha256=1xLeNuSnTG6nMOzBH6AIzmoWdDWAN5d3HXXGPSQfMZA,6451
17
+ reportify_sdk-0.3.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
18
+ reportify_sdk-0.3.0.dist-info/top_level.txt,sha256=tc_dzCSWIDsNbHSi-FlyEEX8xwinhN9gl-CwyLRE4B0,14
19
+ reportify_sdk-0.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.10.1)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,18 +0,0 @@
1
- reportify_sdk/__init__.py,sha256=MZT6iafbhygOeqejK_rh0mBoXizw6f21J7M4ghlUj28,662
2
- reportify_sdk/agent.py,sha256=y1iP4Jq7-ESMxeCWB_vxkAvwCjUCWT8K-ZSeJswU6nQ,6358
3
- reportify_sdk/channels.py,sha256=VbBCispCiP2Mzqn5lmBWVNWog4ElVni46mK2zg7KKzg,3518
4
- reportify_sdk/chat.py,sha256=w2KE8kO9PgL1uFSpBGI-8oD6pVhr0NF5ZAS_YoaFU5I,3551
5
- reportify_sdk/client.py,sha256=6PFJj_2kVQxQ1YXCz-cAmFijAn-9RrYd8WFFzJJj27M,18745
6
- reportify_sdk/concepts.py,sha256=XlHPuuZacFFUccMthyeb5R2OTayFYxXgIODKNfJLa_c,1891
7
- reportify_sdk/docs.py,sha256=6VylFci91gdV89tVKnaUgLYRF3suGEFTkO85VwK_ip4,16570
8
- reportify_sdk/exceptions.py,sha256=r2_C_kTh6tCrQnfA3UozSqMMA-2OBnoP3pGpgYeqcdU,1049
9
- reportify_sdk/kb.py,sha256=3e82_56hvnGQ2fI404g3DAem9javPY7OpE5B8goYOB8,2895
10
- reportify_sdk/quant.py,sha256=9rWKWo2UlG3GfsQC-jpEgXUl25ojEabpvOGISyGMamM,15110
11
- reportify_sdk/stock.py,sha256=DkZkLXAPVK4AbkjWRRe6OdjXjUyJD1JZz0hEXMjtT_Y,21528
12
- reportify_sdk/timeline.py,sha256=7ZbF5-0eGoF_N5h9swEyYgZSaMb54PMwLDXlaqFS4ns,5396
13
- reportify_sdk/user.py,sha256=lsdhvaovllEwYiz4fhhSwl8PMX8tKswzABAvZbB0iJw,1261
14
- reportify_sdk-0.2.9.dist-info/licenses/LICENSE,sha256=zBUq4DL4lE-fZU_PMkr0gnxkYS1LhdRHFw8_LmCb-ek,1066
15
- reportify_sdk-0.2.9.dist-info/METADATA,sha256=cGo0IJ7EViR9IUG71fqyzpicvklzGH9tgYgyB7VwZfU,4311
16
- reportify_sdk-0.2.9.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
17
- reportify_sdk-0.2.9.dist-info/top_level.txt,sha256=tc_dzCSWIDsNbHSi-FlyEEX8xwinhN9gl-CwyLRE4B0,14
18
- reportify_sdk-0.2.9.dist-info/RECORD,,