kensho-kfinance 3.2.4__py3-none-any.whl → 3.2.6__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.

Potentially problematic release.


This version of kensho-kfinance might be problematic. Click here for more details.

Files changed (43) hide show
  1. {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-3.2.6.dist-info}/METADATA +1 -1
  2. {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-3.2.6.dist-info}/RECORD +43 -43
  3. kfinance/CHANGELOG.md +6 -0
  4. kfinance/client/fetch.py +7 -5
  5. kfinance/client/kfinance.py +38 -39
  6. kfinance/client/models/date_and_period_models.py +8 -7
  7. kfinance/client/tests/test_fetch.py +3 -1
  8. kfinance/client/tests/test_objects.py +38 -95
  9. kfinance/domains/business_relationships/business_relationship_tools.py +4 -4
  10. kfinance/domains/business_relationships/tests/test_business_relationship_tools.py +18 -16
  11. kfinance/domains/capitalizations/capitalization_models.py +3 -3
  12. kfinance/domains/capitalizations/capitalization_tools.py +7 -5
  13. kfinance/domains/capitalizations/tests/test_capitalization_tools.py +46 -36
  14. kfinance/domains/companies/company_tools.py +8 -12
  15. kfinance/domains/companies/tests/test_company_tools.py +21 -9
  16. kfinance/domains/competitors/competitor_tools.py +2 -3
  17. kfinance/domains/competitors/tests/test_competitor_tools.py +22 -19
  18. kfinance/domains/cusip_and_isin/cusip_and_isin_tools.py +4 -6
  19. kfinance/domains/cusip_and_isin/tests/test_cusip_and_isin_tools.py +13 -8
  20. kfinance/domains/earnings/earning_tools.py +12 -9
  21. kfinance/domains/earnings/tests/test_earnings_tools.py +52 -43
  22. kfinance/domains/line_items/line_item_models.py +121 -0
  23. kfinance/domains/line_items/line_item_tools.py +2 -3
  24. kfinance/domains/line_items/tests/test_line_item_tools.py +20 -23
  25. kfinance/domains/mergers_and_acquisitions/merger_and_acquisition_models.py +46 -2
  26. kfinance/domains/mergers_and_acquisitions/merger_and_acquisition_tools.py +13 -68
  27. kfinance/domains/mergers_and_acquisitions/tests/test_merger_and_acquisition_tools.py +61 -59
  28. kfinance/domains/prices/price_tools.py +4 -7
  29. kfinance/domains/prices/tests/test_price_tools.py +47 -39
  30. kfinance/domains/segments/segment_tools.py +2 -3
  31. kfinance/domains/segments/tests/test_segment_tools.py +16 -11
  32. kfinance/domains/statements/statement_tools.py +2 -3
  33. kfinance/domains/statements/tests/test_statement_tools.py +40 -35
  34. kfinance/integrations/tool_calling/static_tools/get_n_quarters_ago.py +5 -0
  35. kfinance/integrations/tool_calling/static_tools/tests/test_get_lastest.py +13 -10
  36. kfinance/integrations/tool_calling/static_tools/tests/test_get_n_quarters_ago.py +2 -1
  37. kfinance/integrations/tool_calling/tests/test_tool_calling_models.py +8 -2
  38. kfinance/integrations/tool_calling/tool_calling_models.py +11 -5
  39. kfinance/version.py +2 -2
  40. {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-3.2.6.dist-info}/WHEEL +0 -0
  41. {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-3.2.6.dist-info}/licenses/AUTHORS.md +0 -0
  42. {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-3.2.6.dist-info}/licenses/LICENSE +0 -0
  43. {kensho_kfinance-3.2.4.dist-info → kensho_kfinance-3.2.6.dist-info}/top_level.txt +0 -0
@@ -8,13 +8,18 @@ from kfinance.client.tests.test_objects import (
8
8
  ordered,
9
9
  )
