diff --git a/openbb_sdk/openbb_sdk_core/openbb_sdk_core/app/model/defaults.py b/openbb_sdk/openbb_sdk_core/openbb_sdk_core/app/model/defaults.py new file mode 100644 index 00000000000..154d5f93fc9 --- /dev/null +++ b/openbb_sdk/openbb_sdk_core/openbb_sdk_core/app/model/defaults.py @@ -0,0 +1,20 @@ +from typing import Dict + +from pydantic import BaseModel + + +class Defaults(BaseModel): + """Defaults.""" + + # TODO: Understand if this is good to sync with the hub + endpoints: Dict[str, Dict[str, str]] = { + "/stocks/load": {"provider": "polygon"}, + "/stocks/news": {"provider": "fmp"}, + } + + def __repr__(self) -> str: + return ( + self.__class__.__name__ + + "\n\n" + + "\n".join([f"{k}: {v}" for k, v in self.dict().items()]) + ) diff --git a/openbb_sdk/openbb_sdk_core/openbb_sdk_core/app/model/user_settings.py b/openbb_sdk/openbb_sdk_core/openbb_sdk_core/app/model/user_settings.py index 46df3c74e62..65678799bbb 100644 --- a/openbb_sdk/openbb_sdk_core/openbb_sdk_core/app/model/user_settings.py +++ b/openbb_sdk/openbb_sdk_core/openbb_sdk_core/app/model/user_settings.py @@ -2,6 +2,7 @@ from pydantic import Field from openbb_sdk_core.app.model.abstract.tagged import Tagged from openbb_sdk_core.app.model.credentials import Credentials +from openbb_sdk_core.app.model.defaults import Defaults from openbb_sdk_core.app.model.preferences import Preferences from openbb_sdk_core.app.model.profile import Profile @@ -10,6 +11,7 @@ class UserSettings(Tagged): profile: Profile = Field(default_factory=Profile) credentials: Credentials = Field(default_factory=Credentials) preferences: Preferences = Field(default_factory=Preferences) + defaults: Defaults = Field(default_factory=Defaults) def __repr__(self) -> str: return ( diff --git a/openbb_sdk/openbb_sdk_core/openbb_sdk_core/app/static/package_builder.py b/openbb_sdk/openbb_sdk_core/openbb_sdk_core/app/static/package_builder.py index e4b49b146a0..be255647bbc 100644 --- a/openbb_sdk/openbb_sdk_core/openbb_sdk_core/app/static/package_builder.py +++ b/openbb_sdk/openbb_sdk_core/openbb_sdk_core/app/static/package_builder.py @@ -170,6 +170,7 @@ class ImportDefinition: code += "\nfrom types import NoneType" code += "\nimport pydantic" code += "\nfrom pydantic import validate_arguments" + code += "\nfrom inspect import Parameter" code += "\nfrom typing import List, Dict, Union, Optional, Literal" code += "\nimport warnings" code += "\nimport builtins" @@ -254,19 +255,15 @@ class MethodDefinition: ) @staticmethod - def reorder_params( - params: Dict[str, Parameter] - ) -> OrderedDict[str, Union[str, Parameter]]: + def reorder_params(params: Dict[str, Parameter]) -> OrderedDict[str, Parameter]: formatted_keys = list(params.keys()) for k in ["provider", "extra_params"]: if k in formatted_keys: formatted_keys.remove(k) formatted_keys.append(k) - od: OrderedDict[str, Union[str, Parameter]] = OrderedDict() + od: OrderedDict[str, Parameter] = OrderedDict() for k in formatted_keys: - if k == "provider": - od["*"] = "*" od[k] = params[k] return od @@ -274,7 +271,7 @@ class MethodDefinition: @staticmethod def format_params( parameter_map: Dict[str, Parameter] - ) -> OrderedDict[str, Union[str, Parameter]]: + ) -> OrderedDict[str, Parameter]: # These are types we want to expand. # For example, start_date is always a 'date', but we also accept 'str' as input. # Be careful, if the type is not coercible by pydantic to the original type, you @@ -283,6 +280,7 @@ class MethodDefinition: "data": pd.DataFrame, "start_date": str, "end_date": str, + "provider": None, } parameter_map.pop("cc", None) @@ -292,13 +290,16 @@ class MethodDefinition: for name, param in parameter_map.items(): if name == "extra_params": formatted[name] = Parameter(name="kwargs", kind=Parameter.VAR_KEYWORD) - elif MethodDefinition.is_annotated_dc(param.annotation): fields = param.annotation.__args__[0].__dataclass_fields__ for field_name, field in fields.items(): name = field_name type_ = MethodDefinition.get_type(field) - default = MethodDefinition.get_default(field) + default = ( + None + if name == "provider" + else MethodDefinition.get_default(field) + ) new_type = TYPE_EXPANSION.get(name, ...) updated_type = type_ if new_type is ... else Union[type_, new_type] @@ -384,6 +385,15 @@ class MethodDefinition: code += " data = df_to_basemodel(data, data.index.name is not None)\n" code += "\n" + if "provider_choices" in parameter_map: + code += " if provider is None:\n" + code += " defaults = self._command_runner_session.user_settings.defaults.endpoints.get(\n" + code += f' "{path}",\n' + code += " None,\n" + code += " )\n" + code += ' provider = defaults.get("provider", None) if defaults else Parameter.empty\n' + code += "\n" + code += " o = self._command_runner_session.run(\n" code += f""" "{path}",\n"""