From fc97948a55f73c377413ec91c1e7f83c034449e1 Mon Sep 17 00:00:00 2001 From: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> Date: Tue, 31 Oct 2023 15:07:29 +0100 Subject: [PATCH] Feature/disc router (#5616) * Add disc router and WSJ provider * Lint * Lint * Move endpoints under ETF router * Update etf_performance.py --- .../etf/integration/test_etf_api.py | 45 +++++++++++++++++++ .../etf/integration/test_etf_python.py | 42 +++++++++++++++++ .../openbb_etf}/disc/__init__.py | 0 .../openbb_etf}/disc/disc_router.py | 13 +++--- .../extensions/etf/openbb_etf/etf_router.py | 3 ++ .../stocks/openbb_stocks/stocks_router.py | 2 - ...sset_performance.py => etf_performance.py} | 10 ++--- .../openbb_fmp/models/price_performance.py | 5 ++- .../providers/wsj/openbb_wsj/__init__.py | 6 +-- .../providers/wsj/openbb_wsj/models/active.py | 12 ++--- .../wsj/openbb_wsj/models/gainers.py | 16 +++---- .../providers/wsj/openbb_wsj/models/losers.py | 16 +++---- 12 files changed, 130 insertions(+), 40 deletions(-) rename openbb_platform/extensions/{stocks/openbb_stocks => etf/openbb_etf}/disc/__init__.py (100%) rename openbb_platform/extensions/{stocks/openbb_stocks => etf/openbb_etf}/disc/disc_router.py (81%) rename openbb_platform/platform/provider/openbb_provider/standard_models/{asset_performance.py => etf_performance.py} (84%) diff --git a/openbb_platform/extensions/etf/integration/test_etf_api.py b/openbb_platform/extensions/etf/integration/test_etf_api.py index f9c52259c3d1..299e9e18b52e 100644 --- a/openbb_platform/extensions/etf/integration/test_etf_api.py +++ b/openbb_platform/extensions/etf/integration/test_etf_api.py @@ -78,3 +78,48 @@ def test_etf_price_performance(params, headers): result = requests.get(url, headers=headers, timeout=10) assert isinstance(result, requests.Response) assert result.status_code == 200 + + +@pytest.mark.parametrize( + "params", + [({"sort": "desc", "limit": 10, "provider": "wsj"})], +) +@pytest.mark.integration +def test_etf_disc_gainers(params, headers): + params = {p: v for p, v in params.items() if v} + + query_str = get_querystring(params, []) + url = f"http://0.0.0.0:8000/api/v1/stocks/disc/gainers?{query_str}" + result = requests.get(url, headers=headers, timeout=10) + assert isinstance(result, requests.Response) + assert result.status_code == 200 + + +@pytest.mark.parametrize( + "params", + [({"sort": "desc", "limit": 10, "provider": "wsj"})], +) +@pytest.mark.integration +def test_etf_disc_losers(params, headers): + params = {p: v for p, v in params.items() if v} + + query_str = get_querystring(params, []) + url = f"http://0.0.0.0:8000/api/v1/stocks/disc/losers?{query_str}" + result = requests.get(url, headers=headers, timeout=10) + assert isinstance(result, requests.Response) + assert result.status_code == 200 + + +@pytest.mark.parametrize( + "params", + [({"sort": "desc", "limit": 10, "provider": "wsj"})], +) +@pytest.mark.integration +def test_etf_disc_active(params, headers): + params = {p: v for p, v in params.items() if v} + + query_str = get_querystring(params, []) + url = f"http://0.0.0.0:8000/api/v1/stocks/disc/active?{query_str}" + result = requests.get(url, headers=headers, timeout=10) + assert isinstance(result, requests.Response) + assert result.status_code == 200 diff --git a/openbb_platform/extensions/etf/integration/test_etf_python.py b/openbb_platform/extensions/etf/integration/test_etf_python.py index 4d9273a91f86..63a4628ef139 100644 --- a/openbb_platform/extensions/etf/integration/test_etf_python.py +++ b/openbb_platform/extensions/etf/integration/test_etf_python.py @@ -75,3 +75,45 @@ def test_etf_price_performance(params, obb): assert result assert isinstance(result, OBBject) assert len(result.results) > 0 + + +@pytest.mark.parametrize( + "params", + [({"sort": "desc", "limit": 10})], +) +@pytest.mark.integration +def test_etf_disc_gainers(params, obb): + params = {p: v for p, v in params.items() if v} + + result = obb.stocks.disc.gainers(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 + + +@pytest.mark.parametrize( + "params", + [({"sort": "desc", "limit": 10})], +) +@pytest.mark.integration +def test_etf_disc_losers(params, obb): + params = {p: v for p, v in params.items() if v} + + result = obb.stocks.disc.losers(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 + + +@pytest.mark.parametrize( + "params", + [({"sort": "desc", "limit": 10})], +) +@pytest.mark.integration +def test_etf_disc_active(params, obb): + params = {p: v for p, v in params.items() if v} + + result = obb.stocks.disc.active(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 diff --git a/openbb_platform/extensions/stocks/openbb_stocks/disc/__init__.py b/openbb_platform/extensions/etf/openbb_etf/disc/__init__.py similarity index 100% rename from openbb_platform/extensions/stocks/openbb_stocks/disc/__init__.py rename to openbb_platform/extensions/etf/openbb_etf/disc/__init__.py diff --git a/openbb_platform/extensions/stocks/openbb_stocks/disc/disc_router.py b/openbb_platform/extensions/etf/openbb_etf/disc/disc_router.py similarity index 81% rename from openbb_platform/extensions/stocks/openbb_stocks/disc/disc_router.py rename to openbb_platform/extensions/etf/openbb_etf/disc/disc_router.py index 758a7f016a98..834d5180bbc3 100644 --- a/openbb_platform/extensions/stocks/openbb_stocks/disc/disc_router.py +++ b/openbb_platform/extensions/etf/openbb_etf/disc/disc_router.py @@ -1,3 +1,4 @@ +"""Disc router for ETFs.""" from openbb_core.app.model.command_context import CommandContext from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( @@ -12,34 +13,34 @@ router = Router(prefix="/disc") -@router.command(model="EquityGainers") +@router.command(model="ETFGainers") def gainers( cc: CommandContext, provider_choices: ProviderChoices, standard_params: StandardParams, extra_params: ExtraParams, ) -> OBBject[BaseModel]: - """Get the top Equity gainers.""" + """Get the top ETF gainers.""" return OBBject(results=Query(**locals()).execute()) -@router.command(model="EquityLosers") +@router.command(model="ETFLosers") def losers( cc: CommandContext, provider_choices: ProviderChoices, standard_params: StandardParams, extra_params: ExtraParams, ) -> OBBject[BaseModel]: - """Get the top Equity losers.""" + """Get the top ETF losers.""" return OBBject(results=Query(**locals()).execute()) -@router.command(model="EquityActive") +@router.command(model="ETFActive") def active( cc: CommandContext, provider_choices: ProviderChoices, standard_params: StandardParams, extra_params: ExtraParams, ) -> OBBject[BaseModel]: - """Get the most active Equities.""" + """Get the most active ETFs.""" return OBBject(results=Query(**locals()).execute()) diff --git a/openbb_platform/extensions/etf/openbb_etf/etf_router.py b/openbb_platform/extensions/etf/openbb_etf/etf_router.py index 4a78607664c7..b7bbeb83b2cc 100644 --- a/openbb_platform/extensions/etf/openbb_etf/etf_router.py +++ b/openbb_platform/extensions/etf/openbb_etf/etf_router.py @@ -11,7 +11,10 @@ from openbb_core.app.router import Router from pydantic import BaseModel +from openbb_etf.disc.disc_router import router as disc_router + router = Router(prefix="") +router.include_router(disc_router) # pylint: disable=unused-argument diff --git a/openbb_platform/extensions/stocks/openbb_stocks/stocks_router.py b/openbb_platform/extensions/stocks/openbb_stocks/stocks_router.py index 5faf86fe90db..9c506e439fc0 100644 --- a/openbb_platform/extensions/stocks/openbb_stocks/stocks_router.py +++ b/openbb_platform/extensions/stocks/openbb_stocks/stocks_router.py @@ -14,7 +14,6 @@ from pydantic import BaseModel from openbb_stocks.ca.ca_router import router as ca_router -from openbb_stocks.disc.disc_router import router as disc_router from openbb_stocks.fa.fa_router import router as fa_router from openbb_stocks.options.options_router import router as options_router @@ -28,7 +27,6 @@ router.include_router(fa_router) router.include_router(ca_router) router.include_router(options_router) -router.include_router(disc_router) # router.include_router(dps_router) # router.include_router(gov_router) diff --git a/openbb_platform/platform/provider/openbb_provider/standard_models/asset_performance.py b/openbb_platform/platform/provider/openbb_provider/standard_models/etf_performance.py similarity index 84% rename from openbb_platform/platform/provider/openbb_provider/standard_models/asset_performance.py rename to openbb_platform/platform/provider/openbb_provider/standard_models/etf_performance.py index 1688fc2b677e..f1cbee6ed7b2 100644 --- a/openbb_platform/platform/provider/openbb_provider/standard_models/asset_performance.py +++ b/openbb_platform/platform/provider/openbb_provider/standard_models/etf_performance.py @@ -1,4 +1,4 @@ -"""Available Indices data model.""" +"""ETF performance data model.""" from datetime import date as dateType from pydantic import Field @@ -8,8 +8,8 @@ from openbb_provider.utils.descriptions import DATA_DESCRIPTIONS, QUERY_DESCRIPTIONS -class AssetPerformanceQueryParams(QueryParams): - """Asset Performance QueryParams.""" +class ETFPerformanceQueryParams(QueryParams): + """ETF Performance QueryParams.""" sort: str = Field( default="desc", @@ -21,8 +21,8 @@ class AssetPerformanceQueryParams(QueryParams): ) -class AssetPerformanceData(Data): - """Asset performance data.""" +class ETFPerformanceData(Data): + """ETF performance data.""" symbol: str = Field( description=DATA_DESCRIPTIONS.get("symbol", ""), diff --git a/openbb_platform/providers/fmp/openbb_fmp/models/price_performance.py b/openbb_platform/providers/fmp/openbb_fmp/models/price_performance.py index edae55a5dbdd..e100499af0da 100644 --- a/openbb_platform/providers/fmp/openbb_fmp/models/price_performance.py +++ b/openbb_platform/providers/fmp/openbb_fmp/models/price_performance.py @@ -1,5 +1,4 @@ -"""FMP Price Performance Model""" - +"""FMP Price Performance Model.""" from typing import Any, Dict, List, Optional @@ -66,7 +65,9 @@ def extract_data( @staticmethod def transform_data( + query: FMPPricePerformanceQueryParams, data: Dict, **kwargs: Any, ) -> List[FMPPricePerformanceData]: + """Transform the raw data into the standard model.""" return [FMPPricePerformanceData.model_validate(data[i]) for i in data] diff --git a/openbb_platform/providers/wsj/openbb_wsj/__init__.py b/openbb_platform/providers/wsj/openbb_wsj/__init__.py index 661faf510554..ae57fac5e247 100644 --- a/openbb_platform/providers/wsj/openbb_wsj/__init__.py +++ b/openbb_platform/providers/wsj/openbb_wsj/__init__.py @@ -16,8 +16,8 @@ The WSJ is the largest newspaper in the United States, by circulation. """, fetcher_dict={ - "DiscGainers": WSJGainersFetcher, - "DiscLosers": WSJLosersFetcher, - "DiscActive": WSJActiveFetcher, + "ETFGainers": WSJGainersFetcher, + "ETFLosers": WSJLosersFetcher, + "ETFActive": WSJActiveFetcher, }, ) diff --git a/openbb_platform/providers/wsj/openbb_wsj/models/active.py b/openbb_platform/providers/wsj/openbb_wsj/models/active.py index 18b9605f918f..10fd190a5bb7 100644 --- a/openbb_platform/providers/wsj/openbb_wsj/models/active.py +++ b/openbb_platform/providers/wsj/openbb_wsj/models/active.py @@ -4,21 +4,21 @@ import requests from openbb_provider.abstract.fetcher import Fetcher -from openbb_provider.standard_models.asset_performance import ( - AssetPerformanceData, - AssetPerformanceQueryParams, +from openbb_provider.standard_models.etf_performance import ( + ETFPerformanceData, + ETFPerformanceQueryParams, ) from pydantic import Field, field_validator -class WSJActiveQueryParams(AssetPerformanceQueryParams): +class WSJActiveQueryParams(ETFPerformanceQueryParams): """WSJ asset performance active QueryParams. Source: https://www.wsj.com/market-data/mutualfunds-etfs/etfmovers """ -class WSJActiveData(AssetPerformanceData): +class WSJActiveData(ETFPerformanceData): """WSJ asset performance active Data.""" __alias_dict__ = { @@ -87,7 +87,7 @@ def extract_data( @staticmethod def transform_data( - query: AssetPerformanceQueryParams, + query: ETFPerformanceQueryParams, data: List[Dict], **kwargs: Any, ) -> List[WSJActiveData]: diff --git a/openbb_platform/providers/wsj/openbb_wsj/models/gainers.py b/openbb_platform/providers/wsj/openbb_wsj/models/gainers.py index a05d3f72a1df..3df971d5cd41 100644 --- a/openbb_platform/providers/wsj/openbb_wsj/models/gainers.py +++ b/openbb_platform/providers/wsj/openbb_wsj/models/gainers.py @@ -4,21 +4,21 @@ import requests from openbb_provider.abstract.fetcher import Fetcher -from openbb_provider.standard_models.asset_performance import ( - AssetPerformanceData, - AssetPerformanceQueryParams, +from openbb_provider.standard_models.etf_performance import ( + ETFPerformanceData, + ETFPerformanceQueryParams, ) from pydantic import Field, field_validator -class WSJGainersQueryParams(AssetPerformanceQueryParams): +class WSJGainersQueryParams(ETFPerformanceQueryParams): """WSJ asset performance gainers QueryParams. Source: https://www.wsj.com/market-data/mutualfunds-etfs/etfmovers """ -class WSJGainersData(AssetPerformanceData): +class WSJGainersData(ETFPerformanceData): """WSJ asset performance gainers Data.""" __alias_dict__ = { @@ -29,8 +29,8 @@ class WSJGainersData(AssetPerformanceData): "date": "timestamp", } - bluegrass_channel: str = Field( - description="Bluegrass channel.", + bluegrass_channel: Optional[str] = Field( + description="Bluegrass channel.", default=None ) country: str = Field( description="Country of the entity.", @@ -90,7 +90,7 @@ def extract_data( @staticmethod def transform_data( - query: AssetPerformanceQueryParams, + query: ETFPerformanceQueryParams, data: List[Dict], **kwargs: Any, ) -> List[WSJGainersData]: diff --git a/openbb_platform/providers/wsj/openbb_wsj/models/losers.py b/openbb_platform/providers/wsj/openbb_wsj/models/losers.py index ddbc2ffc31c7..f7ae05e6018f 100644 --- a/openbb_platform/providers/wsj/openbb_wsj/models/losers.py +++ b/openbb_platform/providers/wsj/openbb_wsj/models/losers.py @@ -4,21 +4,21 @@ import requests from openbb_provider.abstract.fetcher import Fetcher -from openbb_provider.standard_models.asset_performance import ( - AssetPerformanceData, - AssetPerformanceQueryParams, +from openbb_provider.standard_models.etf_performance import ( + ETFPerformanceData, + ETFPerformanceQueryParams, ) from pydantic import Field, field_validator -class WSJLosersQueryParams(AssetPerformanceQueryParams): +class WSJLosersQueryParams(ETFPerformanceQueryParams): """WSJ asset performance losers QueryParams. Source: https://www.wsj.com/market-data/mutualfunds-etfs/etfmovers """ -class WSJLosersData(AssetPerformanceData): +class WSJLosersData(ETFPerformanceData): """WSJ asset performance losers Data.""" __alias_dict__ = { @@ -29,8 +29,8 @@ class WSJLosersData(AssetPerformanceData): "date": "timestamp", } - bluegrass_channel: str = Field( - description="Bluegrass channel.", + bluegrass_channel: Optional[str] = Field( + description="Bluegrass channel.", default=None ) country: str = Field( description="Country of the entity.", @@ -90,7 +90,7 @@ def extract_data( @staticmethod def transform_data( - query: AssetPerformanceQueryParams, + query: ETFPerformanceQueryParams, data: List[Dict], **kwargs: Any, ) -> List[WSJLosersData]: