kensho-kfinance 3.2.4__py3-none-any.whl → 4.0.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.
- {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-4.0.0.dist-info}/METADATA +3 -3
- {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-4.0.0.dist-info}/RECORD +57 -56
- kfinance/CHANGELOG.md +51 -0
- kfinance/client/batch_request_handling.py +3 -1
- kfinance/client/fetch.py +127 -54
- kfinance/client/kfinance.py +38 -39
- kfinance/client/meta_classes.py +50 -20
- kfinance/client/models/date_and_period_models.py +32 -7
- kfinance/client/models/decimal_with_unit.py +14 -2
- kfinance/client/models/response_models.py +33 -0
- kfinance/client/models/tests/test_decimal_with_unit.py +9 -0
- kfinance/client/tests/test_batch_requests.py +5 -4
- kfinance/client/tests/test_fetch.py +134 -58
- kfinance/client/tests/test_objects.py +207 -145
- kfinance/conftest.py +10 -0
- kfinance/domains/business_relationships/business_relationship_tools.py +17 -8
- kfinance/domains/business_relationships/tests/test_business_relationship_tools.py +18 -16
- kfinance/domains/capitalizations/capitalization_models.py +7 -5
- kfinance/domains/capitalizations/capitalization_tools.py +38 -20
- kfinance/domains/capitalizations/tests/test_capitalization_tools.py +66 -36
- kfinance/domains/companies/company_models.py +22 -2
- kfinance/domains/companies/company_tools.py +49 -16
- kfinance/domains/companies/tests/test_company_tools.py +27 -9
- kfinance/domains/competitors/competitor_tools.py +19 -5
- kfinance/domains/competitors/tests/test_competitor_tools.py +22 -19
- kfinance/domains/cusip_and_isin/cusip_and_isin_tools.py +29 -8
- kfinance/domains/cusip_and_isin/tests/test_cusip_and_isin_tools.py +13 -8
- kfinance/domains/earnings/earning_tools.py +73 -29
- kfinance/domains/earnings/tests/test_earnings_tools.py +52 -43
- kfinance/domains/line_items/line_item_models.py +372 -16
- kfinance/domains/line_items/line_item_tools.py +198 -46
- kfinance/domains/line_items/tests/test_line_item_tools.py +305 -39
- kfinance/domains/mergers_and_acquisitions/merger_and_acquisition_models.py +46 -2
- kfinance/domains/mergers_and_acquisitions/merger_and_acquisition_tools.py +55 -74
- kfinance/domains/mergers_and_acquisitions/tests/test_merger_and_acquisition_tools.py +61 -59
- kfinance/domains/prices/price_models.py +7 -6
- kfinance/domains/prices/price_tools.py +24 -16
- kfinance/domains/prices/tests/test_price_tools.py +47 -39
- kfinance/domains/segments/segment_models.py +17 -3
- kfinance/domains/segments/segment_tools.py +102 -42
- kfinance/domains/segments/tests/test_segment_tools.py +166 -37
- kfinance/domains/statements/statement_models.py +17 -3
- kfinance/domains/statements/statement_tools.py +130 -46
- kfinance/domains/statements/tests/test_statement_tools.py +251 -49
- kfinance/integrations/local_mcp/kfinance_mcp.py +1 -1
- kfinance/integrations/tests/test_example_notebook.py +57 -16
- kfinance/integrations/tool_calling/all_tools.py +5 -1
- kfinance/integrations/tool_calling/static_tools/get_n_quarters_ago.py +5 -0
- kfinance/integrations/tool_calling/static_tools/tests/test_get_lastest.py +13 -10
- kfinance/integrations/tool_calling/static_tools/tests/test_get_n_quarters_ago.py +2 -1
- kfinance/integrations/tool_calling/tests/test_tool_calling_models.py +15 -4
- kfinance/integrations/tool_calling/tool_calling_models.py +18 -6
- kfinance/version.py +2 -2
- {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-4.0.0.dist-info}/WHEEL +0 -0
- {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-4.0.0.dist-info}/licenses/AUTHORS.md +0 -0
- {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-4.0.0.dist-info}/licenses/LICENSE +0 -0
- {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-4.0.0.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from textwrap import dedent
|
|
1
2
|
from typing import Type
|
|
2
3
|
|
|
3
4
|
from pydantic import BaseModel
|
|
@@ -19,11 +20,22 @@ class GetCusipOrIsinFromIdentifiersResp(ToolRespWithErrors):
|
|
|
19
20
|
|
|
20
21
|
class GetCusipFromIdentifiers(KfinanceTool):
|
|
21
22
|
name: str = "get_cusip_from_identifiers"
|
|
22
|
-
description: str = "
|
|
23
|
+
description: str = dedent("""
|
|
24
|
+
Get the CUSIPs for a group of identifiers.
|
|
25
|
+
|
|
26
|
+
- When possible, pass multiple identifiers in a single call rather than making multiple calls.
|
|
27
|
+
|
|
28
|
+
Examples:
|
|
29
|
+
Query: "What is the CUSIP for Humana?"
|
|
30
|
+
Function: get_cusip_from_identifiers(identifiers=["Humana"])
|
|
31
|
+
|
|
32
|
+
Query: "Get CUSIPs for ATO and DTE"
|
|
33
|
+
Function: get_cusip_from_identifiers(identifiers=["ATO", "DTE"])
|
|
34
|
+
""").strip()
|
|
23
35
|
args_schema: Type[BaseModel] = ToolArgsWithIdentifiers
|
|
24
36
|
accepted_permissions: set[Permission] | None = {Permission.IDPermission}
|
|
25
37
|
|
|
26
|
-
def _run(self, identifiers: list[str]) ->
|
|
38
|
+
def _run(self, identifiers: list[str]) -> GetCusipOrIsinFromIdentifiersResp:
|
|
27
39
|
"""Sample response:
|
|
28
40
|
|
|
29
41
|
{
|
|
@@ -45,23 +57,33 @@ class GetCusipFromIdentifiers(KfinanceTool):
|
|
|
45
57
|
]
|
|
46
58
|
|
|
47
59
|
cusip_responses = process_tasks_in_thread_pool_executor(api_client=api_client, tasks=tasks)
|
|
48
|
-
|
|
60
|
+
return GetCusipOrIsinFromIdentifiersResp(
|
|
49
61
|
results={
|
|
50
62
|
identifier: cusip_resp["cusip"]
|
|
51
63
|
for identifier, cusip_resp in cusip_responses.items()
|
|
52
64
|
},
|
|
53
65
|
errors=list(id_triple_resp.errors.values()),
|
|
54
66
|
)
|
|
55
|
-
return resp_model.model_dump(mode="json")
|
|
56
67
|
|
|
57
68
|
|
|
58
69
|
class GetIsinFromIdentifiers(KfinanceTool):
|
|
59
70
|
name: str = "get_isin_from_identifiers"
|
|
60
|
-
description: str = "
|
|
71
|
+
description: str = dedent("""
|
|
72
|
+
Get the ISINs for a group of identifiers.
|
|
73
|
+
|
|
74
|
+
- When possible, pass multiple identifiers in a single call rather than making multiple calls.
|
|
75
|
+
|
|
76
|
+
Examples:
|
|
77
|
+
Query: "What is the ISIN for Autodesk?"
|
|
78
|
+
Function: get_isin_from_identifiers(identifiers=["Autodesk"])
|
|
79
|
+
|
|
80
|
+
Query: "Get ISINs for RCL and CCL"
|
|
81
|
+
Function: get_isin_from_identifiers(identifiers=["RCL", "CCL"])
|
|
82
|
+
""").strip()
|
|
61
83
|
args_schema: Type[BaseModel] = ToolArgsWithIdentifiers
|
|
62
84
|
accepted_permissions: set[Permission] | None = {Permission.IDPermission}
|
|
63
85
|
|
|
64
|
-
def _run(self, identifiers: list[str]) ->
|
|
86
|
+
def _run(self, identifiers: list[str]) -> GetCusipOrIsinFromIdentifiersResp:
|
|
65
87
|
"""Sample response:
|
|
66
88
|
|
|
67
89
|
{
|
|
@@ -83,10 +105,9 @@ class GetIsinFromIdentifiers(KfinanceTool):
|
|
|
83
105
|
]
|
|
84
106
|
|
|
85
107
|
isin_responses = process_tasks_in_thread_pool_executor(api_client=api_client, tasks=tasks)
|
|
86
|
-
|
|
108
|
+
return GetCusipOrIsinFromIdentifiersResp(
|
|
87
109
|
results={
|
|
88
110
|
identifier: isin_resp["isin"] for identifier, isin_resp in isin_responses.items()
|
|
89
111
|
},
|
|
90
112
|
errors=list(id_triple_resp.errors.values()),
|
|
91
113
|
)
|
|
92
|
-
return resp_model.model_dump(mode="json")
|
|
@@ -4,6 +4,7 @@ from kfinance.client.kfinance import Client
|
|
|
4
4
|
from kfinance.conftest import SPGI_SECURITY_ID
|
|
5
5
|
from kfinance.domains.cusip_and_isin.cusip_and_isin_tools import (
|
|
6
6
|
GetCusipFromIdentifiers,
|
|
7
|
+
GetCusipOrIsinFromIdentifiersResp,
|
|
7
8
|
GetIsinFromIdentifiers,
|
|
8
9
|
)
|
|
9
10
|
from kfinance.integrations.tool_calling.tool_calling_models import ToolArgsWithIdentifiers
|
|
@@ -18,10 +19,12 @@ class TestGetCusipFromIdentifiers:
|
|
|
18
19
|
"""
|
|
19
20
|
|
|
20
21
|
spgi_cusip = "78409V104"
|
|
21
|
-
expected_response =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
expected_response = GetCusipOrIsinFromIdentifiersResp.model_validate(
|
|
23
|
+
{
|
|
24
|
+
"results": {"SPGI": "78409V104"},
|
|
25
|
+
"errors": ["private_company is a private company without a security_id."],
|
|
26
|
+
}
|
|
27
|
+
)
|
|
25
28
|
requests_mock.get(
|
|
26
29
|
url=f"https://kfinance.kensho.com/api/v1/cusip/{SPGI_SECURITY_ID}",
|
|
27
30
|
json={"cusip": spgi_cusip},
|
|
@@ -43,10 +46,12 @@ class TestGetIsinFromIdentifiers:
|
|
|
43
46
|
|
|
44
47
|
spgi_isin = "US78409V1044"
|
|
45
48
|
|
|
46
|
-
expected_response =
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
expected_response = GetCusipOrIsinFromIdentifiersResp.model_validate(
|
|
50
|
+
{
|
|
51
|
+
"results": {"SPGI": "US78409V1044"},
|
|
52
|
+
"errors": ["private_company is a private company without a security_id."],
|
|
53
|
+
}
|
|
54
|
+
)
|
|
50
55
|
requests_mock.get(
|
|
51
56
|
url=f"https://kfinance.kensho.com/api/v1/isin/{SPGI_SECURITY_ID}",
|
|
52
57
|
json={"isin": spgi_isin},
|
|
@@ -14,6 +14,35 @@ from kfinance.integrations.tool_calling.tool_calling_models import (
|
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
class GetTranscriptFromKeyDevIdArgs(BaseModel):
|
|
18
|
+
"""Tool argument with a key_dev_id."""
|
|
19
|
+
|
|
20
|
+
key_dev_id: int = Field(description="The key_dev_id for the earnings call")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class GetTranscriptFromKeyDevIdResp(BaseModel):
|
|
24
|
+
transcript: str
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class GetTranscriptFromKeyDevId(KfinanceTool):
|
|
28
|
+
name: str = "get_transcript_from_key_dev_id"
|
|
29
|
+
description: str = dedent("""
|
|
30
|
+
Get the raw transcript text for an earnings call by key_dev_id.
|
|
31
|
+
|
|
32
|
+
The key_dev_id is obtained from earnings tools (get_earnings_from_identifiers, get_latest_earnings_from_identifiers, or get_next_earnings_from_identifiers).
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
Query: "Get the transcript for earnings call 12346"
|
|
36
|
+
Function: get_transcript_from_key_dev_id(key_dev_id=12346)
|
|
37
|
+
""").strip()
|
|
38
|
+
args_schema: Type[BaseModel] = GetTranscriptFromKeyDevIdArgs
|
|
39
|
+
accepted_permissions: set[Permission] | None = {Permission.TranscriptsPermission}
|
|
40
|
+
|
|
41
|
+
def _run(self, key_dev_id: int) -> GetTranscriptFromKeyDevIdResp:
|
|
42
|
+
transcript = self.kfinance_client.transcript(key_dev_id)
|
|
43
|
+
return GetTranscriptFromKeyDevIdResp(transcript=transcript.raw)
|
|
44
|
+
|
|
45
|
+
|
|
17
46
|
class GetEarningsFromIdentifiersResp(ToolRespWithErrors):
|
|
18
47
|
results: dict[str, EarningsCallResp]
|
|
19
48
|
|
|
@@ -25,9 +54,20 @@ class GetNextOrLatestEarningsFromIdentifiersResp(ToolRespWithErrors):
|
|
|
25
54
|
class GetEarningsFromIdentifiers(KfinanceTool):
|
|
26
55
|
name: str = "get_earnings_from_identifiers"
|
|
27
56
|
description: str = dedent("""
|
|
28
|
-
Get all earnings for a list of identifiers.
|
|
57
|
+
Get all earnings calls for a list of identifiers.
|
|
58
|
+
|
|
59
|
+
Returns a list of dictionaries with 'name' (str), 'key_dev_id' (int), and 'datetime' (str in ISO 8601 format with UTC timezone) attributes for each identifier.
|
|
60
|
+
|
|
61
|
+
- Use get_latest_earnings_from_identifiers to get only the most recent earnings
|
|
62
|
+
- Use get_next_earnings_from_identifiers to get only the next upcoming earnings
|
|
63
|
+
- To fetch the full transcript, call get_transcript_from_key_dev_id with the key_dev_id
|
|
64
|
+
|
|
65
|
+
Examples:
|
|
66
|
+
Query: "Get all earnings calls for Microsoft"
|
|
67
|
+
Function: get_earnings_from_identifiers(identifiers=["Microsoft"])
|
|
29
68
|
|
|
30
|
-
|
|
69
|
+
Query: "Get earnings for CRM and ORCL"
|
|
70
|
+
Function: get_earnings_from_identifiers(identifiers=["CRM", "ORCL"])
|
|
31
71
|
""").strip()
|
|
32
72
|
args_schema: Type[BaseModel] = ToolArgsWithIdentifiers
|
|
33
73
|
accepted_permissions: set[Permission] | None = {
|
|
@@ -35,7 +75,7 @@ class GetEarningsFromIdentifiers(KfinanceTool):
|
|
|
35
75
|
Permission.TranscriptsPermission,
|
|
36
76
|
}
|
|
37
77
|
|
|
38
|
-
def _run(self, identifiers: list[str]) ->
|
|
78
|
+
def _run(self, identifiers: list[str]) -> GetEarningsFromIdentifiersResp:
|
|
39
79
|
"""Sample response:
|
|
40
80
|
|
|
41
81
|
{
|
|
@@ -52,18 +92,28 @@ class GetEarningsFromIdentifiers(KfinanceTool):
|
|
|
52
92
|
}
|
|
53
93
|
|
|
54
94
|
"""
|
|
55
|
-
|
|
95
|
+
return get_earnings_from_identifiers(
|
|
56
96
|
identifiers=identifiers, kfinance_api_client=self.kfinance_client.kfinance_api_client
|
|
57
97
|
)
|
|
58
|
-
return earnings_responses.model_dump(mode="json")
|
|
59
98
|
|
|
60
99
|
|
|
61
100
|
class GetLatestEarningsFromIdentifiers(KfinanceTool):
|
|
62
101
|
name: str = "get_latest_earnings_from_identifiers"
|
|
63
102
|
description: str = dedent("""
|
|
64
|
-
Get the latest earnings for a list of identifiers.
|
|
103
|
+
Get the latest (most recent) earnings call for a list of identifiers.
|
|
65
104
|
|
|
66
105
|
Returns a dictionary with 'name' (str), 'key_dev_id' (int), and 'datetime' (str in ISO 8601 format with UTC timezone) attributes for each identifier.
|
|
106
|
+
|
|
107
|
+
- Use get_earnings_from_identifiers for all historical earnings
|
|
108
|
+
- Use get_next_earnings_from_identifiers for upcoming earnings
|
|
109
|
+
- To fetch the full transcript, call get_transcript_from_key_dev_id with the key_dev_id
|
|
110
|
+
|
|
111
|
+
Examples:
|
|
112
|
+
Query: "What was Microsoft's latest earnings call?"
|
|
113
|
+
Function: get_latest_earnings_from_identifiers(identifiers=["Microsoft"])
|
|
114
|
+
|
|
115
|
+
Query: "Get latest earnings for JPM and GS"
|
|
116
|
+
Function: get_latest_earnings_from_identifiers(identifiers=["JPM", "GS"])
|
|
67
117
|
""").strip()
|
|
68
118
|
args_schema: Type[BaseModel] = ToolArgsWithIdentifiers
|
|
69
119
|
accepted_permissions: set[Permission] | None = {
|
|
@@ -71,7 +121,7 @@ class GetLatestEarningsFromIdentifiers(KfinanceTool):
|
|
|
71
121
|
Permission.TranscriptsPermission,
|
|
72
122
|
}
|
|
73
123
|
|
|
74
|
-
def _run(self, identifiers: list[str]) ->
|
|
124
|
+
def _run(self, identifiers: list[str]) -> GetNextOrLatestEarningsFromIdentifiersResp:
|
|
75
125
|
"""Sample response:
|
|
76
126
|
|
|
77
127
|
{
|
|
@@ -95,15 +145,26 @@ class GetLatestEarningsFromIdentifiers(KfinanceTool):
|
|
|
95
145
|
output_model.results[identifier] = most_recent_earnings
|
|
96
146
|
else:
|
|
97
147
|
output_model.errors.append(f"No latest earnings available for {identifier}.")
|
|
98
|
-
return output_model
|
|
148
|
+
return output_model
|
|
99
149
|
|
|
100
150
|
|
|
101
151
|
class GetNextEarningsFromIdentifiers(KfinanceTool):
|
|
102
152
|
name: str = "get_next_earnings_from_identifiers"
|
|
103
153
|
description: str = dedent("""
|
|
104
|
-
Get the next earnings for a
|
|
154
|
+
Get the next scheduled earnings call for a list of identifiers.
|
|
155
|
+
|
|
156
|
+
Returns a dictionary with 'name' (str), 'key_dev_id' (int), and 'datetime' (str in ISO 8601 format with UTC timezone) attributes for each identifier.
|
|
105
157
|
|
|
106
|
-
|
|
158
|
+
- Use get_latest_earnings_from_identifiers for the most recent completed earnings
|
|
159
|
+
- Use get_earnings_from_identifiers for all historical earnings
|
|
160
|
+
- To fetch the full transcript (once available), call get_transcript_from_key_dev_id with the key_dev_id
|
|
161
|
+
|
|
162
|
+
Examples:
|
|
163
|
+
Query: "When is Waste Management's next earnings call?"
|
|
164
|
+
Function: get_next_earnings_from_identifiers(identifiers=["Waste Management"])
|
|
165
|
+
|
|
166
|
+
Query: "Get next earnings for FDX and UPS"
|
|
167
|
+
Function: get_next_earnings_from_identifiers(identifiers=["FDX", "UPS"])
|
|
107
168
|
""").strip()
|
|
108
169
|
args_schema: Type[BaseModel] = ToolArgsWithIdentifiers
|
|
109
170
|
accepted_permissions: set[Permission] | None = {
|
|
@@ -111,7 +172,7 @@ class GetNextEarningsFromIdentifiers(KfinanceTool):
|
|
|
111
172
|
Permission.TranscriptsPermission,
|
|
112
173
|
}
|
|
113
174
|
|
|
114
|
-
def _run(self, identifiers: list[str]) ->
|
|
175
|
+
def _run(self, identifiers: list[str]) -> GetNextOrLatestEarningsFromIdentifiersResp:
|
|
115
176
|
"""Sample response:
|
|
116
177
|
|
|
117
178
|
{
|
|
@@ -135,7 +196,7 @@ class GetNextEarningsFromIdentifiers(KfinanceTool):
|
|
|
135
196
|
output_model.results[identifier] = next_earnings
|
|
136
197
|
else:
|
|
137
198
|
output_model.errors.append(f"No next earnings available for {identifier}.")
|
|
138
|
-
return output_model
|
|
199
|
+
return output_model
|
|
139
200
|
|
|
140
201
|
|
|
141
202
|
def get_earnings_from_identifiers(
|
|
@@ -162,20 +223,3 @@ def get_earnings_from_identifiers(
|
|
|
162
223
|
results=earnings_responses, errors=list(id_triple_resp.errors.values())
|
|
163
224
|
)
|
|
164
225
|
return resp_model
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
class GetTranscriptFromKeyDevIdArgs(BaseModel):
|
|
168
|
-
"""Tool argument with a key_dev_id."""
|
|
169
|
-
|
|
170
|
-
key_dev_id: int = Field(description="The key dev ID for the earnings call")
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
class GetTranscriptFromKeyDevId(KfinanceTool):
|
|
174
|
-
name: str = "get_transcript_from_key_dev_id"
|
|
175
|
-
description: str = "Get the raw transcript text for an earnings call by key dev ID."
|
|
176
|
-
args_schema: Type[BaseModel] = GetTranscriptFromKeyDevIdArgs
|
|
177
|
-
accepted_permissions: set[Permission] | None = {Permission.TranscriptsPermission}
|
|
178
|
-
|
|
179
|
-
def _run(self, key_dev_id: int) -> str:
|
|
180
|
-
transcript = self.kfinance_client.transcript(key_dev_id)
|
|
181
|
-
return transcript.raw
|
|
@@ -7,10 +7,13 @@ from kfinance.client.kfinance import Client
|
|
|
7
7
|
from kfinance.conftest import SPGI_COMPANY_ID
|
|
8
8
|
from kfinance.domains.earnings.earning_tools import (
|
|
9
9
|
GetEarningsFromIdentifiers,
|
|
10
|
+
GetEarningsFromIdentifiersResp,
|
|
10
11
|
GetLatestEarningsFromIdentifiers,
|
|
11
12
|
GetNextEarningsFromIdentifiers,
|
|
13
|
+
GetNextOrLatestEarningsFromIdentifiersResp,
|
|
12
14
|
GetTranscriptFromKeyDevId,
|
|
13
15
|
GetTranscriptFromKeyDevIdArgs,
|
|
16
|
+
GetTranscriptFromKeyDevIdResp,
|
|
14
17
|
)
|
|
15
18
|
from kfinance.integrations.tool_calling.tool_calling_models import ToolArgsWithIdentifiers
|
|
16
19
|
|
|
@@ -43,27 +46,29 @@ class TestGetEarnings:
|
|
|
43
46
|
json=self.earnings_response,
|
|
44
47
|
)
|
|
45
48
|
|
|
46
|
-
expected_response =
|
|
47
|
-
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
49
|
+
expected_response = GetEarningsFromIdentifiersResp.model_validate(
|
|
50
|
+
{
|
|
51
|
+
"results": {
|
|
52
|
+
"SPGI": {
|
|
53
|
+
"earnings": [
|
|
54
|
+
{
|
|
55
|
+
"name": "SPGI Q1 2025 Earnings Call",
|
|
56
|
+
"key_dev_id": 12346,
|
|
57
|
+
"datetime": "2025-04-29T12:30:00Z",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "SPGI Q4 2024 Earnings Call",
|
|
61
|
+
"key_dev_id": 12345,
|
|
62
|
+
"datetime": "2025-02-11T13:30:00Z",
|
|
63
|
+
},
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"errors": [
|
|
68
|
+
"No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
|
|
69
|
+
],
|
|
70
|
+
}
|
|
71
|
+
)
|
|
67
72
|
|
|
68
73
|
tool = GetEarningsFromIdentifiers(kfinance_client=mock_client)
|
|
69
74
|
response = tool.run(
|
|
@@ -95,16 +100,18 @@ class TestGetEarnings:
|
|
|
95
100
|
json={"earnings": []},
|
|
96
101
|
)
|
|
97
102
|
|
|
98
|
-
expected_response =
|
|
99
|
-
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
expected_response = GetNextOrLatestEarningsFromIdentifiersResp.model_validate(
|
|
104
|
+
{
|
|
105
|
+
"results": {
|
|
106
|
+
"SPGI": {
|
|
107
|
+
"name": "SPGI Q1 2025 Earnings Call",
|
|
108
|
+
"key_dev_id": 12346,
|
|
109
|
+
"datetime": "2025-04-29T12:30:00Z",
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
"errors": ["No latest earnings available for private_company."],
|
|
113
|
+
}
|
|
114
|
+
)
|
|
108
115
|
|
|
109
116
|
tool = GetLatestEarningsFromIdentifiers(kfinance_client=mock_client)
|
|
110
117
|
response = tool.run(
|
|
@@ -136,16 +143,18 @@ class TestGetEarnings:
|
|
|
136
143
|
json={"earnings": []},
|
|
137
144
|
)
|
|
138
145
|
|
|
139
|
-
expected_response =
|
|
140
|
-
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
expected_response = GetNextOrLatestEarningsFromIdentifiersResp.model_validate(
|
|
147
|
+
{
|
|
148
|
+
"results": {
|
|
149
|
+
"SPGI": {
|
|
150
|
+
"datetime": "2025-04-29T12:30:00Z",
|
|
151
|
+
"key_dev_id": 12346,
|
|
152
|
+
"name": "SPGI Q1 2025 Earnings Call",
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"errors": ["No next earnings available for private_company."],
|
|
156
|
+
}
|
|
157
|
+
)
|
|
149
158
|
|
|
150
159
|
tool = GetNextEarningsFromIdentifiers(kfinance_client=mock_client)
|
|
151
160
|
response = tool.run(
|
|
@@ -181,8 +190,8 @@ class TestGetTranscript:
|
|
|
181
190
|
json=transcript_data,
|
|
182
191
|
)
|
|
183
192
|
|
|
184
|
-
expected_response = (
|
|
185
|
-
"Operator: Good morning, everyone.\n\nCEO: Thank you for joining us today."
|
|
193
|
+
expected_response = GetTranscriptFromKeyDevIdResp(
|
|
194
|
+
transcript="Operator: Good morning, everyone.\n\nCEO: Thank you for joining us today."
|
|
186
195
|
)
|
|
187
196
|
|
|
188
197
|
tool = GetTranscriptFromKeyDevId(kfinance_client=mock_client)
|