feature/intrinio-equity-search: Adds Intrinio to obb.equity.search() (#5863)

* intrinio equity search

* integration tests

* test

---------

Co-authored-by: James Maslek <jmaslek11@gmail.com>
This commit is contained in:
Danglewood
2023-12-06 16:40:05 -08:00
committed by GitHub
parent 17a69d2145
commit 1604c78ee5
7 changed files with 160 additions and 11 deletions

View File

@@ -1,8 +1,8 @@
"""Equity Search Standard Model."""
from typing import List, Set, Union
from typing import Optional
from pydantic import Field, field_validator
from pydantic import Field
from openbb_core.provider.abstract.data import Data
from openbb_core.provider.abstract.query_params import QueryParams
@@ -21,13 +21,7 @@ class EquitySearchQueryParams(QueryParams):
class EquitySearchData(Data):
"""Equity Search Data."""
symbol: str = Field(description=DATA_DESCRIPTIONS.get("symbol", ""))
symbol: Optional[str] = Field(
default=None, description=DATA_DESCRIPTIONS.get("symbol", "")
)
name: str = Field(description="Name of the company.")
@field_validator("symbol", mode="before", check_fields=False)
@classmethod
def upper_symbol(cls, v: Union[str, List[str], Set[str]]):
"""Convert symbol to uppercase."""
if isinstance(v, str):
return v.upper()
return ",".join([symbol.upper() for symbol in list(v)])

View File

@@ -1017,6 +1017,7 @@ def test_equity_fundamental_latest_attributes(params, headers):
[
({"query": "AAPl", "is_symbol": True, "provider": "cboe"}),
({"query": "Apple", "provider": "sec", "use_cache": False, "is_fund": False}),
({"query": "gold", "provider": "intrinio", "active": True, "limit": 100}),
],
)
@pytest.mark.integration

View File

@@ -974,6 +974,7 @@ def test_equity_fundamental_latest_attributes(params, obb):
[
({"query": "AAPL", "is_symbol": True, "provider": "cboe"}),
({"query": "Apple", "provider": "sec", "use_cache": False, "is_fund": False}),
({"query": "gold", "provider": "intrinio", "active": True, "limit": 100}),
],
)
@pytest.mark.integration

View File

