mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-09 02:42:36 +00:00
[BugFix] obb.news.world Add Validators To Providers Where Symbol Is Mandatory (#6625)
* add validators to enforce mandatory symbols in providers where required * linter * fmp 3.9 test cassette --------- Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com>
This commit is contained in:
18
openbb_platform/openbb/assets/reference.json
vendored
18
openbb_platform/openbb/assets/reference.json
vendored
@@ -35717,7 +35717,12 @@
|
||||
"description": "The source of the news article.",
|
||||
"default": null,
|
||||
"optional": true,
|
||||
"choices": null
|
||||
"choices": [
|
||||
"yahoo",
|
||||
"moody",
|
||||
"moody_us_news",
|
||||
"moody_us_press_releases"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "sentiment",
|
||||
@@ -35725,7 +35730,11 @@
|
||||
"description": "Return news only from this source.",
|
||||
"default": null,
|
||||
"optional": true,
|
||||
"choices": null
|
||||
"choices": [
|
||||
"positive",
|
||||
"neutral",
|
||||
"negative"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "language",
|
||||
@@ -35791,7 +35800,10 @@
|
||||
"description": "Sort order of the articles.",
|
||||
"default": "desc",
|
||||
"optional": true,
|
||||
"choices": null
|
||||
"choices": [
|
||||
"asc",
|
||||
"desc"
|
||||
]
|
||||
}
|
||||
],
|
||||
"tiingo": [
|
||||
|
||||
@@ -77,7 +77,7 @@ class ROUTER_news(Container):
|
||||
Number of seconds since the news was published. (provider: benzinga)
|
||||
sort : Literal['id', 'created', 'updated']
|
||||
Key to sort the news by. (provider: benzinga)
|
||||
order : Optional[Literal['asc', 'desc']]
|
||||
order : Literal['asc', 'desc']
|
||||
Order to sort the news by. (provider: benzinga);
|
||||
Sort order of the articles. (provider: polygon)
|
||||
isin : Optional[str]
|
||||
@@ -240,7 +240,30 @@ class ROUTER_news(Container):
|
||||
"polygon": {"multiple_items_allowed": True, "choices": None},
|
||||
"tiingo": {"multiple_items_allowed": True, "choices": None},
|
||||
"yfinance": {"multiple_items_allowed": True, "choices": None},
|
||||
}
|
||||
},
|
||||
"order": {
|
||||
"polygon": {
|
||||
"multiple_items_allowed": False,
|
||||
"choices": ["asc", "desc"],
|
||||
}
|
||||
},
|
||||
"source": {
|
||||
"intrinio": {
|
||||
"multiple_items_allowed": False,
|
||||
"choices": [
|
||||
"yahoo",
|
||||
"moody",
|
||||
"moody_us_news",
|
||||
"moody_us_press_releases",
|
||||
],
|
||||
}
|
||||
},
|
||||
"sentiment": {
|
||||
"intrinio": {
|
||||
"multiple_items_allowed": False,
|
||||
"choices": ["positive", "neutral", "negative"],
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -26,6 +26,14 @@ class FMPCompanyNewsQueryParams(CompanyNewsQueryParams):
|
||||
description="Page number of the results. Use in combination with limit.",
|
||||
)
|
||||
|
||||
@field_validator("symbol", mode="before", check_fields=False)
|
||||
@classmethod
|
||||
def _symbol_mandatory(cls, v):
|
||||
"""Symbol mandatory validator."""
|
||||
if not v:
|
||||
raise ValueError("Required field missing -> symbol")
|
||||
return v
|
||||
|
||||
|
||||
class FMPCompanyNewsData(CompanyNewsData):
|
||||
"""FMP Company News Data."""
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
"""FMP World News Model."""
|
||||
|
||||
import math
|
||||
import warnings
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
from warnings import warn
|
||||
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.standard_models.world_news import (
|
||||
WorldNewsData,
|
||||
WorldNewsQueryParams,
|
||||
)
|
||||
from openbb_core.provider.utils.helpers import amake_requests
|
||||
from openbb_core.provider.utils.errors import EmptyDataError
|
||||
from pydantic import Field, field_validator
|
||||
|
||||
_warn = warnings.warn
|
||||
|
||||
|
||||
class FMPWorldNewsQueryParams(WorldNewsQueryParams):
|
||||
"""FMP World News Query.
|
||||
@@ -31,16 +30,18 @@ class FMPWorldNewsData(WorldNewsData):
|
||||
site: str = Field(description="News source.")
|
||||
|
||||
@field_validator("date", mode="before", check_fields=False)
|
||||
def date_validate(cls, v): # pylint: disable=E0213
|
||||
@classmethod
|
||||
def date_validate(cls, v):
|
||||
"""Return the date as a datetime object."""
|
||||
return datetime.strptime(v, "%Y-%m-%dT%H:%M:%S.%fZ")
|
||||
|
||||
@field_validator("images", mode="before", check_fields=False)
|
||||
def images_validate(cls, v): # pylint: disable=E0213
|
||||
@classmethod
|
||||
def images_validate(cls, v):
|
||||
"""Conform the response to a list."""
|
||||
if isinstance(v, str):
|
||||
return [{"o": v}]
|
||||
return v if isinstance(v, List[Dict]) else None
|
||||
return v if isinstance(v, list) else None
|
||||
|
||||
|
||||
class FMPWorldNewsFetcher(
|
||||
@@ -55,7 +56,7 @@ class FMPWorldNewsFetcher(
|
||||
def transform_query(params: Dict[str, Any]) -> FMPWorldNewsQueryParams:
|
||||
"""Transform the query params."""
|
||||
if params.get("start_date") or params.get("end_date"):
|
||||
_warn("start_date and end_date are not supported for this endpoint.")
|
||||
warn("start_date and end_date are not supported for this endpoint.")
|
||||
return FMPWorldNewsQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
@@ -65,21 +66,35 @@ class FMPWorldNewsFetcher(
|
||||
**kwargs: Any,
|
||||
) -> List[Dict]:
|
||||
"""Return the raw data from the FMP endpoint."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
import math # noqa
|
||||
import asyncio
|
||||
from openbb_core.provider.utils.helpers import amake_request
|
||||
from openbb_fmp.utils.helpers import response_callback
|
||||
|
||||
api_key = credentials.get("fmp_api_key") if credentials else ""
|
||||
pages = math.ceil(query.limit / 20)
|
||||
|
||||
base_url = "https://financialmodelingprep.com/api/v4"
|
||||
results: List = []
|
||||
|
||||
async def get_one(url):
|
||||
"""Get data for one URL."""
|
||||
data = await amake_request(url, response_callback=response_callback)
|
||||
if data:
|
||||
results.extend(data)
|
||||
|
||||
urls = [
|
||||
f"{base_url}/general_news?page={page}&apikey={api_key}"
|
||||
for page in range(pages)
|
||||
]
|
||||
response = await amake_requests(urls, **kwargs)
|
||||
data = sorted(response, key=lambda x: x["publishedDate"], reverse=True)
|
||||
await asyncio.gather(*[get_one(url) for url in urls])
|
||||
|
||||
return data[: query.limit]
|
||||
if results:
|
||||
data = sorted(results, key=lambda x: x["publishedDate"], reverse=True)
|
||||
|
||||
return data[: query.limit]
|
||||
raise EmptyDataError("The request was returned empty.")
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
query: FMPWorldNewsQueryParams, data: List[Dict], **kwargs: Any
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Dict, List, Literal, Optional, Union
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
from warnings import warn
|
||||
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
@@ -31,7 +31,13 @@ class IntrinioCompanyNewsQueryParams(CompanyNewsQueryParams):
|
||||
"limit": "page_size",
|
||||
"source": "specific_source",
|
||||
}
|
||||
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
|
||||
__json_schema_extra__ = {
|
||||
"symbol": {"multiple_items_allowed": True},
|
||||
"source": {
|
||||
"choices": ["yahoo", "moody", "moody_us_news", "moody_us_press_releases"]
|
||||
},
|
||||
"sentiment": {"choices": ["positive", "neutral", "negative"]},
|
||||
}
|
||||
|
||||
source: Optional[
|
||||
Literal["yahoo", "moody", "moody_us_news", "moody_us_press_releases"]
|
||||
@@ -39,7 +45,7 @@ class IntrinioCompanyNewsQueryParams(CompanyNewsQueryParams):
|
||||
default=None,
|
||||
description="The source of the news article.",
|
||||
)
|
||||
sentiment: Union[None, Literal["positive", "neutral", "negative"]] = Field(
|
||||
sentiment: Optional[Literal["positive", "neutral", "negative"]] = Field(
|
||||
default=None,
|
||||
description="Return news only from this source.",
|
||||
)
|
||||
@@ -81,6 +87,14 @@ class IntrinioCompanyNewsQueryParams(CompanyNewsQueryParams):
|
||||
+ " Unsupported for yahoo source. Value is a decimal between 0 and 1.",
|
||||
)
|
||||
|
||||
@field_validator("symbol", mode="before", check_fields=False)
|
||||
@classmethod
|
||||
def _symbol_mandatory(cls, v):
|
||||
"""Symbol mandatory validator."""
|
||||
if not v:
|
||||
raise OpenBBError("Required field missing -> symbol")
|
||||
return v
|
||||
|
||||
|
||||
class IntrinioCompanyNewsData(CompanyNewsData):
|
||||
"""Intrinio Company News Data."""
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
from typing import Any, Dict, List, Literal, Optional
|
||||
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.standard_models.company_news import (
|
||||
CompanyNewsData,
|
||||
@@ -18,17 +19,28 @@ class PolygonCompanyNewsQueryParams(CompanyNewsQueryParams):
|
||||
Source: https://polygon.io/docs/stocks/get_v2_reference_news
|
||||
"""
|
||||
|
||||
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
|
||||
__json_schema_extra__ = {
|
||||
"symbol": {"multiple_items_allowed": True},
|
||||
"order": {"choices": ["asc", "desc"]},
|
||||
}
|
||||
__alias_dict__ = {
|
||||
"symbol": "ticker",
|
||||
"start_date": "published_utc.gte",
|
||||
"end_date": "published_utc.lte",
|
||||
}
|
||||
|
||||
order: Optional[Literal["asc", "desc"]] = Field(
|
||||
order: Literal["asc", "desc"] = Field(
|
||||
default="desc", description="Sort order of the articles."
|
||||
)
|
||||
|
||||
@field_validator("symbol", mode="before", check_fields=False)
|
||||
@classmethod
|
||||
def _symbol_mandatory(cls, v):
|
||||
"""Symbol mandatory validator."""
|
||||
if not v:
|
||||
raise OpenBBError("Required field missing -> symbol")
|
||||
return v
|
||||
|
||||
|
||||
class PolygonPublisher(BaseModel):
|
||||
"""PolygonPublisher Data Model."""
|
||||
|
||||
@@ -22,6 +22,14 @@ class YFinanceCompanyNewsQueryParams(CompanyNewsQueryParams):
|
||||
|
||||
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
|
||||
|
||||
@field_validator("symbol", mode="before", check_fields=False)
|
||||
@classmethod
|
||||
def _symbol_mandatory(cls, v):
|
||||
"""Symbol mandatory validator."""
|
||||
if not v:
|
||||
raise ValueError("Required field missing -> symbol")
|
||||
return v
|
||||
|
||||
|
||||
class YFinanceCompanyNewsData(CompanyNewsData):
|
||||
"""YFinance Company News Data."""
|
||||
|
||||
Reference in New Issue
Block a user