10
10
  from kfinance.conftest import SPGI_COMPANY_ID
11
- from kfinance.domains.companies.company_models import COMPANY_ID_PREFIX
11
+ from kfinance.domains.mergers_and_acquisitions.merger_and_acquisition_models import (
12
+ AdvisorResp,
13
+ MergerInfo,
14
+ )
12
15
  from kfinance.domains.mergers_and_acquisitions.merger_and_acquisition_tools import (
13
16
  GetAdvisorsForCompanyInTransactionFromIdentifier,
14
17
  GetAdvisorsForCompanyInTransactionFromIdentifierArgs,
18
+ GetAdvisorsForCompanyInTransactionFromIdentifierResp,
15
19
  GetMergerInfoFromTransactionId,
16
20
  GetMergerInfoFromTransactionIdArgs,
17
21
  GetMergersFromIdentifiers,
22
+ GetMergersFromIdentifiersResp,
18
23
  )
19
24
  from kfinance.integrations.tool_calling.tool_calling_models import ToolArgsWithIdentifiers
20
25
 
@@ -27,12 +32,14 @@ class TestGetMergersFromIdentifiers:
27
32
  THEN we get back the SPGI mergers and an error for the non-existent company"""
28
33
 
29
34
  merger_data = MERGERS_RESP.model_dump(mode="json")
30
- expected_response = {
31
- "results": {"SPGI": merger_data},
32
- "errors": [
33
- "No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
34
- ],
35
- }
35
+ expected_response = GetMergersFromIdentifiersResp.model_validate(
36
+ {
37
+ "results": {"SPGI": merger_data},
38
+ "errors": [
39
+ "No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
40
+ ],
41
+ }
42
+ )
36
43
  requests_mock.get(
37
44
  url=f"https://kfinance.kensho.com/api/v1/mergers/{SPGI_COMPANY_ID}", json=merger_data
38
45
  )
@@ -51,13 +58,21 @@ class TestGetCompaniesAdvisingCompanyInTransactionFromIdentifier:
51
58
  "advisor_company_name": "Kensho Technologies, Inc.",
52
59
  "advisor_type_name": "Professional Mongo Enjoyer",
53
60
  }
54
- api_response = {"advisors": [deepcopy(advisor_data)]}
55
- expected_response = {"results": [deepcopy(advisor_data)]}
56
- expected_response["results"][0]["advisor_company_id"] = f"{COMPANY_ID_PREFIX}251994106"
61
+ expected_response = GetAdvisorsForCompanyInTransactionFromIdentifierResp(
62
+ results=[
63
+ AdvisorResp(
64
+ advisor_company_id=251994106,
65
+ advisor_company_name="Kensho Technologies, Inc.",
66
+ advisor_type_name="Professional Mongo Enjoyer",
67
+ )
68
+ ],
69
+ errors=[],
70
+ )
71
+
57
72
  transaction_id = 554979212
58
73
  requests_mock.get(
59
74
  url=f"https://kfinance.kensho.com/api/v1/merger/info/{transaction_id}/advisors/{SPGI_COMPANY_ID}",
60
- json=api_response,
75
+ json={"advisors": [deepcopy(advisor_data)]},
61
76
  )
62
77
  tool = GetAdvisorsForCompanyInTransactionFromIdentifier(kfinance_client=mock_client)
63
78
  args = GetAdvisorsForCompanyInTransactionFromIdentifierArgs(
@@ -67,14 +82,14 @@ class TestGetCompaniesAdvisingCompanyInTransactionFromIdentifier:
67
82
  assert response == expected_response
68
83
 
69
84
  def test_get_companies_advising_company_in_transaction_from_bad_identifier(
70
- self, requests_mock: Mocker, mock_client: Client
85
+ self, mock_client: Client
71
86
  ):
72
- expected_response = {
73
- "results": [],
74
- "errors": [
87
+ expected_response = GetAdvisorsForCompanyInTransactionFromIdentifierResp(
88
+ results=[],
89
+ errors=[
75
90
  "No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
76
91
  ],
77
- }
92
+ )
78
93
  transaction_id = 554979212
79
94
  tool = GetAdvisorsForCompanyInTransactionFromIdentifier(kfinance_client=mock_client)
80
95
  args = GetAdvisorsForCompanyInTransactionFromIdentifierArgs(
@@ -86,30 +101,11 @@ class TestGetCompaniesAdvisingCompanyInTransactionFromIdentifier:
86
101
 
87
102
  class TestGetMergerInfoFromTransactionId:
88
103
  def test_get_merger_info_from_transaction_id(self, requests_mock: Mocker, mock_client: Client):
89
- response_base = {
90
- "timeline": [
91
- {"status": "Announced", "date": "2000-09-12"},
92
- {"status": "Closed", "date": "2000-09-12"},
93
- ],
94
- "participants": {},
95
- "consideration": {
96
- "currency_name": "US Dollar",
97
- "current_calculated_gross_total_transaction_value": "51609375.000000",
98
- "current_calculated_implied_equity_value": "51609375.000000",
99
- "current_calculated_implied_enterprise_value": "51609375.000000",
100
- "details": [
101
- {
102
- "scenario": "Stock Lump Sum",
103
- "subtype": "Common Equity",
104
- "cash_or_cash_equivalent_per_target_share_unit": None,
105
- "number_of_target_shares_sought": "1000000.000000",
106
- "current_calculated_gross_value_of_consideration": "51609375.000000",
107
- }
108
- ],
109
- },
110
- }
111
-
112
- participants_api_response = {
104
+ timeline_resp = [
105
+ {"status": "Announced", "date": "2000-09-12"},
106
+ {"status": "Closed", "date": "2000-09-12"},
107
+ ]
108
+ participants_resp = {
113
109
  "target": {"company_id": 31696, "company_name": "MongoMusic, Inc."},
114
110
  "buyers": [{"company_id": 21835, "company_name": "Microsoft Corporation"}],
115
111
  "sellers": [
@@ -117,33 +113,39 @@ class TestGetMergerInfoFromTransactionId:
117
113
  {"company_id": 20087, "company_name": "Draper Richards, L.P."},
118
114
  ],
119
115
  }
120
- api_response = deepcopy(response_base)
121
- api_response["participants"] = participants_api_response
122
116
 
123
- # Returned company IDs should be prefixed
124
- expected_participants_tool_response = {
125
- "target": {
126
- "company_id": f"{COMPANY_ID_PREFIX}31696",
127
- "company_name": "MongoMusic, Inc.",
128
- },
129
- "buyers": [
130
- {"company_id": f"{COMPANY_ID_PREFIX}21835", "company_name": "Microsoft Corporation"}
131
- ],
132
- "sellers": [
133
- {"company_id": f"{COMPANY_ID_PREFIX}18805", "company_name": "Angel Investors L.P."},
117
+ consideration_resp = {
118
+ "currency_name": "US Dollar",
119
+ "current_calculated_gross_total_transaction_value": "51609375.000000",
120
+ "current_calculated_implied_equity_value": "51609375.000000",
121
+ "current_calculated_implied_enterprise_value": "51609375.000000",
122
+ "details": [
134
123
  {
135
- "company_id": f"{COMPANY_ID_PREFIX}20087",
136
- "company_name": "Draper Richards, L.P.",
137
- },
124
+ "scenario": "Stock Lump Sum",
125
+ "subtype": "Common Equity",
126
+ "cash_or_cash_equivalent_per_target_share_unit": None,
127
+ "number_of_target_shares_sought": "1000000.000000",
128
+ "current_calculated_gross_value_of_consideration": "51609375.000000",
129
+ }
138
130
  ],
139
131
  }
140
- expected_response = deepcopy(response_base)
141
- expected_response["participants"] = expected_participants_tool_response
132
+
133
+ expected_response = MergerInfo.model_validate(
134
+ {
135
+ "timeline": timeline_resp,
136
+ "participants": participants_resp,
137
+ "consideration": consideration_resp,
138
+ }
139
+ )
142
140
 
143
141
  transaction_id = 517414
144
142
  requests_mock.get(
145
143
  url=f"https://kfinance.kensho.com/api/v1/merger/info/{transaction_id}",
146
- json=api_response,
144
+ json={
145
+ "timeline": timeline_resp,
146
+ "participants": participants_resp,
147
+ "consideration": consideration_resp,
148
+ },
147
149
  )
148
150
  tool = GetMergerInfoFromTransactionId(kfinance_client=mock_client)
149
151
  args = GetMergerInfoFromTransactionIdArgs(transaction_id=transaction_id)
@@ -60,7 +60,7 @@ class GetPricesFromIdentifiers(KfinanceTool):
60
60
  end_date: date | None = None,
61
61
  periodicity: Periodicity = Periodicity.day,
62
62
  adjusted: bool = True,
63
- ) -> dict:
63
+ ) -> GetPricesFromIdentifiersResp:
64
64
  """Sample Response:
