From c852dc3d4d133c444fd6f5d3c496bffd36e12836 Mon Sep 17 00:00:00 2001 From: Diogo Sousa Date: Sun, 30 Jul 2023 17:18:28 +0100 Subject: [PATCH] handle multiple types of data (the fetcher should declare them later) --- .../openbb_core/app/provider_interface.py | 22 ++++++++++++------- openbb_sdk/sdk/core/openbb_core/app/router.py | 8 +++---- .../app/static/package/__commands__.py | 1 - .../openbb_provider/abstract/fetcher.py | 8 +++---- .../openbb_provider/query_executor.py | 4 +--- .../provider/openbb_provider/registry_map.py | 13 ++++------- 6 files changed, 25 insertions(+), 31 deletions(-) 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 dc6eba5a7a9..94e2fc04f0e 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/provider_interface.py +++ b/openbb_sdk/sdk/core/openbb_core/app/provider_interface.py @@ -1,7 +1,8 @@ from dataclasses import dataclass, make_dataclass -from typing import Any, Dict, List, Literal, Optional, Tuple, Union +from typing import Any, Dict, List, Literal, Optional, Tuple, Type, Union from fastapi import Query +from openbb_provider.abstract.fetcher import GenericDataType from openbb_provider.query_executor import QueryExecutor from openbb_provider.registry_map import MapType, RegistryMap from pydantic import BaseConfig, BaseModel, Extra, Field, create_model @@ -55,7 +56,7 @@ class ProviderInterface: Dictionary of provider choices by model. params : Dict[str, Dict[str, Union[StandardParams, ExtraParams]]] Dictionary of params by model. - merged_data : Dict[str, BaseModel] + merged_return : Dict[str, Type[BaseModel]] Dictionary of data by model. providers_literal : type Literal of provider names. @@ -85,7 +86,7 @@ class ProviderInterface: ) self._params = self._generate_params_dc(self._registry_map) self._data = self._generate_data_dc(self._registry_map) - self._merged_data = self._merge_data_dc(self._data) + self._merged_return = self._merged_return_model(self._data) self._providers_literal = self._get_provider_literal( self._registry_map.available_providers ) @@ -117,9 +118,9 @@ class ProviderInterface: return self._data @property - def merged_data(self) -> Dict[str, BaseModel]: + def merged_return(self) -> Dict[str, Type[BaseModel]]: """Dictionary of data by model merged.""" - return self._merged_data + return self._merged_return @property def providers_literal(self) -> type: @@ -399,9 +400,9 @@ class ProviderInterface: return result - def _merge_data_dc( + def _merged_return_model( self, data: Dict[str, Dict[str, Union[StandardData, ExtraData]]] - ) -> Dict[str, BaseModel]: + ) -> Dict[str, Type[BaseModel]]: """Merge standard data with extra data into a single BaseModel to benzinga injected as FastAPI dependency.""" result: Dict = {} @@ -426,12 +427,17 @@ class ProviderInterface: class Config(BaseConfig): extra = Extra.allow - result[model_name] = create_model( # type: ignore + model = create_model( # type: ignore model_name, __config__=Config, **fields_dict, # type: ignore ) + # TODO: Get GenericDataType depending on the model + # The info needs to be in the registry_map + # instead of hardcoding it with Union[..., List[...], Dict[str, ...]] + result[model_name] = GenericDataType[model] + return result def _get_provider_literal(self, available_providers: List[str]) -> type: diff --git a/openbb_sdk/sdk/core/openbb_core/app/router.py b/openbb_sdk/sdk/core/openbb_core/app/router.py index 1bda623ab9d..e50dd80c04c 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/router.py +++ b/openbb_sdk/sdk/core/openbb_core/app/router.py @@ -19,7 +19,6 @@ from typing import ( import pkg_resources from fastapi import APIRouter, Depends -from openbb_provider.abstract.fetcher import GenericDataType from pydantic import BaseModel from pydantic.config import BaseConfig from pydantic.validators import find_validators @@ -260,10 +259,9 @@ class SignatureInspector: callable_=provider_interface.params[model]["extra"], ) - # TODO: Implement the output structure in each endpoint and then just fill - # the genertic with `data_type` - data_type = provider_interface.merged_data[model] - func.__annotations__["return"] = CommandOutput[GenericDataType[data_type]] + ReturnModel = provider_interface.merged_return[model] + func.__annotations__["return"] = CommandOutput[ReturnModel] # type: ignore + elif ( "provider_choices" in func.__annotations__ and func.__annotations__["provider_choices"] == ProviderChoices diff --git a/openbb_sdk/sdk/core/openbb_core/app/static/package/__commands__.py b/openbb_sdk/sdk/core/openbb_core/app/static/package/__commands__.py index 465e59d17d5..d059a295ecb 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/static/package/__commands__.py +++ b/openbb_sdk/sdk/core/openbb_core/app/static/package/__commands__.py @@ -1,7 +1,6 @@ ### THIS FILE IS AUTO-GENERATED. DO NOT EDIT. ### - from openbb_core.app.static.container import Container diff --git a/openbb_sdk/sdk/provider/openbb_provider/abstract/fetcher.py b/openbb_sdk/sdk/provider/openbb_provider/abstract/fetcher.py index ed9fa45ec86..55cb29abc46 100644 --- a/openbb_sdk/sdk/provider/openbb_provider/abstract/fetcher.py +++ b/openbb_sdk/sdk/provider/openbb_provider/abstract/fetcher.py @@ -77,8 +77,6 @@ class Fetcher( # pylint: disable=E1101 return self.__orig_bases__[0].__args__[3] - @property - def return_type(self): - """Get the type of the return.""" - # pylint: disable=E1101 - return self.transform_data.__annotations__["return"] + # TODO: Create abstract class attribute for generic return type + # @property + # def generic_return_type(self): diff --git a/openbb_sdk/sdk/provider/openbb_provider/query_executor.py b/openbb_sdk/sdk/provider/openbb_provider/query_executor.py index b94b7d129a8..19c232f088e 100644 --- a/openbb_sdk/sdk/provider/openbb_provider/query_executor.py +++ b/openbb_sdk/sdk/provider/openbb_provider/query_executor.py @@ -42,9 +42,7 @@ class QueryExecutor: for c in provider.required_credentials: credential_value = credentials.get(c) if c not in credentials or credential_value is None: - raise ProviderError( - f"Missing credential '{c}'." - ) + raise ProviderError(f"Missing credential '{c}'.") def execute( self, diff --git a/openbb_sdk/sdk/provider/openbb_provider/registry_map.py b/openbb_sdk/sdk/provider/openbb_provider/registry_map.py index dbe1e13a701..c9246757918 100644 --- a/openbb_sdk/sdk/provider/openbb_provider/registry_map.py +++ b/openbb_sdk/sdk/provider/openbb_provider/registry_map.py @@ -57,7 +57,7 @@ class RegistryMap: f = fetcher() standard_query, extra_query = self.extract_info(f, "query_params") standard_data, extra_data = self.extract_info(f, "data") - return_info = self.extract_return_info(f) + return_type = self.extract_return_type(f) if model_name not in map_: map_[model_name] = {} @@ -69,7 +69,7 @@ class RegistryMap: map_[model_name][p] = { "QueryParams": extra_query, "Data": extra_data, - "Return": return_info, + "ReturnType": return_type, } return map_ @@ -98,12 +98,7 @@ class RegistryMap: return standard_info, extra_info - @staticmethod - def extract_return_info(fetcher: Fetcher): + def extract_return_type(fetcher: Fetcher): """Extract return info from fetcher.""" - - data_type = getattr(fetcher, "provider_data_type") - return_type = fetcher.return_type - - return (data_type, return_type) + return getattr(fetcher, "generic_return_type", None)