diff options
author | Danglewood <85772166+deeleeramone@users.noreply.github.com> | 2024-04-22 09:45:56 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-22 16:45:56 +0000 |
commit | ee422419d0db8859471522af9c8cc47bebe084f4 (patch) | |
tree | 93886292d4cf10a5351927ea45f501f687c97b61 | |
parent | f18680a5c2b78f82941ce4bca74f6faac834aa73 (diff) |
[Feature] EconDB Provider Extension With New Economy Endpoints. (#6313)
* economy router
* router endpoints
* update available_indicators
* add econdb provider extension
* black
* fetcher test
* country description
* recapture tests and router examples
* black
* codespell
* codespell skip
* codespell skip...?
* use . instead of * in codespell.skip?
* this is supposed to skip the file from codespell
* try another thing for codespell
* unused import
* pylint
* doc page example - df.filter needs axis
* unused argument
* more pylint
* mypy
* insert image to doc page
* recapture test
* description
* mypy
* Update .codespell.skip
* black
* linting..
* more linters
* black
* init docstring
* static files
---------
Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com>
36 files changed, 16017 insertions, 387 deletions
diff --git a/.codespell.ignore b/.codespell.ignore index a2564b9c108..c0b8680423f 100644 --- a/.codespell.ignore +++ b/.codespell.ignore @@ -34,6 +34,7 @@ shold shs statics te +tha toke vai varian diff --git a/openbb_platform/core/openbb_core/provider/standard_models/available_indicators.py b/openbb_platform/core/openbb_core/provider/standard_models/available_indicators.py new file mode 100644 index 00000000000..3e1167b1d82 --- /dev/null +++ b/openbb_platform/core/openbb_core/provider/standard_models/available_indicators.py @@ -0,0 +1,43 @@ +"""Available Indicators Standard Model.""" + +from typing import Optional + +from pydantic import Field + +from openbb_core.provider.abstract.data import Data +from openbb_core.provider.abstract.query_params import QueryParams +from openbb_core.provider.utils.descriptions import DATA_DESCRIPTIONS + + +class AvailableIndicesQueryParams(QueryParams): + """Available Indicators Query.""" + + +class AvailableIndicatorsData(Data): + """Available Indicators Data. + + Returns the list of available economic indicators from a provider. + """ + + symbol_root: Optional[str] = Field( + default=None, description="The root symbol representing the indicator." + ) + symbol: Optional[str] = Field( + default=None, + description=DATA_DESCRIPTIONS.get("symbol", "") + + " The root symbol with additional codes.", + ) + country: Optional[str] = Field( + default=None, + description="The name of the country, region, or entity represented by the symbol.", + ) + iso: Optional[str] = Field( + default=None, + description="The ISO code of the country, region, or entity represented by the symbol.", + ) + description: Optional[str] = Field( + default=None, description="The description of the indicator." + ) + frequency: Optional[str] = Field( + default=None, description="The frequency of the indicator data." + ) diff --git a/openbb_platform/core/openbb_core/provider/standard_models/country_profile.py b/openbb_platform/core/openbb_core/provider/standard_models/country_profile.py new file mode 100644 index 00000000000..1dccae669c7 --- /dev/null +++ b/openbb_platform/core/openbb_core/provider/standard_models/country_profile.py @@ -0,0 +1,89 @@ +"""Country Profile Standard Model.""" + +from typing import Optional + +from pydantic import Field, field_validator + +from openbb_core.provider.abstract.data import Data +from openbb_core.provider.abstract.query_params import QueryParams +from openbb_core.provider.utils.descriptions import ( + DATA_DESCRIPTIONS, + QUERY_DESCRIPTIONS, +) + + +class CountryProfileQueryParams(QueryParams): + """Country Profile Query.""" + + country: str = Field(description=QUERY_DESCRIPTIONS.get("country", "")) + + @field_validator("country", mode="before", check_fields=False) + @classmethod + def to_lower(cls, v: str) -> str: + """Convert the country to lowercase.""" + return v.lower().replace(" ", "_") + + +class CountryProfileData(Data): + """Country Profile Data.""" + + country: str = Field(description=DATA_DESCRIPTIONS.get("country", "")) + population: Optional[int] = Field(default=None, description="Population.") + gdp_usd: Optional[float] = Field( + default=None, description="Gross Domestic Product, in billions of USD." + ) + gdp_qoq: Optional[float] = Field( + default=None, + description="GDP growth quarter-over-quarter change, as a normalized percent.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + gdp_yoy: Optional[float] = Field( + default=None, + description="GDP growth year-over-year change, as a normalized percent.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + cpi_yoy: Optional[float] = Field( + default=None, + description="Consumer Price Index year-over-year change, as a normalized percent.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + core_yoy: Optional[float] = Field( + default=None, + description="Core Consumer Price Index year-over-year change, as a normalized percent.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + retail_sales_yoy: Optional[float] = Field( + default=None, + description="Retail Sales year-over-year change, as a normalized percent.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + industrial_production_yoy: Optional[float] = Field( + default=None, + description="Industrial Production year-over-year change, as a normalized percent.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + policy_rate: Optional[float] = Field( + default=None, + description="Short term policy rate, as a normalized percent.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + yield_10y: Optional[float] = Field( + default=None, + description="10-year government bond yield, as a normalized percent.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + govt_debt_gdp: Optional[float] = Field( + default=None, + description="Government debt as a percent (normalized) of GDP.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + current_account_gdp: Optional[float] = Field( + default=None, + description="Current account balance as a percent (normalized) of GDP.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + jobless_rate: Optional[float] = Field( + default=None, + description="Unemployment rate, as a normalized percent.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) diff --git a/openbb_platform/core/openbb_core/provider/standard_models/economic_indicators.py b/openbb_platform/core/openbb_core/provider/standard_models/economic_indicators.py new file mode 100644 index 00000000000..3abbfc861ea --- /dev/null +++ b/openbb_platform/core/openbb_core/provider/standard_models/economic_indicators.py @@ -0,0 +1,57 @@ +"""Economic Indicators Standard Model.""" + +from datetime import date as dateType +from typing import Optional, Union + +from pydantic import Field, field_validator + +from openbb_core.provider.abstract.data import Data +from openbb_core.provider.abstract.query_params import QueryParams +from openbb_core.provider.utils.descriptions import ( + DATA_DESCRIPTIONS, + QUERY_DESCRIPTIONS, +) + + +class EconomicIndicatorsQueryParams(QueryParams): + """Economic Indicators Query.""" + + symbol: str = Field( + description=QUERY_DESCRIPTIONS.get("symbol", "") + + " The base symbol for the indicator (e.g. GDP, CPI, etc.).", + ) + country: Optional[str] = Field( + default=None, + description=QUERY_DESCRIPTIONS.get("country", "") + + " The country represented by the indicator, if available.", + ) + start_date: Optional[dateType] = Field( + description=QUERY_DESCRIPTIONS.get("start_date", ""), default=None + ) + end_date: Optional[dateType] = Field( + description=QUERY_DESCRIPTIONS.get("end_date", ""), default=None + ) + + @field_validator("symbol", mode="before", check_fields=False) + @classmethod + def to_upper(cls, v: str) -> str: + """Convert field to uppercase.""" + return v.upper() + + +class EconomicIndicatorsData(Data): + """Economic Indicators Data.""" + + date: dateType = Field(description=DATA_DESCRIPTIONS.get("date", "")) + symbol_root: Optional[str] = Field( + default=None, description="The root symbol for the indicator (e.g. GDP)." + ) + symbol: Optional[str] = Field( + default=None, description=DATA_DESCRIPTIONS.get("symbol", "") + ) + country: Optional[str] = Field( + default=None, description="The country represented by the data." + ) + value: Optional[Union[int, float]] = Field( + default=None, description=DATA_DESCRIPTIONS.get("value", "") + ) diff --git a/openbb_platform/dev_install.py b/openbb_platform/dev_install.py index 1f157976b5b..391aa08fa28 100644 --- a/openbb_platform/dev_install.py +++ b/openbb_platform/dev_install.py @@ -18,6 +18,7 @@ openbb-devtools = { path = "./extensions/devtools", develop = true } openbb-core = { path = "./core", develop = true } openbb-benzinga = { path = "./providers/benzinga", develop = true } +openbb-econdb = { path = "./providers/econdb", develop = true } openbb-federal-reserve = { path = "./providers/federal_reserve", develop = true } openbb-fmp = { path = "./providers/fmp", develop = true } openbb-fred = { path = "./providers/fred", develop = true } diff --git a/openbb_platform/extensions/economy/integration/test_economy_api.py b/openbb_platform/extensions/economy/integration/test_economy_api.py index 9563b719459..839065cecef 100644 --- a/openbb_platform/extensions/economy/integration/test_economy_api.py +++ b/openbb_platform/extensions/economy/integration/test_economy_api.py @@ -562,3 +562,74 @@ def test_economy_fred_regional(params, headers): result = requests.get(url, headers=headers, timeout=10) assert isinstance(result, requests.Response) assert result.status_code == 200 + + +@parametrize( + "params", + [ + ( + { + "provider": "econdb", + "country": "us,uk,jp", + "symbol": "GDP,GDEBT", + "transform": None, + "start_date": "2022-01-01", + "end_date": "2024-01-01", + "use_cache": False, + } + ), + ], +) +@pytest.mark.integration +def test_economy_indicators(params, headers): + """Test the economy indicators.""" + 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/economy/indicators?{query_str}" + result = requests.get(url, headers=headers, timeout=20) + assert isinstance(result, requests.Response) + assert result.status_code == 200 + + +@parametrize( + "params", + [ + ({"provider": "econdb", "use_cache": False}), + ], +) +@pytest.mark.integration +def test_economy_available_indicators(params, headers): + """Test the economy available indicators.""" + 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/economy/available_indicators?{query_str}" + result = requests.get(url, headers=headers, timeout=5) + assert isinstance(result, requests.Response) + assert result.status_code == 200 + + +@parametrize( + "params", + [ + ( + { + "provider": "econdb", + "country": "us,uk,jp", + "latest": True, + "use_cache": False, + } + ), + ], +) +@pytest.mark.integration +def test_economy_country_profile(params, headers): + """Test the economy country profile.""" + 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/economy/country_profile?{query_str}" + result = requests.get(url, headers=headers, timeout=30) + assert isinstance(result, requests.Response) + assert result.status_code == 200 diff --git a/openbb_platform/extensions/economy/integration/test_economy_python.py b/openbb_platform/extensions/economy/integration/test_economy_python.py index bf9c7bfa1e7..a838c71a272 100644 --- a/openbb_platform/extensions/economy/integration/test_economy_python.py +++ b/openbb_platform/extensions/economy/integration/test_economy_python.py @@ -510,3 +510,71 @@ def test_economy_fred_regional(params, obb): assert result assert isinstance(result, OBBject) assert len(result.results) > 0 + + +@parametrize( + "params", + [ + ( + { + "provider": "econdb", + "country": "us,uk,jp", + "latest": True, + "use_cache": False, + } + ), + ], +) +@pytest.mark.integration +def test_economy_country_profile(params, obb): + """Test economy country profile.""" + params = {p: v for p, v in params.items() if v} + + result = obb.economy.country_profile(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 + + +@parametrize( + "params", + [ + ({"provider": "econdb", "use_cache": False}), + ], +) +@pytest.mark.integration +def test_economy_available_indicators(params, obb): + """Test economy available indicators.""" + params = {p: v for p, v in params.items() if v} + + result = obb.economy.available_indicators(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 + + +@parametrize( + "params", + [ + ( + { + "provider": "econdb", + "country": "us,uk,jp", + "symbol": "GDP,GDEBT", + "transform": None, + "start_date": "2022-01-01", + "end_date": "2024-01-01", + "use_cache": False, + } + ), + ], +) +@pytest.mark.integration +def test_economy_indicators(params, obb): + """Test economy indicators.""" + params = {p: v for p, v in params.items() if v} + + result = obb.economy.indicators(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 diff --git a/openbb_platform/extensions/economy/openbb_economy/economy_router.py b/openbb_platform/extensions/economy/openbb_economy/economy_router.py index 9f3b6e05577..7ccb4a723d1 100644 --- a/openbb_platform/extensions/economy/openbb_economy/economy_router.py +++ b/openbb_platform/extensions/economy/openbb_economy/economy_router.py @@ -306,3 +306,69 @@ async def fred_regional( The series group ID is found by using `fred_search` and the `series_id` parameter. """ return await OBBject.from_query(Query(**locals())) + + +@router.command( + model="CountryProfile", + examples=[ + APIEx(parameters={"provider": "econdb", "country": "united_kingdom"}), + APIEx( + description="Enter the country as the full name, or iso code." + + " If `latest` is False, the complete history for each series is returned.", + parameters={ + "country": "united_states,jp", + "latest": False, + "provider": "econdb", + }, + ), + ], +) +async def country_profile( + cc: CommandContext, + provider_choices: ProviderChoices, + standard_params: StandardParams, + extra_params: ExtraParams, +) -> OBBject: + """Get a profile of country statistics and economic indicators.""" + return await OBBject.from_query(Query(**locals())) + + +@router.command( + model="AvailableIndicators", + examples=[ + APIEx(parameters={"provider": "econdb"}), + ], +) +async def available_indicators( + cc: CommandContext, + provider_choices: ProviderChoices, + standard_params: StandardParams, + extra_params: ExtraParams, +) -> OBBject: + """Get the available economic indicators for a provider.""" + return await OBBject.from_query(Query(**locals())) + + +@router.command( + model="EconomicIndicators", + examples=[ + APIEx(parameters={"provider": "econdb", "symbol": "PCOCO"}), + APIEx( + description="Enter the country as the full name, or iso code." + + " Use `available_indicators()` to get a list of supported indicators from EconDB.", + parameters={ + "symbol": "CPI", + "country": "united_states,jp", + "provider": "econdb", + }, + ), + ], +) +async def indicators( + cc: CommandContext, + provider_choices: ProviderChoices, + standard_params: StandardParams, + extra_params: ExtraParams, +) -> OBBject: + """Get economic indicators by country and indicator.""" + return await OBBject.from_query(Query(**locals())) diff --git a/openbb_platform/openbb/assets/reference.json b/openbb_platform/openbb/assets/reference.json index 76e676be348..d9f6ebca19d 100644 --- a/openbb_platform/openbb/assets/reference.json +++ b/openbb_platform/openbb/assets/reference.json @@ -20,6 |