65
65
 
66
66
  {
@@ -116,10 +116,9 @@ class GetPricesFromIdentifiers(KfinanceTool):
116
116
  for price_response in price_responses.values():
117
117
  price_response.prices = price_response.prices[-1:]
118
118
 
119
- output_model = GetPricesFromIdentifiersResp(
119
+ return GetPricesFromIdentifiersResp(
120
120
  results=price_responses, errors=list(id_triple_resp.errors.values())
121
121
  )
122
- return output_model.model_dump(mode="json")
123
122
 
124
123
 
125
124
  class GetHistoryMetadataFromIdentifiersResp(ToolRespWithErrors):
@@ -136,7 +135,7 @@ class GetHistoryMetadataFromIdentifiers(KfinanceTool):
136
135
  args_schema: Type[BaseModel] = ToolArgsWithIdentifiers
137
136
  accepted_permissions: set[Permission] | None = None
138
137
 
139
- def _run(self, identifiers: list[str]) -> dict:
138
+ def _run(self, identifiers: list[str]) -> GetHistoryMetadataFromIdentifiersResp:
140
139
  """Sample response:
141
140
 
142
141
  {
@@ -169,8 +168,6 @@ class GetHistoryMetadataFromIdentifiers(KfinanceTool):
169
168
  history_metadata_responses: dict[str, HistoryMetadataResp] = (
170
169
  process_tasks_in_thread_pool_executor(api_client=api_client, tasks=tasks)
171
170
  )
172
- output_model = GetHistoryMetadataFromIdentifiersResp(
171
+ return GetHistoryMetadataFromIdentifiersResp(
173
172
  results=history_metadata_responses, errors=list(id_triple_resp.errors.values())
174
173
  )
175
-
176
- return output_model.model_dump(mode="json")
@@ -5,8 +5,10 @@ from kfinance.conftest import SPGI_TRADING_ITEM_ID
5
5
  from kfinance.domains.companies.company_models import COMPANY_ID_PREFIX
6
6
  from kfinance.domains.prices.price_tools import (
7
7
  GetHistoryMetadataFromIdentifiers,
8
+ GetHistoryMetadataFromIdentifiersResp,
8
9
  GetPricesFromIdentifiers,
9
10
  GetPricesFromIdentifiersArgs,
11
+ GetPricesFromIdentifiersResp,
10
12
  )
11
13
  from kfinance.integrations.tool_calling.tool_calling_models import ToolArgsWithIdentifiers
12
14
 
@@ -27,12 +29,14 @@ class TestGetHistoryMetadataFromIdentifiers:
27
29
  "instrument_type": "Equity",
28
30
  "symbol": "SPGI",
29
31
  }
30
- expected_resp = {
31
- "results": {"SPGI": metadata_resp},
32
- "errors": [
33
- "No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
34
- ],
35
- }
32
+ expected_resp = GetHistoryMetadataFromIdentifiersResp.model_validate(
33
+ {
34
+ "results": {"SPGI": metadata_resp},
35
+ "errors": [
36
+ "No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
37
+ ],
38
+ }
39
+ )
36
40
 
37
41
  requests_mock.get(
38
42
  url=f"https://kfinance.kensho.com/api/v1/pricing/{SPGI_TRADING_ITEM_ID}/metadata",
@@ -80,33 +84,35 @@ class TestGetPricesFromIdentifiers:
80
84
  url=f"https://kfinance.kensho.com/api/v1/pricing/{SPGI_TRADING_ITEM_ID}/none/none/day/adjusted",
81
85
  json=self.prices_resp,
82
86
  )
83
- expected_response = {
84
- "results": {
85
- "SPGI": {
86
- "prices": [
87
- {
88
- "date": "2024-04-11",
89
- "open": {"value": "424.26", "unit": "USD"},
90
- "high": {"value": "425.99", "unit": "USD"},
91
- "low": {"value": "422.04", "unit": "USD"},
92
- "close": {"value": "422.92", "unit": "USD"},
93
- "volume": {"value": "1129158", "unit": "Shares"},
94
- },
95
- {
96
- "date": "2024-04-12",
97
- "open": {"value": "419.23", "unit": "USD"},
98
- "high": {"value": "421.94", "unit": "USD"},
99
- "low": {"value": "416.45", "unit": "USD"},
100
- "close": {"value": "417.81", "unit": "USD"},
101
- "volume": {"value": "1182229", "unit": "Shares"},
102
- },
103
- ]
104
- }
105
- },
106
- "errors": [
107
- "No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
108
- ],
109
- }
87
+ expected_response = GetPricesFromIdentifiersResp.model_validate(
88
+ {
89
+ "results": {
90
+ "SPGI": {
91
+ "prices": [
92
+ {
93
+ "date": "2024-04-11",
94
+ "open": {"value": "424.26", "unit": "USD"},
95
+ "high": {"value": "425.99", "unit": "USD"},
96
+ "low": {"value": "422.04", "unit": "USD"},
97
+ "close": {"value": "422.92", "unit": "USD"},
98
+ "volume": {"value": "1129158", "unit": "Shares"},
99
+ },
100
+ {
101
+ "date": "2024-04-12",
102
+ "open": {"value": "419.23", "unit": "USD"},
103
+ "high": {"value": "421.94", "unit": "USD"},
104
+ "low": {"value": "416.45", "unit": "USD"},
105
+ "close": {"value": "417.81", "unit": "USD"},
106
+ "volume": {"value": "1182229", "unit": "Shares"},
107
+ },
108
+ ]
109
+ }
110
+ },
111
+ "errors": [
112
+ "No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
113
+ ],
114
+ }
115
+ )
110
116
 
111
117
  tool = GetPricesFromIdentifiers(kfinance_client=mock_client)
112
118
  response = tool.run(
@@ -142,12 +148,14 @@ class TestGetPricesFromIdentifiers:
142
148
  }
143
149
  ]
144
150
  }
145
- expected_response = {
146
- "results": {
147
- "C_1": expected_single_company_response,
148
- "C_2": expected_single_company_response,
149
- },
150
- }
151
+ expected_response = GetPricesFromIdentifiersResp.model_validate(
152
+ {
153
+ "results": {
154
+ "C_1": expected_single_company_response,
155
+ "C_2": expected_single_company_response,
156
+ },
157
+ }
158
+ )
151
159
  tool = GetPricesFromIdentifiers(kfinance_client=mock_client)
152
160
  response = tool.run(
153
161
  GetPricesFromIdentifiersArgs(
@@ -43,7 +43,7 @@ class GetSegmentsFromIdentifiers(KfinanceTool):
43
43
  end_year: int | None = None,
44
44
  start_quarter: Literal[1, 2, 3, 4] | None = None,
45
45
  end_quarter: Literal[1, 2, 3, 4] | None = None,
46
- ) -> dict:
46
+ ) -> GetSegmentsFromIdentifiersResp:
47
47
  """Sample Response:
48
48
 
49
49
  {
@@ -102,7 +102,6 @@ class GetSegmentsFromIdentifiers(KfinanceTool):
102
102
  most_recent_year_data = segments_response.segments[most_recent_year]
103
103
  segments_response.segments = {most_recent_year: most_recent_year_data}
104
104
 
105
- output_model = GetSegmentsFromIdentifiersResp(
105
+ return GetSegmentsFromIdentifiersResp(
106
106
  results=segments_responses, errors=list(id_triple_resp.errors.values())
107
107
  )
108
- return output_model.model_dump(mode="json")
@@ -7,6 +7,7 @@ from kfinance.domains.segments.segment_models import SegmentType
7
7
  from kfinance.domains.segments.segment_tools import (
8
8
  GetSegmentsFromIdentifiers,
9
9
  GetSegmentsFromIdentifiersArgs,
10
+ GetSegmentsFromIdentifiersResp,
10
11
  )
11
12
 
12
13
 
@@ -43,12 +44,14 @@ class TestGetSegmentsFromIdentifier:
43
44
  json=self.segments_response,
44
45
  )
45
46
 
46
- expected_response = {
47
- "results": {"SPGI": self.segments_response},
48
- "errors": [
49
- "No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
50
- ],
51
- }
47
+ expected_response = GetSegmentsFromIdentifiersResp.model_validate(
48
+ {
49
+ "results": {"SPGI": self.segments_response},
50
+ "errors": [
51
+ "No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
52
+ ],
53
+ }
54
+ )
52
55
 
53
56
  tool = GetSegmentsFromIdentifiers(kfinance_client=mock_client)
54
57
  args = GetSegmentsFromIdentifiersArgs(
@@ -65,12 +68,14 @@ class TestGetSegmentsFromIdentifier:
65
68
  """
66
69
 
67
70
  company_ids = [1, 2]
68
- expected_response = {
69
- "results": {
70
- "C_1": {"segments": {"2021": self.segments_response["segments"]["2021"]}},
71
- "C_2": {"segments": {"2021": self.segments_response["segments"]["2021"]}},
71
+ expected_response = GetSegmentsFromIdentifiersResp.model_validate(
72
+ {
73
+ "results": {
74
+ "C_1": {"segments": {"2021": self.segments_response["segments"]["2021"]}},
75
+ "C_2": {"segments": {"2021": self.segments_response["segments"]["2021"]}},
76
+ }
72
77
  }
73
- }
78
+ )
74
79
 
75
80
  for company_id in company_ids:
76
81
  requests_mock.get(
@@ -55,7 +55,7 @@ class GetFinancialStatementFromIdentifiers(KfinanceTool):
55
55
  end_year: int | None = None,
56
56
  start_quarter: Literal[1, 2, 3, 4] | None = None,
57
57
  end_quarter: Literal[1, 2, 3, 4] | None = None,
58
- ) -> dict:
58
+ ) -> GetFinancialStatementFromIdentifiersResp:
59
59
  """Sample response:
60
60
 
61
61
  {
@@ -109,7 +109,6 @@ class GetFinancialStatementFromIdentifiers(KfinanceTool):
109
109
  most_recent_year_data = statement_response.statements[most_recent_year]
110
110
  statement_response.statements = {most_recent_year: most_recent_year_data}
111
111
 
112
- output_model = GetFinancialStatementFromIdentifiersResp(
112
+ return GetFinancialStatementFromIdentifiersResp(
113
113
  results=statement_responses, errors=list(id_triple_resp.errors.values())
114
114
  )
115
- return output_model.model_dump(mode="json")
@@ -7,6 +7,7 @@ from kfinance.domains.statements.statement_models import StatementType
7
7
  from kfinance.domains.statements.statement_tools import (
8
8
  GetFinancialStatementFromIdentifiers,
9
9
  GetFinancialStatementFromIdentifiersArgs,
10
+ GetFinancialStatementFromIdentifiersResp,
10
11
  )
11
12
 
12
13
 
@@ -31,25 +32,27 @@ class TestGetFinancialStatementFromIdentifiers:
31
32
  url=f"https://kfinance.kensho.com/api/v1/statements/{SPGI_COMPANY_ID}/income_statement/none/none/none/none/none",
32
33
  json=self.statement_resp,
33
34
  )
34
- expected_response = {
35
- "results": {
36
- "SPGI": {
37
- "statements": {
38
- "2020": {
39
- "Revenues": "7442000000.000000",
40
- "Total Revenues": "7442000000.000000",
41
- },
42
- "2021": {
43
- "Revenues": "8243000000.000000",
44
- "Total Revenues": "8243000000.000000",
45
- },
35
+ expected_response = GetFinancialStatementFromIdentifiersResp.model_validate(
36
+ {
37
+ "results": {
38
+ "SPGI": {
39
+ "statements": {
40
+ "2020": {
41
+ "Revenues": "7442000000.000000",
42
+ "Total Revenues": "7442000000.000000",
43
+ },
44
+ "2021": {
45
+ "Revenues": "8243000000.000000",
46
+ "Total Revenues": "8243000000.000000",
47
+ },
48
+ }
46
49
  }
47
- }
48
- },
49
- "errors": [
50
- "No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
51
- ],
52
- }
50
+ },
51
+ "errors": [
52
+ "No identification triple found for the provided identifier: NON-EXISTENT of type: ticker"
53
+ ],
54
+ }
55
+ )
53
56
 
54
57
  tool = GetFinancialStatementFromIdentifiers(kfinance_client=mock_client)
55
58
  args = GetFinancialStatementFromIdentifiersArgs(
@@ -66,26 +69,28 @@ class TestGetFinancialStatementFromIdentifiers:
66
69
  """
67
70
 
68
71
  company_ids = [1, 2]
69
- expected_response = {
70
- "results": {
71
- "C_1": {
72
- "statements": {
73
- "2021": {
74
- "Revenues": "8243000000.000000",
75
- "Total Revenues": "8243000000.000000",
72
+ expected_response = GetFinancialStatementFromIdentifiersResp.model_validate(
73
+ {
74
+ "results": {
75
+ "C_1": {
76
+ "statements": {
77
+ "2021": {
78
+ "Revenues": "8243000000.000000",
79
+ "Total Revenues": "8243000000.000000",
80
+ }
76
81
  }
77
- }
78
- },
79
- "C_2": {
80
- "statements": {
81
- "2021": {
82
- "Revenues": "8243000000.000000",
83
- "Total Revenues": "8243000000.000000",
82
+ },
83
+ "C_2": {
84
+ "statements": {
85
+ "2021": {
86
+ "Revenues": "8243000000.000000",
87
+ "Total Revenues": "8243000000.000000",
88
+ }
84
89
  }
85
- }
86
- },
90
+ },
91
+ }
87
92
  }
88
- }
93
+ )
89
94
 
90
95
  for company_id in company_ids:
91
96
  requests_mock.get(
@@ -11,6 +11,11 @@ class GetNQuartersAgoArgs(BaseModel):
11
11
  n: int = Field(description="Number of quarters before the current quarter")
12
12
 
13
13
 
14
+ class GetNQuartersAgoResp(BaseModel):
15
+ year: int
16
+ quarter: int
17
+
18
+
14
19
  class GetNQuartersAgo(KfinanceTool):
15
20
  name: str = "get_n_quarters_ago"
16
21
  description: str = (
@@ -3,6 +3,7 @@ from datetime import datetime
3
3
  import time_machine
4
4
 
5
5
  from kfinance.client.kfinance import Client
6
+ from kfinance.client.models.date_and_period_models import LatestPeriods
6
7
  from kfinance.integrations.tool_calling.static_tools.get_latest import GetLatest, GetLatestArgs
7
8
 
8
9
 
@@ -15,16 +16,18 @@ class TestGetLatest:
15
16
  THEN we get back latest info
16
17
  """
17
18
 
18
- expected_resp = {
19
- "annual": {"latest_year": 2024},
20
- "now": {
21
- "current_date": "2025-01-01",
22
- "current_month": 1,
23
- "current_quarter": 1,
24
- "current_year": 2025,
25
- },
26
- "quarterly": {"latest_quarter": 4, "latest_year": 2024},
27
- }
19
+ expected_resp = LatestPeriods.model_validate(
20
+ {
21
+ "annual": {"latest_year": 2024},
22
+ "now": {
23
+ "current_date": "2025-01-01",
24
+ "current_month": 1,
25
+ "current_quarter": 1,
26
+ "current_year": 2025,
27
+ },
28
+ "quarterly": {"latest_quarter": 4, "latest_year": 2024},
29
+ }
30
+ )
28
31
  tool = GetLatest(kfinance_client=mock_client)
29
32
  resp = tool.run(GetLatestArgs().model_dump(mode="json"))
30
33
  assert resp == expected_resp
@@ -3,6 +3,7 @@ from datetime import datetime
3
3
  import time_machine
4
4
 
5
5
  from kfinance.client.kfinance import Client
6
+ from kfinance.client.models.date_and_period_models import YearAndQuarter
6
7
  from kfinance.integrations.tool_calling.static_tools.get_n_quarters_ago import (
7
8
  GetNQuartersAgo,
8
9
  GetNQuartersAgoArgs,
@@ -18,7 +19,7 @@ class TestGetNQuartersAgo:
18
19
  THEN we get back 3 quarters ago
19
20
  """
20
21
 
21
- expected_resp = {"quarter": 2, "year": 2024}
22
+ expected_resp = YearAndQuarter(year=2024, quarter=2)
22
23
  tool = GetNQuartersAgo(kfinance_client=mock_client)
23
24
  resp = tool.run(GetNQuartersAgoArgs(n=3).model_dump(mode="json"))
24
25
  assert resp == expected_resp
@@ -7,7 +7,10 @@ from requests_mock import Mocker
7
7
 
8
8
  from kfinance.client.kfinance import Client
9
9
  from kfinance.conftest import SPGI_COMPANY_ID
10
- from kfinance.domains.companies.company_tools import GetInfoFromIdentifiers
10
+ from kfinance.domains.companies.company_tools import (
11
+ GetInfoFromIdentifiers,
12
+ GetInfoFromIdentifiersResp,
13
+ )
11
14
  from kfinance.integrations.tool_calling.tool_calling_models import ValidQuarter
12
15
 
13
16
 
@@ -27,7 +30,10 @@ class TestGetEndpointsFromToolCallsWithGrounding:
27
30
  "https://kfinance.kensho.com/api/v1/ids",
28
31
  "https://kfinance.kensho.com/api/v1/info/21719",
29
32
  ]
30
- expected_resp = {"data": {"results": {"SPGI": resp_data}}, "endpoint_urls": resp_endpoint}
33
+ expected_resp = {
34
+ "data": GetInfoFromIdentifiersResp.model_validate({"results": {"SPGI": resp_data}}),
35
+ "endpoint_urls": resp_endpoint,
36
+ }
31
37
 
32
38
  requests_mock.get(
33
39
  url=f"https://kfinance.kensho.com/api/v1/info/{SPGI_COMPANY_ID}",