@@ -10,6 +10,7 @@ from openbb_intrinio.models.currency_pairs import IntrinioCurrencyPairsFetcher
from openbb_intrinio.models.equity_historical import IntrinioEquityHistoricalFetcher
from openbb_intrinio.models.equity_info import IntrinioEquityInfoFetcher
from openbb_intrinio.models.equity_quote import IntrinioEquityQuoteFetcher
from openbb_intrinio.models.equity_search import IntrinioEquitySearchFetcher
from openbb_intrinio.models.fred_series import IntrinioFredSeriesFetcher
from openbb_intrinio.models.historical_attributes import (
IntrinioHistoricalAttributesFetcher,
@@ -49,6 +50,7 @@ intrinio_provider = Provider(
"EquityHistorical": IntrinioEquityHistoricalFetcher,
"EquityInfo": IntrinioEquityInfoFetcher,
"EquityQuote": IntrinioEquityQuoteFetcher,
"EquitySearch": IntrinioEquitySearchFetcher,
"FredSeries": IntrinioFredSeriesFetcher,
"HistoricalAttributes": IntrinioHistoricalAttributesFetcher,
"HistoricalDividends": IntrinioHistoricalDividendsFetcher,

View File

@@ -0,0 +1,89 @@
"""Intrinio Equity Search Model."""
from typing import Any, Dict, List, Optional
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.standard_models.equity_search import (
EquitySearchData,
EquitySearchQueryParams,
)
from openbb_core.provider.utils.descriptions import (
DATA_DESCRIPTIONS,
QUERY_DESCRIPTIONS,
)
from openbb_core.provider.utils.helpers import get_querystring
from openbb_intrinio.utils.helpers import get_data_one
from pydantic import Field
class IntrinioEquitySearchQueryParams(EquitySearchQueryParams):
"""Intrinio Equity Search Query.
Source: https://docs.intrinio.com/documentation/web_api/search_companies_v2
"""
__alias_dict__ = {
"limit": "page_size",
}
active: Optional[bool] = Field(
default=True,
description="When true, return companies that are actively traded (having stock prices within the past 14 days)."
+ " When false, return companies that are not actively traded or never have been traded.",
)
limit: Optional[int] = Field(
default=10000,
description=QUERY_DESCRIPTIONS.get("limit", ""),
)
class IntrinioEquitySearchData(EquitySearchData):
"""Intrinio Equity Search Data."""
__alias_dict__ = {
"intrinio_id": "id",
"symbol": "ticker",
}
cik: Optional[str] = Field(description=DATA_DESCRIPTIONS.get("CIK", ""))
lei: Optional[str] = Field(
description="The Legal Entity Identifier (LEI) of the company."
)
intrinio_id: str = Field(description="The Intrinio ID of the company.")
class IntrinioEquitySearchFetcher(
Fetcher[
IntrinioEquitySearchQueryParams,
List[IntrinioEquitySearchData],
]
):
"""Transform the query, extract and transform the data from the Intrinio endpoints."""
@staticmethod
def transform_query(params: Dict[str, Any]) -> IntrinioEquitySearchQueryParams:
"""Transform the query."""
return IntrinioEquitySearchQueryParams(**params)
@staticmethod
def extract_data(
query: IntrinioEquitySearchQueryParams, # pylint: disable=unused-argument
credentials: Optional[Dict[str, str]],
**kwargs: Any,
) -> List[Dict]:
"""Return the raw data from the Intrinio endpoint."""
api_key = credentials.get("intrinio_api_key") if credentials else ""
query_str = get_querystring(query.model_dump(by_alias=True), ["is_symbol"])
base_url = "https://api-v2.intrinio.com/companies/search?"
url = f"{base_url}{query_str}&api_key={api_key}"
data = get_data_one(url, **kwargs)
return data
@staticmethod
def transform_data(
query: IntrinioEquitySearchQueryParams, data: Dict, **kwargs: Any
) -> List[IntrinioEquitySearchData]:
"""Transform the data to the standard format."""
return [IntrinioEquitySearchData.model_validate(d) for d in data["companies"]]

View File

@@ -0,0 +1,52 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate, br
Connection:
- keep-alive
method: GET
uri: https://api-v2.intrinio.com/companies/search?active=True&api_key=MOCK_API_KEY&page_size=100&query=gold
response:
body:
string: !!binary |
H4sIAHb8b2UAA4yWW3PiOBCF/wrF8+yWkGxZnjdfQAFsY2wuhq2tKQMujyfEJlwSYGr++4rNZlCL
YnHewOFT6/ic7v7ZXFYvm7Qssl3z618/m8Wq+fXy1bfF+bW/yJtfmvti+Zxtxbd84Lnic5m+ZOKT
bUVR1+k3Lt82nEEUikfrrBBP0EDr20OnN08YHve5Y08MIh4ui+fLQ/Fn6JSZWvPXF+m4c3vS3pzk
47rWOLkeV/zBUINX61XDqbabPz8PKw/rtYRuMZ2YFCvoV1tfAHQw4V7nyg4mV/I9MEUGQ4YC9rNX
dgZgLikUZO8f3G65/C2OrpkEIZ0jHjhPIXqinkmBOOxyGIUH5RkbTMENxrE1vp40jh9eACFsIJMo
3NkPGiQytz/irqRMHz9WRme3kifT43oGlBlFUSKBR0F06xyVrBG9ZZpKyS7N3gA59i0ukePqJa1h
FEPAEYLs08LdWkCOiTV2JPakeKvFxgRpqld6Ln8HcfKTmF/RfnY87D7Y4/gemOg6NRTwibylQyhI
xOeSHvt0W6NmTWSH6Gpwtu4rsF00a8dXdFTssjporDGqxP20Cn60gdRekMiv0SvKw/Gx+RBjwoCQ
vc2RHwF2xOXOFVWndH2TzJu8MF1XBcmPxqYPm1TgWFLVgpc2BmUdVXRDw0Q199GfPYPKff4kG9Av
ymVVQxWMGFZqT7jHpsAnPaGKxO6lYgzUKJwyitTk5JrnUuBueySZ28b5o5I1bJpEsXYeDtfQJBPZ
2ZNit09vxfivxeKp0xl5/YndZa7G4PxhhGDVkC36boAbjGweyh2r7duDa8+6Kw+59EPlIgkNCQW+
iXkgT6C4yEvJk//TWTBuKZXnk0UJtbd494q21ulLtbs3iEbuIDHIjM+StqmbskqtliGypRpUa//A
MFoTT45tlL1ldS5ChY2Ymi7khS7cOKaxnC5evWe7/Qfc26/uRwszTKg6q8vFM1wCOtyBw7pTHcrV
43QxDYny1S7sDUHtHz/6jG36vqvK34XfFQVjis2bSbqlILbeIJBbgleJlrB9rLhmYKq+zrM/9dtA
ccfmcwnupIttrdeJTGYoy8WZBXYFfWnJS8sF+iI6Tpwuv+8a4ffTrlh+ntUede5GAIlhoqq/iRYa
sCXvdOFJjU6RrVc7Wf6mLnoOQqSfdO3ecObYtmtgJQLYUBvFucLTEkbAHXfkCFhu97KQXTqFGA93
NWu1CKZInbhROAQudSNpcokP/2JvLzFHIeFRFGDic6I14TAQa5S6EvvTlQnezZi7XekS47LIHwxI
U6MaUTeotauvQf3WnMviWPNR27Eer35ipSS6GuFeSG1oqJgPZPguLfe1Zq9Y0FTpczzL2qB0zwe7
sHd4Kco66x81CSaK4PmQtxcwxmEf7DuHTfpch65jsVuqsvdDLwXKxP6gA5bistpWdeiEtZjoEn+L
n2bH/bdNmmcf//XrHwAAAP//AwB3pkhmKg4AAA==
headers:
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 06 Dec 2023 04:45:42 GMT
Transfer-Encoding:
- chunked
Vary:
- Origin,Accept-Encoding
status:
code: 200
message: OK
version: 1

View File

@@ -12,6 +12,7 @@ from openbb_intrinio.models.currency_pairs import IntrinioCurrencyPairsFetcher
from openbb_intrinio.models.equity_historical import IntrinioEquityHistoricalFetcher
from openbb_intrinio.models.equity_info import IntrinioEquityInfoFetcher
from openbb_intrinio.models.equity_quote import IntrinioEquityQuoteFetcher
from openbb_intrinio.models.equity_search import IntrinioEquitySearchFetcher
from openbb_intrinio.models.fred_series import IntrinioFredSeriesFetcher
from openbb_intrinio.models.historical_attributes import (
IntrinioHistoricalAttributesFetcher,
@@ -305,3 +306,12 @@ def test_intrinio_share_statistics_fetcher(credentials=test_credentials):
fetcher = IntrinioShareStatisticsFetcher()
result = fetcher.test(params, credentials)
assert result is None
@pytest.mark.record_http
def test_intrinio_equity_search_fetcher(credentials=test_credentials):
params = {"query": "gold", "limit": 100}
fetcher = IntrinioEquitySearchFetcher()
result = fetcher.test(params, credentials)
assert result is None