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
|
@@ -18,6 +18,7 @@ from kfinance.domains.companies.company_models import (
|
|
|
18
18
|
CompanyIdAndName,
|
|
19
19
|
CompanyOtherNames,
|
|
20
20
|
)
|
|
21
|
+
from kfinance.domains.segments.segment_models import SegmentType
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
def build_mock_api_client() -> KFinanceApiClient:
|
|
@@ -95,59 +96,107 @@ class TestFetchItem(TestCase):
|
|
|
95
96
|
def test_fetch_statement(self) -> None:
|
|
96
97
|
company_id = 21719
|
|
97
98
|
statement_type = "BS"
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
self.kfinance_api_client.fetch.
|
|
99
|
+
expected_url = f"{self.kfinance_api_client.url_base}statements/"
|
|
100
|
+
expected_request_body = {
|
|
101
|
+
"company_ids": [company_id],
|
|
102
|
+
"statement_type": statement_type,
|
|
103
|
+
}
|
|
104
|
+
# Mock the response to have the expected PostResponse structure
|
|
105
|
+
self.kfinance_api_client.fetch.return_value = {"results": {}, "errors": {}}
|
|
106
|
+
result = self.kfinance_api_client.fetch_statement(
|
|
107
|
+
company_ids=[company_id], statement_type=statement_type
|
|
108
|
+
)
|
|
109
|
+
self.kfinance_api_client.fetch.assert_called_with(
|
|
110
|
+
expected_url, method="POST", request_body=expected_request_body
|
|
111
|
+
)
|
|
112
|
+
# Verify the result is a PostResponse
|
|
113
|
+
assert "results" in result.model_dump()
|
|
114
|
+
# errors field is excluded when empty
|
|
115
|
+
|
|
105
116
|
period_type = PeriodType.quarterly
|
|
106
117
|
start_year = 2024
|
|
107
118
|
end_year = 2024
|
|
108
119
|
start_quarter = 1
|
|
109
120
|
end_quarter = 4
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
expected_request_body = {
|
|
122
|
+
"company_ids": [company_id],
|
|
123
|
+
"statement_type": statement_type,
|
|
124
|
+
"period_type": period_type.value,
|
|
125
|
+
"start_year": start_year,
|
|
126
|
+
"end_year": end_year,
|
|
127
|
+
"start_quarter": start_quarter,
|
|
128
|
+
"end_quarter": end_quarter,
|
|
129
|
+
}
|
|
130
|
+
# Mock the response to have the expected PostResponse structure
|
|
131
|
+
self.kfinance_api_client.fetch.return_value = {"results": {}, "errors": {}}
|
|
132
|
+
result = self.kfinance_api_client.fetch_statement(
|
|
133
|
+
company_ids=[company_id],
|
|
134
|
+
statement_type=statement_type,
|
|
135
|
+
period_type=period_type,
|
|
136
|
+
start_year=start_year,
|
|
137
|
+
end_year=end_year,
|
|
138
|
+
start_quarter=start_quarter,
|
|
139
|
+
end_quarter=end_quarter,
|
|
140
|
+
)
|
|
141
|
+
self.kfinance_api_client.fetch.assert_called_with(
|
|
142
|
+
expected_url, method="POST", request_body=expected_request_body
|
|
143
|
+
)
|
|
144
|
+
# Verify the result is a PostResponse
|
|
145
|
+
assert "results" in result.model_dump()
|
|
146
|
+
# errors field is excluded when empty
|
|
123
147
|
|
|
124
148
|
def test_fetch_line_item(self) -> None:
|
|
125
149
|
company_id = 21719
|
|
126
150
|
line_item = "cash"
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
151
|
+
expected_url = f"{self.kfinance_api_client.url_base}line_item/"
|
|
152
|
+
expected_request_body = {
|
|
153
|
+
"company_ids": [company_id],
|
|
154
|
+
"line_item": line_item,
|
|
155
|
+
}
|
|
156
|
+
# Mock the response to have the expected PostResponse structure
|
|
157
|
+
self.kfinance_api_client.fetch.return_value = {"results": {}, "errors": {}}
|
|
158
|
+
result = self.kfinance_api_client.fetch_line_item(
|
|
159
|
+
company_ids=[company_id], line_item=line_item
|
|
160
|
+
)
|
|
161
|
+
self.kfinance_api_client.fetch.assert_called_with(
|
|
162
|
+
expected_url, method="POST", request_body=expected_request_body
|
|
163
|
+
)
|
|
164
|
+
# Verify the result is a PostResponse
|
|
165
|
+
assert "results" in result.model_dump()
|
|
166
|
+
# errors field is excluded when empty
|
|
167
|
+
|
|
132
168
|
period_type = PeriodType.quarterly
|
|
133
169
|
start_year = 2024
|
|
134
170
|
end_year = 2024
|
|
135
171
|
start_quarter = 1
|
|
136
172
|
end_quarter = 4
|
|
137
|
-
|
|
173
|
+
expected_request_body = {
|
|
174
|
+
"company_ids": [company_id],
|
|
175
|
+
"line_item": line_item,
|
|
176
|
+
"period_type": period_type.value,
|
|
177
|
+
"start_year": start_year,
|
|
178
|
+
"end_year": end_year,
|
|
179
|
+
"start_quarter": start_quarter,
|
|
180
|
+
"end_quarter": end_quarter,
|
|
181
|
+
}
|
|
138
182
|
|
|
139
|
-
#
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
self.kfinance_api_client.fetch.assert_called_with(
|
|
183
|
+
# Mock the response to have the expected PostResponse structure
|
|
184
|
+
self.kfinance_api_client.fetch.return_value = {"results": {}, "errors": {}}
|
|
185
|
+
result = self.kfinance_api_client.fetch_line_item(
|
|
186
|
+
company_ids=[company_id],
|
|
187
|
+
line_item=line_item,
|
|
188
|
+
period_type=period_type,
|
|
189
|
+
start_year=start_year,
|
|
190
|
+
end_year=end_year,
|
|
191
|
+
start_quarter=start_quarter,
|
|
192
|
+
end_quarter=end_quarter,
|
|
193
|
+
)
|
|
194
|
+
self.kfinance_api_client.fetch.assert_called_with(
|
|
195
|
+
expected_url, method="POST", request_body=expected_request_body
|
|
196
|
+
)
|
|
197
|
+
# Verify the result is a PostResponse
|
|
198
|
+
assert "results" in result.model_dump()
|
|
199
|
+
# errors field is excluded when empty
|
|
151
200
|
|
|
152
201
|
def test_fetch_info(self) -> None:
|
|
153
202
|
company_id = 21719
|
|
@@ -275,30 +324,55 @@ class TestFetchItem(TestCase):
|
|
|
275
324
|
|
|
276
325
|
def test_fetch_segments(self) -> None:
|
|
277
326
|
company_id = 21719
|
|
278
|
-
segment_type =
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
327
|
+
segment_type = SegmentType.business
|
|
328
|
+
expected_url = f"{self.kfinance_api_client.url_base}segments/"
|
|
329
|
+
expected_request_body = {
|
|
330
|
+
"company_ids": [company_id],
|
|
331
|
+
"segment_type": segment_type.value,
|
|
332
|
+
}
|
|
333
|
+
# Mock the response to have the expected PostResponse structure
|
|
334
|
+
self.kfinance_api_client.fetch.return_value = {"results": {}, "errors": {}}
|
|
335
|
+
result = self.kfinance_api_client.fetch_segments(
|
|
336
|
+
company_ids=[company_id], segment_type=segment_type
|
|
337
|
+
)
|
|
338
|
+
self.kfinance_api_client.fetch.assert_called_with(
|
|
339
|
+
expected_url, method="POST", request_body=expected_request_body
|
|
340
|
+
)
|
|
341
|
+
# Verify the result is a PostResponse
|
|
342
|
+
assert "results" in result.model_dump()
|
|
343
|
+
# errors field is excluded when empty
|
|
344
|
+
|
|
285
345
|
period_type = PeriodType.quarterly
|
|
286
346
|
start_year = 2023
|
|
287
347
|
end_year = 2023
|
|
288
348
|
start_quarter = 1
|
|
289
349
|
end_quarter = 4
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
self.kfinance_api_client.
|
|
350
|
+
expected_request_body = {
|
|
351
|
+
"company_ids": [company_id],
|
|
352
|
+
"segment_type": segment_type.value,
|
|
353
|
+
"period_type": period_type.value,
|
|
354
|
+
"start_year": start_year,
|
|
355
|
+
"end_year": end_year,
|
|
356
|
+
"start_quarter": start_quarter,
|
|
357
|
+
"end_quarter": end_quarter,
|
|
358
|
+
}
|
|
359
|
+
# Mock the response to have the expected PostResponse structure
|
|
360
|
+
self.kfinance_api_client.fetch.return_value = {"results": {}, "errors": {}}
|
|
361
|
+
result = self.kfinance_api_client.fetch_segments(
|
|
362
|
+
company_ids=[company_id],
|
|
363
|
+
segment_type=segment_type,
|
|
364
|
+
period_type=period_type,
|
|
365
|
+
start_year=start_year,
|
|
366
|
+
end_year=end_year,
|
|
367
|
+
start_quarter=start_quarter,
|
|
368
|
+
end_quarter=end_quarter,
|
|
369
|
+
)
|
|
370
|
+
self.kfinance_api_client.fetch.assert_called_with(
|
|
371
|
+
expected_url, method="POST", request_body=expected_request_body
|
|
372
|
+
)
|
|
373
|
+
# Verify the result is a PostResponse
|
|
374
|
+
assert "results" in result.model_dump()
|
|
375
|
+
# errors field is excluded when empty
|
|
302
376
|
|
|
303
377
|
def test_fetch_mergers_for_company(self) -> None:
|
|
304
378
|
company_id = 21719
|
|
@@ -311,7 +385,9 @@ class TestFetchItem(TestCase):
|
|
|
311
385
|
def test_fetch_merger_info(self) -> None:
|
|
312
386
|
transaction_id = 554979212
|
|
313
387
|
expected_fetch_url = f"{self.kfinance_api_client.url_base}merger/info/{transaction_id}"
|
|
314
|
-
|
|
388
|
+
# Validation error is ok, we only care that the function was called with the correct url
|
|
389
|
+
with pytest.raises(ValidationError):
|
|
390
|
+
self.kfinance_api_client.fetch_merger_info(transaction_id=transaction_id)
|
|
315
391
|
self.kfinance_api_client.fetch.assert_called_with(expected_fetch_url)
|
|
316
392
|
|
|
317
393
|
def test_fetch_advisors_for_company_in_merger(self) -> None:
|