diff --git a/openbb_sdk/sdk/core/openbb_core/app/provider_interface.py b/openbb_sdk/sdk/core/openbb_core/app/provider_interface.py index 42049eb387a..af4c6477510 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/provider_interface.py +++ b/openbb_sdk/sdk/core/openbb_core/app/provider_interface.py @@ -1,5 +1,5 @@ from dataclasses import dataclass, make_dataclass -from typing import Any, Dict, List, Literal, Optional, Tuple, Type, Union +from typing import Any, Dict, List, Literal, Optional, Tuple, Type, TypeVar, Union from fastapi import Query from openbb_provider.query_executor import QueryExecutor @@ -7,13 +7,15 @@ from openbb_provider.registry_map import MapType, RegistryMap from pydantic import BaseConfig, BaseModel, Extra, Field, create_model from pydantic.fields import ModelField +TupleFieldType = TypeVar("TupleFieldType", bound=Tuple[str, type, Any]) + @dataclass class DataclassField: """Dataclass field.""" name: str - type_: Any + type_: type default: Any @@ -169,7 +171,7 @@ class ProviderInterface: return DataclassField( name=current_name, - type_=merged_type, + type_=merged_type, # type: ignore default=merged_default, ) @@ -220,10 +222,10 @@ class ProviderInterface: def _extract_params( cls, providers: Any, - ) -> Tuple[Dict[str, Tuple[str, type, Any]], Dict[str, Tuple[str, type, Any]]]: + ) -> Tuple[Dict[str, TupleFieldType], Dict[str, TupleFieldType]]: """Extract parameters from map.""" - standard: Dict[str, Tuple[str, Any, Any]] = {} - extra: Dict[str, Tuple[str, Any, Any]] = {} + standard: Dict[str, TupleFieldType] = {} + extra: Dict[str, TupleFieldType] = {} for provider_name, model_details in providers.items(): if provider_name == "openbb": @@ -267,9 +269,9 @@ class ProviderInterface: def _extract_data( cls, providers: Any, - ) -> Tuple[Dict[str, Tuple[str, type, Any]], Dict[str, Tuple[str, type, Any]]]: - standard: Dict[str, Tuple[str, Any, Any]] = {} - extra: Dict[str, Tuple[str, Any, Any]] = {} + ) -> Tuple[Dict[str, TupleFieldType], Dict[str, TupleFieldType]]: + standard: Dict[str, TupleFieldType] = {} + extra: Dict[str, TupleFieldType] = {} for provider_name, model_details in providers.items(): if provider_name == "openbb": @@ -326,8 +328,9 @@ class ProviderInterface: """ result: Dict = {} - # TODO: Consider multiprocessing this loop to speed startup for model_name, providers in map_.items(): + standard: dict + extra: dict standard, extra = self._extract_params(providers) result[model_name] = { @@ -392,6 +395,8 @@ class ProviderInterface: result: Dict = {} for model_name, providers in map_.items(): + standard: dict + extra: dict standard, extra = self._extract_data(providers) result[model_name] = { "standard": make_dataclass( # type: ignore diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package/crypto.py b/openbb_sdk/sdk/core/openbb_core/app/static/package/crypto.py index b8e6e6936f3..3b0416647f6 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package/crypto.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package/crypto.py @@ -34,7 +34,7 @@ class CLASS_crypto(Container): ] = None, chart: bool = False, provider: Optional[Literal["fmp", "polygon", "yfinance"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Crypto Intraday Price. diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package/fixedincome.py b/openbb_sdk/sdk/core/openbb_core/app/static/package/fixedincome.py index 957738f5196..c18efece12b 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package/fixedincome.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package/fixedincome.py @@ -32,7 +32,7 @@ class CLASS_fixedincome(Container): ] = None, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Get treasury rates. diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package/forex.py b/openbb_sdk/sdk/core/openbb_core/app/static/package/forex.py index 5e1cbb21410..f6a00a7ae0f 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package/forex.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package/forex.py @@ -18,7 +18,7 @@ class CLASS_forex(Container): self, chart: bool = False, provider: Optional[Literal["fmp", "polygon"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Forex Available Pairs. @@ -148,7 +148,7 @@ class CLASS_forex(Container): ] = None, chart: bool = False, provider: Optional[Literal["fmp", "polygon", "yfinance"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Forex Intraday Price. diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package/news.py b/openbb_sdk/sdk/core/openbb_core/app/static/package/news.py index 936a8206ca6..e690d59b5e4 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package/news.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package/news.py @@ -24,7 +24,7 @@ class CLASS_news(Container): ] = 0, chart: bool = False, provider: Optional[Literal["benzinga", "fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Global News. diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks.py b/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks.py index 2455302d023..b3616daaf55 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks.py @@ -102,7 +102,7 @@ class CLASS_stocks(Container): ] = None, chart: bool = False, provider: Optional[Literal["cboe", "fmp", "polygon", "yfinance"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Load stock data for a specific ticker. @@ -268,7 +268,7 @@ class CLASS_stocks(Container): ] = 15, chart: bool = False, provider: Optional[Literal["benzinga", "fmp", "polygon"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Get news for one or more stock tickers. @@ -455,7 +455,7 @@ class CLASS_stocks(Container): ] = 100, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Get valuation multiples for a stock ticker. @@ -670,7 +670,7 @@ class CLASS_stocks(Container): ] = False, chart: bool = False, provider: Optional[Literal["cboe"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Search for a company or stock ticker. @@ -752,7 +752,7 @@ class CLASS_stocks(Container): ], chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Load stock data for a specific ticker. @@ -868,7 +868,7 @@ class CLASS_stocks(Container): ], chart: bool = False, provider: Optional[Literal["cboe"]] = None, - **kwargs + **kwargs, ) -> OBBject[BaseModel]: """Get general price and performance metrics of a stock. diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_ca.py b/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_ca.py index bf341ae33dc..d7f1970b697 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_ca.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_ca.py @@ -23,7 +23,7 @@ class CLASS_stocks_ca(Container): ], chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[BaseModel]: """Company peers. diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_dd.py b/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_dd.py index 7d04ee19715..809429f536c 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_dd.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_dd.py @@ -134,7 +134,7 @@ class CLASS_stocks_dd(Container): ] = 100, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """SEC Filings. diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_fa.py b/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_fa.py index 1a581942af0..65e52e2826f 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_fa.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package/stocks_fa.py @@ -53,7 +53,7 @@ class CLASS_stocks_fa(Container): ] = 12, chart: bool = False, provider: Optional[Literal["fmp", "polygon"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Balance Sheet. @@ -288,7 +288,7 @@ class CLASS_stocks_fa(Container): ] = 10, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Balance Sheet Statement Growth. @@ -455,7 +455,7 @@ class CLASS_stocks_fa(Container): ] = None, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Show Dividend Calendar for a given start and end dates. @@ -556,7 +556,7 @@ class CLASS_stocks_fa(Container): ] = 12, chart: bool = False, provider: Optional[Literal["fmp", "polygon"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Cash Flow Statement. @@ -753,7 +753,7 @@ class CLASS_stocks_fa(Container): ] = 10, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Cash Flow Statement Growth. @@ -894,7 +894,7 @@ class CLASS_stocks_fa(Container): ], chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Executive Compensation. @@ -1000,7 +1000,7 @@ class CLASS_stocks_fa(Container): ] = None, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Stock Split Calendar. @@ -1119,7 +1119,7 @@ class CLASS_stocks_fa(Container): ], chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Historical Dividends. @@ -1226,7 +1226,7 @@ class CLASS_stocks_fa(Container): ] = 50, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Earnings Calendar. @@ -1319,7 +1319,7 @@ class CLASS_stocks_fa(Container): ], chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Number of Employees. @@ -1453,7 +1453,7 @@ class CLASS_stocks_fa(Container): ] = 30, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Analyst Estimates. @@ -1669,7 +1669,7 @@ class CLASS_stocks_fa(Container): ] = 12, chart: bool = False, provider: Optional[Literal["fmp", "polygon"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Income Statement. @@ -1890,7 +1890,7 @@ class CLASS_stocks_fa(Container): ] = "annually", chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Income Statement Growth. @@ -2065,7 +2065,7 @@ class CLASS_stocks_fa(Container): ] = 0, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Stock Insider Trading. @@ -2186,7 +2186,7 @@ class CLASS_stocks_fa(Container): ] = None, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Institutional Ownership. @@ -2362,7 +2362,7 @@ class CLASS_stocks_fa(Container): ] = 100, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Key Metrics. @@ -2560,7 +2560,7 @@ class CLASS_stocks_fa(Container): ], chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Key Executives. @@ -2679,7 +2679,7 @@ class CLASS_stocks_fa(Container): ], chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[BaseModel]: """Company Overview. @@ -2831,7 +2831,7 @@ class CLASS_stocks_fa(Container): ] = 0, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Stock Ownership. @@ -2987,7 +2987,7 @@ class CLASS_stocks_fa(Container): ], chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[BaseModel]: """Price Target Consensus. @@ -3069,7 +3069,7 @@ class CLASS_stocks_fa(Container): ], chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Price Target. @@ -3174,7 +3174,7 @@ class CLASS_stocks_fa(Container): ] = 12, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Extensive set of ratios over time. @@ -3410,7 +3410,7 @@ class CLASS_stocks_fa(Container): ] = "flat", chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Revenue Geographic. @@ -3512,7 +3512,7 @@ class CLASS_stocks_fa(Container): ] = "flat", chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Revenue Business Line. @@ -3660,7 +3660,7 @@ class CLASS_stocks_fa(Container): ], chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Share Statistics. @@ -3744,7 +3744,7 @@ class CLASS_stocks_fa(Container): ], chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Historical Stock Splits. @@ -3853,7 +3853,7 @@ class CLASS_stocks_fa(Container): ] = 1, chart: bool = False, provider: Optional[Literal["fmp"]] = None, - **kwargs + **kwargs, ) -> OBBject[List]: """Earnings Call Transcript. diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package_builder.py b/openbb_sdk/sdk/core/openbb_core/app/static/package_builder.py index 90269669e50..4b944dfdffb 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package_builder.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package_builder.py @@ -243,7 +243,7 @@ class DocstringGenerator: """Dynamically generate docstrings for the commands.""" @staticmethod - def get_OBBject_description() -> str: + def get_object_description() -> str: """Get the command output description.""" OBBject_description = ( "\nReturns\n" @@ -327,7 +327,7 @@ class DocstringGenerator: section_docstring += f"{padding}{field_description}\n" if provider == "openbb" and section_name == "QueryParams": - section_docstring += cls.get_OBBject_description() + section_docstring += cls.get_object_description() return section_docstring diff --git a/openbb_sdk/sdk/core/tests/app/static/test_package_builder.py b/openbb_sdk/sdk/core/tests/app/static/test_package_builder.py index 659061194a2..823e8225b98 100644 --- a/openbb_sdk/sdk/core/tests/app/static/test_package_builder.py +++ b/openbb_sdk/sdk/core/tests/app/static/test_package_builder.py @@ -5,8 +5,10 @@ from dataclasses import dataclass from inspect import _empty import pytest +from openbb_core.app.provider_interface import get_provider_interface from openbb_core.app.static.package_builder import ( ClassDefinition, + DocstringGenerator, ImportDefinition, Linters, MethodDefinition, @@ -446,4 +448,84 @@ def test_mypy(linters): linters.mypy() -# TODO: Implement unit test for the DocstringGenerator class once refactored. +@pytest.fixture(scope="module") +def docstring_generator(): + """Return package builder.""" + return DocstringGenerator() + + +def test_docstring_generator_init(docstring_generator): + """Test docstring generator init.""" + assert docstring_generator + + +def test_get_object_description(docstring_generator): + """Test build docstring.""" + docstring = docstring_generator.get_object_description() + assert docstring + + +def test_get_available_providers(docstring_generator): + """Test get available providers.""" + provider_assert = ["fmp", "polygon"] + some_mapping = {"fmp": 1, "openbb": 2, "polygon": 3} + providers = docstring_generator.get_available_providers(query_mapping=some_mapping) + assert providers + for provider in provider_assert: + assert provider in providers + + +def test_reorder_dictionary(docstring_generator): + """Test reorder dictionary.""" + some_mapping = {"fmp": 1, "openbb": 2, "polygon": 3} + reordered = docstring_generator.reorder_dictionary( + dictionary=some_mapping, key_to_move_first="openbb" + ) + assert reordered + assert list(reordered.keys())[0] == "openbb" + + +def test_extract_field_details(docstring_generator): + """Test extract field details.""" + mapping = get_provider_interface().map + section_docstring = docstring_generator.extract_field_details( + model_name="GlobalNews", + provider="openbb", + section_name="QueryParams", + section_docstring="some_param: str\n Some param description\n", + mapping=mapping, + ) + assert section_docstring + assert "some_param" in section_docstring + + +def test_generate_provider_docstrings(docstring_generator): + """Test generate provider docstrings.""" + docstring = "" + model_name = "GlobalNews" + provider_interface_mapping = get_provider_interface().map + query_mapping = provider_interface_mapping.get(model_name, None) + docstring = docstring_generator.generate_provider_docstrings( + docstring=docstring, + query_mapping=query_mapping, + model_name=model_name, + provider_interface_mapping=provider_interface_mapping, + ) + + assert docstring + assert "openbb" in docstring + assert "GlobalNews" in docstring + + +def test_generate_command_docstring(docstring_generator): + """Test generate command docstring.""" + + def some_func(): + """Some func docstring.""" + pass + + docstring = docstring_generator.generate_command_docstring( + func=some_func, model_name="GlobalNews" + ) + assert docstring + assert "openbb" in docstring.__doc__