kensho-kfinance 2.2.4__py3-none-any.whl → 2.2.5__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.
- {kensho_kfinance-2.2.4.dist-info → kensho_kfinance-2.2.5.dist-info}/METADATA +1 -1
- {kensho_kfinance-2.2.4.dist-info → kensho_kfinance-2.2.5.dist-info}/RECORD +12 -11
- kfinance/CHANGELOG.md +3 -0
- kfinance/fetch.py +16 -10
- kfinance/meta_classes.py +26 -8
- kfinance/pydantic_models.py +25 -0
- kfinance/tests/test_fetch.py +62 -1
- kfinance/version.py +2 -2
- {kensho_kfinance-2.2.4.dist-info → kensho_kfinance-2.2.5.dist-info}/WHEEL +0 -0
- {kensho_kfinance-2.2.4.dist-info → kensho_kfinance-2.2.5.dist-info}/licenses/AUTHORS.md +0 -0
- {kensho_kfinance-2.2.4.dist-info → kensho_kfinance-2.2.5.dist-info}/licenses/LICENSE +0 -0
- {kensho_kfinance-2.2.4.dist-info → kensho_kfinance-2.2.5.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kensho-kfinance
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.5
|
|
4
4
|
Summary: Python CLI for kFinance
|
|
5
5
|
Author-email: Luke Brown <luke.brown@kensho.com>, Michelle Keoy <michelle.keoy@kensho.com>, Keith Page <keith.page@kensho.com>, Matthew Rosen <matthew.rosen@kensho.com>, Nick Roshdieh <nick.roshdieh@kensho.com>
|
|
6
6
|
Project-URL: source, https://github.com/kensho-technologies/kfinance
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
kensho_kfinance-2.2.
|
|
2
|
-
kensho_kfinance-2.2.
|
|
3
|
-
kfinance/CHANGELOG.md,sha256=
|
|
1
|
+
kensho_kfinance-2.2.5.dist-info/licenses/AUTHORS.md,sha256=0h9ClbI0pu1oKj1M28ROUsaxrbZg-6ukQGl6X4y9noI,68
|
|
2
|
+
kensho_kfinance-2.2.5.dist-info/licenses/LICENSE,sha256=bsY4blvSgq6o0FMQ3RXa2NCgco--nHCCchLXzxr6kms,83
|
|
3
|
+
kfinance/CHANGELOG.md,sha256=Nlkx-7DFWd9kyeKUdm7pqHW7bFi8ZdruQxCmOo88TpY,1302
|
|
4
4
|
kfinance/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
kfinance/batch_request_handling.py,sha256=p6p_G4_BL06GgeKlh7P1k9CUqOMahWCLEw1NoBwbLvU,5698
|
|
6
6
|
kfinance/constants.py,sha256=UuFzqL253-2tRQfma785K9tfaZGv-o821tO2tVLwc5Q,48813
|
|
7
|
-
kfinance/fetch.py,sha256=
|
|
7
|
+
kfinance/fetch.py,sha256=y4B-xPKrGNDVkicSf904q-M1hXHtNN8AuJ0Y55x_r2s,23464
|
|
8
8
|
kfinance/kfinance.py,sha256=_U69k0Dcwkw1B_lzaUZy8N2-c-v93ZKoUAVVZb6wBUM,52758
|
|
9
|
-
kfinance/meta_classes.py,sha256=
|
|
9
|
+
kfinance/meta_classes.py,sha256=3V0nSXDDoake5o7kXnrqXuqNIiwI75KR4IYxFqSPhTE,20736
|
|
10
10
|
kfinance/prompt.py,sha256=PtVB8c_FcSlVdyGgByAnIFGzuUuBaEjciCqnBJl1hSQ,25133
|
|
11
11
|
kfinance/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
kfinance/pydantic_models.py,sha256=WWLjcxBvVOpW2Wzpq1zKKju4uMlIeH4nKvM2GqLsjEE,597
|
|
12
13
|
kfinance/server_thread.py,sha256=jUnt1YGoYDkqqz1MbCwd44zJs1T_Z2BCgvj75bdtLgA,2574
|
|
13
|
-
kfinance/version.py,sha256=
|
|
14
|
+
kfinance/version.py,sha256=VXEVDzLsFHRu1B1J9TV6pbjt3sWduv6BDj43YpV5xIM,511
|
|
14
15
|
kfinance/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
16
|
kfinance/tests/conftest.py,sha256=voB-w8P_6L3Nel3rdgylXKe5WWaS1q7nCFt1O04uqoY,948
|
|
16
17
|
kfinance/tests/test_batch_requests.py,sha256=uXJF2IcRdyBm5SthwIUHMKtkGZ21MY84pg_k1JeSNOY,11430
|
|
17
18
|
kfinance/tests/test_client.py,sha256=O7icZCSDhlQ9WGhzoXlpiSvbuA-mQNJHBYVsilyP_dE,2209
|
|
18
19
|
kfinance/tests/test_example_notebook.py,sha256=XhDAJp3H5Y6usLAt3k4Ug4W3H6gLyh68nzmoWgOOLn4,6441
|
|
19
|
-
kfinance/tests/test_fetch.py,sha256=
|
|
20
|
+
kfinance/tests/test_fetch.py,sha256=LbE8JLS4OsByfQ_GsGxYwSX5Z4Dgfr-T6bFaZo1k7Oo,16079
|
|
20
21
|
kfinance/tests/test_group_objects.py,sha256=SoMEZmkG4RYdgWOAwxLHHtzIQho92KM01YbQXPUg578,1689
|
|
21
22
|
kfinance/tests/test_objects.py,sha256=CSk3iN-uDt-E6gaOX4jExuYPT8Up-YNC3hafpenadcA,23614
|
|
22
23
|
kfinance/tests/test_tools.py,sha256=ne4XhebhoxDHFl4kRLl10j4K-SXLrxS6jv6Ypt0Gv_E,16846
|
|
@@ -37,7 +38,7 @@ kfinance/tool_calling/get_prices_from_identifier.py,sha256=ViJkwLDvStB7grc8RuoKS
|
|
|
37
38
|
kfinance/tool_calling/get_segments_from_identifier.py,sha256=WIqJ1wWE6Z87VBREGu42nRc6_eJqUbGKcE9elzqBQJE,1867
|
|
38
39
|
kfinance/tool_calling/resolve_identifier.py,sha256=npslr6bBCu0qEDV1-8d24F5OC3nQ1KBMphuMbHVC1AU,626
|
|
39
40
|
kfinance/tool_calling/shared_models.py,sha256=K-NPQyE_7Ew6Cs0zxG1xO2O47gp5uDHdHtWD7wUDZX4,2132
|
|
40
|
-
kensho_kfinance-2.2.
|
|
41
|
-
kensho_kfinance-2.2.
|
|
42
|
-
kensho_kfinance-2.2.
|
|
43
|
-
kensho_kfinance-2.2.
|
|
41
|
+
kensho_kfinance-2.2.5.dist-info/METADATA,sha256=ilytuQ2DVw1h-i2Qo3EV-VKP6_p0OgiuF-Fzdvo5R9M,3436
|
|
42
|
+
kensho_kfinance-2.2.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
43
|
+
kensho_kfinance-2.2.5.dist-info/top_level.txt,sha256=kT_kNwVhfQoOAecY8W7uYah5xaHMoHoAdBIvXh6DaKM,9
|
|
44
|
+
kensho_kfinance-2.2.5.dist-info/RECORD,,
|
kfinance/CHANGELOG.md
CHANGED
kfinance/fetch.py
CHANGED
|
@@ -6,6 +6,7 @@ from typing import Callable, Generator, Optional
|
|
|
6
6
|
from uuid import uuid4
|
|
7
7
|
|
|
8
8
|
import jwt
|
|
9
|
+
from pydantic import ValidationError
|
|
9
10
|
import requests
|
|
10
11
|
|
|
11
12
|
from .constants import (
|
|
@@ -17,6 +18,7 @@ from .constants import (
|
|
|
17
18
|
Permission,
|
|
18
19
|
SegmentType,
|
|
19
20
|
)
|
|
21
|
+
from .pydantic_models import RelationshipResponse, RelationshipResponseNoName
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
# version.py gets autogenerated by setuptools-scm and is not available
|
|
@@ -505,26 +507,30 @@ class KFinanceApiClient:
|
|
|
505
507
|
|
|
506
508
|
def fetch_companies_from_business_relationship(
|
|
507
509
|
self, company_id: int, relationship_type: BusinessRelationshipType
|
|
508
|
-
) ->
|
|
509
|
-
"""Fetches a dictionary of current and previous company IDs associated with a given company ID based on the specified relationship type.
|
|
510
|
-
|
|
511
|
-
The returned dictionary has the following structure:
|
|
512
|
-
{
|
|
513
|
-
"current": List[int],
|
|
514
|
-
"previous": List[int]
|
|
515
|
-
}
|
|
510
|
+
) -> RelationshipResponse | RelationshipResponseNoName:
|
|
511
|
+
"""Fetches a dictionary of current and previous company IDs and names associated with a given company ID based on the specified relationship type.
|
|
516
512
|
|
|
517
513
|
Example: fetch_companies_from_business_relationship(company_id=1234, relationship_type="distributor") returns a dictionary of company 1234's current and previous distributors.
|
|
518
514
|
|
|
515
|
+
As of 2024-05-28, we are changing the response on the backend from
|
|
516
|
+
RelationshipResponseNoName to RelationshipResponse. This function can handle both response
|
|
517
|
+
types.
|
|
518
|
+
|
|
519
519
|
:param company_id: The ID of the company for which associated companies are being fetched.
|
|
520
520
|
:type company_id: int
|
|
521
521
|
:param relationship_type: The type of relationship to filter by. Valid relationship types are defined in the BusinessRelationshipType class.
|
|
522
522
|
:type relationship_type: BusinessRelationshipType
|
|
523
523
|
:return: A dictionary containing lists of current and previous company IDs that have the specified relationship with the given company_id.
|
|
524
|
-
:rtype:
|
|
524
|
+
:rtype: RelationshipResponse | RelationshipResponseNoName
|
|
525
525
|
"""
|
|
526
526
|
url = f"{self.url_base}relationship/{company_id}/{relationship_type}"
|
|
527
|
-
|
|
527
|
+
result = self.fetch(url)
|
|
528
|
+
# Try to parse as the newer RelationshipResponse and fall back to
|
|
529
|
+
# RelationshipResponseNoName if that fails.
|
|
530
|
+
try:
|
|
531
|
+
return RelationshipResponse.model_validate(result)
|
|
532
|
+
except ValidationError:
|
|
533
|
+
return RelationshipResponseNoName.model_validate(result)
|
|
528
534
|
|
|
529
535
|
def fetch_ticker_from_industry_code(
|
|
530
536
|
self,
|
kfinance/meta_classes.py
CHANGED
|
@@ -9,12 +9,12 @@ import pandas as pd
|
|
|
9
9
|
|
|
10
10
|
from .constants import LINE_ITEMS, BusinessRelationshipType, PeriodType, SegmentType
|
|
11
11
|
from .fetch import KFinanceApiClient
|
|
12
|
+
from .pydantic_models import RelationshipResponse
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
if TYPE_CHECKING:
|
|
15
16
|
from .kfinance import BusinessRelationships
|
|
16
17
|
|
|
17
|
-
|
|
18
18
|
logger = logging.getLogger(__name__)
|
|
19
19
|
|
|
20
20
|
|
|
@@ -223,14 +223,32 @@ class CompanyFunctionsMetaClass:
|
|
|
223
223
|
"""
|
|
224
224
|
from .kfinance import BusinessRelationships, Companies
|
|
225
225
|
|
|
226
|
-
|
|
227
|
-
self.company_id,
|
|
228
|
-
relationship_type,
|
|
229
|
-
)
|
|
230
|
-
return BusinessRelationships(
|
|
231
|
-
Companies(self.kfinance_api_client, companies["current"]),
|
|
232
|
-
Companies(self.kfinance_api_client, companies["previous"]),
|
|
226
|
+
relationship_resp = self.kfinance_api_client.fetch_companies_from_business_relationship(
|
|
227
|
+
company_id=self.company_id,
|
|
228
|
+
relationship_type=relationship_type,
|
|
233
229
|
)
|
|
230
|
+
if isinstance(relationship_resp, RelationshipResponse):
|
|
231
|
+
return BusinessRelationships(
|
|
232
|
+
current=Companies(
|
|
233
|
+
kfinance_api_client=self.kfinance_api_client,
|
|
234
|
+
company_ids=[c.company_id for c in relationship_resp.current],
|
|
235
|
+
),
|
|
236
|
+
previous=Companies(
|
|
237
|
+
kfinance_api_client=self.kfinance_api_client,
|
|
238
|
+
company_ids=[c.company_id for c in relationship_resp.previous],
|
|
239
|
+
),
|
|
240
|
+
)
|
|
241
|
+
else:
|
|
242
|
+
return BusinessRelationships(
|
|
243
|
+
current=Companies(
|
|
244
|
+
kfinance_api_client=self.kfinance_api_client,
|
|
245
|
+
company_ids=relationship_resp.current,
|
|
246
|
+
),
|
|
247
|
+
previous=Companies(
|
|
248
|
+
kfinance_api_client=self.kfinance_api_client,
|
|
249
|
+
company_ids=relationship_resp.previous,
|
|
250
|
+
),
|
|
251
|
+
)
|
|
234
252
|
|
|
235
253
|
def market_cap(
|
|
236
254
|
self,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class RelationshipResponseNoName(BaseModel):
|
|
5
|
+
"""A response from the relationship endpoint before adding the company name.
|
|
6
|
+
|
|
7
|
+
Each element in `current` and `previous` is a company_id.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
current: list[int]
|
|
11
|
+
previous: list[int]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CompanyIdAndName(BaseModel):
|
|
15
|
+
"""A company_id and name"""
|
|
16
|
+
|
|
17
|
+
company_id: int
|
|
18
|
+
company_name: str
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class RelationshipResponse(BaseModel):
|
|
22
|
+
"""A response from the relationship endpoint that includes both company_id and name."""
|
|
23
|
+
|
|
24
|
+
current: list[CompanyIdAndName]
|
|
25
|
+
previous: list[CompanyIdAndName]
|
kfinance/tests/test_fetch.py
CHANGED
|
@@ -2,9 +2,17 @@ from unittest import TestCase
|
|
|
2
2
|
from unittest.mock import MagicMock
|
|
3
3
|
|
|
4
4
|
import pytest
|
|
5
|
+
from requests_mock import Mocker
|
|
5
6
|
|
|
6
|
-
from kfinance.constants import Periodicity, PeriodType
|
|
7
|
+
from kfinance.constants import BusinessRelationshipType, Periodicity, PeriodType
|
|
7
8
|
from kfinance.fetch import KFinanceApiClient
|
|
9
|
+
from kfinance.kfinance import Client
|
|
10
|
+
from kfinance.pydantic_models import (
|
|
11
|
+
CompanyIdAndName,
|
|
12
|
+
RelationshipResponse,
|
|
13
|
+
RelationshipResponseNoName,
|
|
14
|
+
)
|
|
15
|
+
from kfinance.tests.conftest import SPGI_COMPANY_ID
|
|
8
16
|
|
|
9
17
|
|
|
10
18
|
def build_mock_api_client() -> KFinanceApiClient:
|
|
@@ -279,3 +287,56 @@ class TestMarketCap:
|
|
|
279
287
|
expected_fetch_url = f"{client.url_base}users/permissions"
|
|
280
288
|
client.fetch_permissions()
|
|
281
289
|
client.fetch.assert_called_with(expected_fetch_url)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
class TestFetchCompaniesFromBusinessRelationship:
|
|
293
|
+
def test_old_response_format(self, requests_mock: Mocker, mock_client: Client) -> None:
|
|
294
|
+
"""
|
|
295
|
+
GIVEN a business relationship request
|
|
296
|
+
WHEN the api returns a response in the old (no name) format
|
|
297
|
+
THEN the response can successfully be parsed.
|
|
298
|
+
"""
|
|
299
|
+
http_resp = {"current": [883103], "previous": [472898, 8182358]}
|
|
300
|
+
expected_result = RelationshipResponseNoName(current=[883103], previous=[472898, 8182358])
|
|
301
|
+
requests_mock.get(
|
|
302
|
+
url=f"{mock_client.kfinance_api_client.url_base}relationship/{SPGI_COMPANY_ID}/{BusinessRelationshipType.supplier}",
|
|
303
|
+
json=http_resp,
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
resp = mock_client.kfinance_api_client.fetch_companies_from_business_relationship(
|
|
307
|
+
company_id=SPGI_COMPANY_ID, relationship_type=BusinessRelationshipType.supplier
|
|
308
|
+
)
|
|
309
|
+
assert resp == expected_result
|
|
310
|
+
|
|
311
|
+
def test_new_response_format(self, requests_mock: Mocker, mock_client: Client) -> None:
|
|
312
|
+
"""
|
|
313
|
+
GIVEN a business relationship request
|
|
314
|
+
WHEN the api returns a response in the new (with name) format
|
|
315
|
+
THEN the response can successfully be parsed.
|
|
316
|
+
"""
|
|
317
|
+
|
|
318
|
+
http_resp = {
|
|
319
|
+
"current": [{"company_name": "foo", "company_id": 883103}],
|
|
320
|
+
"previous": [
|
|
321
|
+
{"company_name": "bar", "company_id": 472898},
|
|
322
|
+
{"company_name": "baz", "company_id": 8182358},
|
|
323
|
+
],
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
expected_result = RelationshipResponse(
|
|
327
|
+
current=[CompanyIdAndName(company_name="foo", company_id=883103)],
|
|
328
|
+
previous=[
|
|
329
|
+
CompanyIdAndName(company_name="bar", company_id=472898),
|
|
330
|
+
CompanyIdAndName(company_name="baz", company_id=8182358),
|
|
331
|
+
],
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
requests_mock.get(
|
|
335
|
+
url=f"{mock_client.kfinance_api_client.url_base}relationship/{SPGI_COMPANY_ID}/{BusinessRelationshipType.supplier}",
|
|
336
|
+
json=http_resp,
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
resp = mock_client.kfinance_api_client.fetch_companies_from_business_relationship(
|
|
340
|
+
company_id=SPGI_COMPANY_ID, relationship_type=BusinessRelationshipType.supplier
|
|
341
|
+
)
|
|
342
|
+
assert resp == expected_result
|
kfinance/version.py
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|