[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:
Danglewood
2024-08-16 23:12:43 -07:00
committed by GitHub
parent b2ab84fc7c
commit 07d8232f22
8 changed files with 16456 additions and 119 deletions

View File

@@ -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": [

View File

@@ -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"],
}
},
},
)
)

View File

@@ -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."""

View File

@@ -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

View File

@@ -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."""

View File

@@ -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."""

View File

@@ -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."""