Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Add Nasdaq To Equity Screener #6521

Merged
merged 6 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions openbb_platform/extensions/equity/integration/test_equity_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,19 @@ def test_equity_search(params, headers):
"provider": "fmp",
}
),
(
{
"sector": "consumer_staples,consumer_discretionary",
"exchange": "all",
"exsubcategory": "all",
"region": "all",
"country": "all",
"mktcap": "large",
"recommendation": "all",
"limit": None,
"provider": "nasdaq",
}
),
],
)
@pytest.mark.integration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1396,6 +1396,19 @@ def test_equity_search(params, obb):
"provider": "fmp",
}
),
(
{
"sector": "consumer_staples,consumer_discretionary",
"exchange": "all",
"exsubcategory": "all",
"region": "all",
"country": "all",
"mktcap": "large",
"recommendation": "all",
"limit": None,
"provider": "nasdaq",
}
),
],
)
@pytest.mark.integration
Expand Down
6 changes: 2 additions & 4 deletions openbb_platform/extensions/news/integration/test_news_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,8 @@ def headers():
(
{
"provider": "biztoc",
"filter": "tag",
"tag": "federalreserve",
"source": "bloomberg",
"term": "MSFT",
"source": None,
"term": "microsoft",
"start_date": None,
"end_date": None,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,8 @@ def obb(pytestconfig): # pylint: disable=inconsistent-return-statements
(
{
"provider": "biztoc",
"filter": "tag",
"tag": "federalreserve",
"source": "bloomberg",
"term": "MSFT",
"source": None,
"term": "microsoft",
"start_date": None,
"end_date": None,
}
Expand Down
112 changes: 69 additions & 43 deletions openbb_platform/providers/biztoc/openbb_biztoc/models/world_news.py
Original file line number Diff line number Diff line change
@@ -1,59 +1,47 @@
"""Biztoc World News Model."""

import warnings
from datetime import datetime, timedelta
from typing import Any, Dict, List, Literal, Optional
# pylint: disable=unused-argument

from openbb_biztoc.utils.helpers import get_news
from typing import Any, Dict, List, Optional
from warnings import warn

from openbb_core.app.model.abstract.error import OpenBBError
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 make_request
from pandas import to_datetime
from pydantic import Field, field_validator

_warn = warnings.warn


class BiztocWorldNewsQueryParams(WorldNewsQueryParams):
"""Biztoc World News Query."""

filter: Literal["crypto", "hot", "latest", "main", "media", "source", "tag"] = (
Field(default="latest", description="Filter by type of news.")
)
source: str = Field(
description="Filter by a specific publisher. Only valid when filter is set to source.",
default="bloomberg",
)
tag: Optional[str] = Field(
description="Tag, topic, to filter articles by. Only valid when filter is set to tag.",
default=None,
)
term: Optional[str] = Field(
description="Search term to filter articles by. This overrides all other filters.",
default=None,
)
source: Optional[str] = Field(
description="Filter by a specific publisher. Only valid when filter is set to source.",
default=None,
)


class BiztocWorldNewsData(WorldNewsData):
"""Biztoc World News Data."""

__alias_dict__ = {
"date": "created",
"date": "published",
"text": "body",
"site": "domain",
"images": "img",
}

images: Optional[Dict[str, str]] = Field(
description="Images for the article.", alias="images", default=None
)
favicon: Optional[str] = Field(
description="Icon image for the source of the article.", default=None
)
tags: Optional[List[str]] = Field(description="Tags for the article.", default=None)
id: Optional[str] = Field(description="Unique Article ID.", default=None)
score: Optional[float] = Field(
description="Search relevance score for the article.", default=None
)
Expand All @@ -64,6 +52,12 @@ def date_validate(cls, v):
"""Return formatted datetime."""
return to_datetime(v).strftime("%Y-%m-%d %H:%M:%S")

@field_validator("title")
@classmethod
def title_validate(cls, v):
"""Strip empty title text."""
return v.strip() if v else None


class BiztocWorldNewsFetcher(
Fetcher[
Expand All @@ -77,7 +71,7 @@ class BiztocWorldNewsFetcher(
def transform_query(params: Dict[str, Any]) -> BiztocWorldNewsQueryParams:
"""Transform the query."""
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 BiztocWorldNewsQueryParams(**params)

@staticmethod
Expand All @@ -88,29 +82,61 @@ def extract_data(
) -> List[Dict]:
"""Extract the data from the Biztoc endpoint."""
api_key = credentials.get("biztoc_api_key") if credentials else ""

data = get_news(
api_key=api_key, filter_=query.filter, source=query.source, tag=query.tag, term=query.term # type: ignore
)
if query.filter == "hot":
data = [post for sublist in data for post in sublist["posts"]]

times = {"2 Hours Ago": 2, "4 Hours Ago": 4}
# Drop 'body_preview' because it is always nan, empty string, or empty string with space.
for _, item in enumerate(data):
item.pop("body_preview", None) # Removes 'body_preview' if it exists
# Adjust 'created' time if necessary
if item.get("created") in times:
item["created"] = datetime.now() - timedelta(
hours=times[item["created"]]
headers = {
"X-RapidAPI-Key": f"{api_key}",
"X-RapidAPI-Host": "biztoc.p.rapidapi.com",
"Accept": "application/json",
"Accept-Encoding": "gzip",
}
base_url = "https://biztoc.p.rapidapi.com/"
url = ""
response: List = []
if query.term:
query.term = query.term.replace(" ", "%20")
url = base_url + f"search?q={query.term}"
response = make_request(url, headers=headers).json()
if query.source is not None:
sources_response = make_request(
"https://biztoc.p.rapidapi.com/sources",
headers=headers,
).json()
sources = [source["id"] for source in sources_response]
if query.source.lower() not in sources:
raise OpenBBError(
f"{query.source} not a valid source. Valid sources: {sources}"
)
url = base_url + f"news/source/{query.source.lower()}"
response = make_request(url, headers=headers).json()
else:
url1 = base_url + "news/latest"
url2 = base_url + "news/topics"
response = make_request(url1, headers=headers).json()
response2 = make_request(url2, headers=headers).json()
if response2:
for topic in response2:
stories = topic.get("stories", [])
if stories:
response.extend(
{
"text" if k == "body_preview" else k: v
for k, v in story.items()
}
for story in stories
)

return response

return sorted(data, key=lambda x: x["created"], reverse=True)

# pylint: disable=unused-argument
@staticmethod
def transform_data(
query: BiztocWorldNewsQueryParams, data: List[Dict], **kwargs: Any
) -> List[BiztocWorldNewsData]:
"""Transform the data to the standard format."""
return [BiztocWorldNewsData.model_validate(d) for d in data[: query.limit]]
results: List[BiztocWorldNewsData] = []
for item in data:
item.pop("id", None)
item.pop("uid", None)
item.pop("body_preview", None)
item.pop("site", None)
item.pop("domain", None)
results.append(BiztocWorldNewsData.model_validate(item))
return results
144 changes: 0 additions & 144 deletions openbb_platform/providers/biztoc/openbb_biztoc/utils/helpers.py

This file was deleted.

Loading
Loading