From f43ff2a1abb75853a7047c8b53362795f245477e Mon Sep 17 00:00:00 2001 From: Pratyush Shukla Date: Fri, 26 Jan 2024 22:38:42 +0530 Subject: [PATCH] CI listing quick fix (#6002) * BIGGGG LINTING * fixing lints * fixing lints * black * very ruff * no export * fix hedge_view again * lints * platform lints * lints * black * black it @hjoaquim * fix some more linting --------- Co-authored-by: hjoaquim --- .../core/openbb_core/app/model/preferences.py | 3 + .../openbb_core/app/static/package_builder.py | 3 + .../providers/oecd/openbb_oecd/__init__.py | 3 + .../ultima/openbb_ultima/__init__.py | 27 +++++ .../openbb_ultima/models/company_news.py | 95 ++++++++++++++++ .../openbb_ultima/models/sector_news.py | 103 ++++++++++++++++++ .../ultima/openbb_ultima/utils/helpers.py | 26 +++++ 7 files changed, 260 insertions(+) create mode 100644 openbb_platform/providers/ultima/openbb_ultima/__init__.py create mode 100644 openbb_platform/providers/ultima/openbb_ultima/models/company_news.py create mode 100644 openbb_platform/providers/ultima/openbb_ultima/models/sector_news.py create mode 100644 openbb_platform/providers/ultima/openbb_ultima/utils/helpers.py diff --git a/openbb_platform/core/openbb_core/app/model/preferences.py b/openbb_platform/core/openbb_core/app/model/preferences.py index e42ec29b8420..f7f38669928a 100644 --- a/openbb_platform/core/openbb_core/app/model/preferences.py +++ b/openbb_platform/core/openbb_core/app/model/preferences.py @@ -24,11 +24,14 @@ class Preferences(BaseModel): table_style: Literal["dark", "light"] = "dark" request_timeout: PositiveInt = 15 metadata: bool = True +<<<<<<< HEAD <<<<<<< HEAD field_order: bool = ( False # Whether to display the field order by which the data was defined ) ======= +>>>>>>> 13283fbfce (CI listing quick fix (#6002)) +======= >>>>>>> 13283fbfce (CI listing quick fix (#6002)) output_type: Literal["OBBject", "dataframe", "polars", "numpy", "dict", "chart"] = ( Field(default="OBBject", description="Python default output type.") diff --git a/openbb_platform/core/openbb_core/app/static/package_builder.py b/openbb_platform/core/openbb_core/app/static/package_builder.py index a56e3753bfa2..edcac1702c83 100644 --- a/openbb_platform/core/openbb_core/app/static/package_builder.py +++ b/openbb_platform/core/openbb_core/app/static/package_builder.py @@ -402,6 +402,7 @@ def build(path: str, ext_map: Optional[Dict[str, List[str]]] = None) -> str: else None ), <<<<<<< HEAD +<<<<<<< HEAD <<<<<<< HEAD examples=route.openapi_extra.get("examples", None), ======= @@ -409,6 +410,8 @@ def build(path: str, ext_map: Optional[Dict[str, List[str]]] = None) -> str: ======= examples=route.openapi_extra.get("examples", None), >>>>>>> c6eefd26b9 ([Feature] - Support for custom examples in router commands (#5993)) +======= +>>>>>>> 13283fbfce (CI listing quick fix (#6002)) ) # type: ignore else: doc += " /" if path else " /" diff --git a/openbb_platform/providers/oecd/openbb_oecd/__init__.py b/openbb_platform/providers/oecd/openbb_oecd/__init__.py index 252bc92fd3bd..7d4b017dc01f 100644 --- a/openbb_platform/providers/oecd/openbb_oecd/__init__.py +++ b/openbb_platform/providers/oecd/openbb_oecd/__init__.py @@ -2,6 +2,9 @@ """OECD provider module.""" ======= """FRED provider module.""" +<<<<<<< HEAD +>>>>>>> 13283fbfce (CI listing quick fix (#6002)) +======= >>>>>>> 13283fbfce (CI listing quick fix (#6002)) from openbb_core.provider.abstract.provider import Provider diff --git a/openbb_platform/providers/ultima/openbb_ultima/__init__.py b/openbb_platform/providers/ultima/openbb_ultima/__init__.py new file mode 100644 index 000000000000..1d7b285740b5 --- /dev/null +++ b/openbb_platform/providers/ultima/openbb_ultima/__init__.py @@ -0,0 +1,27 @@ +"""Ultima provider module.""" + +import warnings +from typing import Union + +from openbb_core.provider.abstract.provider import Provider + +ultima_provider: Union[Provider, None] = None + +try: + from openbb_ultima.models.company_news import UltimaCompanyNewsFetcher + from openbb_ultima.models.sector_news import UltimaSectorNewsFetcher + + ultima_provider = Provider( + name="ultima", + website="https://www.ultimainsights.ai/openbb", + description="""Ultima harnesses the power of LLMs to deliver news before it hits the frontpage of Bloomberg.""", + credentials=["api_key"], + fetcher_dict={ + "CompanyNews": UltimaCompanyNewsFetcher, + "SectorNews": UltimaSectorNewsFetcher, + }, + ) +except ImportError: + warnings.warn( + "openbb-ultima is not installed. Please install openbb-ultima to use the Ultima provider." + ) diff --git a/openbb_platform/providers/ultima/openbb_ultima/models/company_news.py b/openbb_platform/providers/ultima/openbb_ultima/models/company_news.py new file mode 100644 index 000000000000..8d28d65cdae8 --- /dev/null +++ b/openbb_platform/providers/ultima/openbb_ultima/models/company_news.py @@ -0,0 +1,95 @@ +"""Ultima Company News Model.""" + +from datetime import datetime +from typing import Any, Dict, List, Optional + +from openbb_core.provider.abstract.fetcher import Fetcher +from openbb_core.provider.standard_models.company_news import ( + CompanyNewsData, + CompanyNewsQueryParams, +) +from openbb_ultima.utils.helpers import get_data +from pydantic import Field + + +class UltimaCompanyNewsQueryParams(CompanyNewsQueryParams): + """Ultima Company News Query. + + Source: https://api.ultimainsights.ai/v1/api-docs#/default/get_v1_getOpenBBProInsights__tickers_ + """ + + __alias_dict__ = { + "symbols": "tickers", + } + + +class UltimaCompanyNewsData(CompanyNewsData): + """Ultima Company News Data.""" + + __alias_dict__ = { + "symbols": "ticker", + "date": "publishedDate", + "text": "summary", + "title": "headline", + } + + publisher: str = Field(description="Publisher of the news.") + risk_category: str = Field(description="Risk category of the news.") + + +class UltimaCompanyNewsFetcher( + Fetcher[ + UltimaCompanyNewsQueryParams, + List[UltimaCompanyNewsData], + ] +): + """Transform the query, extract and transform the data from the Ultima endpoints.""" + + @staticmethod + def transform_query(params: Dict[str, Any]) -> UltimaCompanyNewsQueryParams: + """Transform query.""" + return UltimaCompanyNewsQueryParams(**params) + + @staticmethod + def extract_data( + query: UltimaCompanyNewsQueryParams, + credentials: Optional[Dict[str, str]], + **kwargs: Any, + ) -> List[Dict]: + """Extract data from Ultima Insights API.""" + token = credentials.get("ultima_api_key") if credentials else "" + kwargs["auth"] = token + + base_url = "https://api.ultimainsights.ai/v1/getOpenBBProInsights" + + querystring = str(query).split("=")[1].split("'")[1].replace(" ", "") + + data = [] + url = f"{base_url}/{querystring}" + response = get_data(url, **kwargs) + data.extend(response) + + return data + + @staticmethod + def transform_data( + query: UltimaCompanyNewsQueryParams, + data: List[Dict], + **kwargs: Any, + ) -> List[UltimaCompanyNewsData]: + """Transform data.""" + results = [] + for ele in data: + for key in ["8k_filings", "articles", "industry_summary"]: + for item in ele[key]: + # manual assignment required for Pydantic to work + item["symbols"] = ele["ticker"] + item["date"] = datetime.strptime( + item["publishedDate"], "%Y-%m-%d %H:%M:%S" + ) + item["title"] = item["headline"] + item["url"] = item["url"] + item["publisher"] = item["publisher"] + item["risk_category"] = item["riskCategory"] + results.append(UltimaCompanyNewsData.model_validate(item)) + return results diff --git a/openbb_platform/providers/ultima/openbb_ultima/models/sector_news.py b/openbb_platform/providers/ultima/openbb_ultima/models/sector_news.py new file mode 100644 index 000000000000..78c5c23b2480 --- /dev/null +++ b/openbb_platform/providers/ultima/openbb_ultima/models/sector_news.py @@ -0,0 +1,103 @@ +"""Ultima Sector News Model.""" + +from datetime import datetime +from typing import Any, Dict, List, Optional + +from openbb_core.provider.abstract.fetcher import Fetcher +from openbb_core.provider.standard_models.sector_news import ( + SectorNewsData, + SectorNewsQueryParams, +) +from openbb_ultima.utils.helpers import get_data +from pydantic import Field + + +class UltimaSectorNewsQueryParams(SectorNewsQueryParams): + """Ultima Sector News Query. + + Source: https://api.ultimainsights.ai/v1/api-docs#/default/get_v1_getOpenBBProInsights__tickers_ + """ + + __alias_dict__ = { + "symbols": "sectors", + } + + +class UltimaSectorNewsData(SectorNewsData): + """Ultima Sector News Data.""" + + __alias_dict__ = { + "symbols": "ticker", + "date": "publishedDate", + "text": "summary", + "title": "headline", + } + + publisher: str = Field(description="Publisher of the news.") + risk_category: str = Field(description="Risk category of the news.") + + +class UltimaSectorNewsFetcher( + Fetcher[ + UltimaSectorNewsQueryParams, + List[UltimaSectorNewsData], + ] +): + """Transform the query, extract and transform the data from the Ultima endpoints.""" + + @staticmethod + def transform_query(params: Dict[str, Any]) -> UltimaSectorNewsQueryParams: + """Transform query.""" + return UltimaSectorNewsQueryParams(**params) + + @staticmethod + def extract_data( + query: UltimaSectorNewsQueryParams, + credentials: Optional[Dict[str, str]], + **kwargs: Any, + ) -> List[Dict]: + """Extract data from Ultima Insights API.""" + token = credentials.get("ultima_api_key") if credentials else "" + kwargs["auth"] = token + + base_url = "https://api.ultimainsights.ai/v1/getCompaniesForSectors" + pro_base_url = "https://api.ultimainsights.ai/v1/getOpenBBProInsights" + + querystring = str(query).split("=")[1].split("'")[1] + + tickers = [] + url = f"{base_url}/{querystring}" + response = get_data(url, **kwargs) + tickers.extend(response) + + querystring = ",".join(tickers) + + data = [] + url = f"{pro_base_url}/{querystring}" + response = get_data(url, **kwargs) + data.extend(response) + + return data + + @staticmethod + def transform_data( + query: UltimaSectorNewsQueryParams, + data: List[Dict], + **kwargs: Any, + ) -> List[UltimaSectorNewsData]: + """Transform data.""" + results = [] + for ele in data: + for key in ["8k_filings", "articles", "industry_summary"]: + for item in ele[key]: + # manual assignment required for Pydantic to work + item["symbols"] = ele["ticker"] + item["date"] = datetime.strptime( + item["publishedDate"], "%Y-%m-%d %H:%M:%S" + ) + item["title"] = item["headline"] + item["url"] = item["url"] + item["publisher"] = item["publisher"] + item["risk_category"] = item["riskCategory"] + results.append(UltimaSectorNewsData.model_validate(item)) + return results diff --git a/openbb_platform/providers/ultima/openbb_ultima/utils/helpers.py b/openbb_platform/providers/ultima/openbb_ultima/utils/helpers.py new file mode 100644 index 000000000000..1fe2c3dc64e8 --- /dev/null +++ b/openbb_platform/providers/ultima/openbb_ultima/utils/helpers.py @@ -0,0 +1,26 @@ +"""Ultima Helpers.""" + +from typing import Any, Dict + +from openbb_core.provider import helpers + + +def get_data(url: str, **kwargs: Any) -> Dict: + """Do an API request to Ultima and return the data.""" + auth = kwargs.pop("auth", "") + if auth is None or len(auth) == 0: + raise RuntimeError("Ultima API key is required.") + if "Bearer" not in auth: + auth = f"Bearer {auth}" + result = helpers.make_request( + url, + timeout=10, + headers={"accept": "application/json", "Authorization": auth}, + **kwargs, + ) + if result.status_code != 200: + data = result.json() + message = data.get("message") + raise RuntimeError(f"Error in Ultima request -> {message}") + + return result.json()