diff --git a/openbb_platform/core/openbb_core/app/assets/parameter_pool.json b/openbb_platform/core/openbb_core/app/assets/parameter_pool.json deleted file mode 100644 index 41b8af1d0f87..000000000000 --- a/openbb_platform/core/openbb_core/app/assets/parameter_pool.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "crypto": { - "symbol": "BTCUSD" - }, - "currency": { - "symbol": "EURUSD" - }, - "derivatives": { - "symbol": "AAPL" - }, - "economy": { - "country": "portugal", - "countries": ["portugal", "spain"] - }, - "economy.fred_series": { - "symbol": "GFDGDPA188S" - }, - "equity": { - "symbol": "AAPL", - "symbols": "AAPL,MSFT", - "query": "AAPL" - }, - "etf": { - "symbol": "SPY", - "query": "Vanguard" - }, - "futures": { - "symbol": "ES" - }, - "index": { - "symbol": "SPX", - "index": "^IBEX" - }, - "news": { - "symbol": "AAPL" - }, - "regulators": { - "symbol": "AAPL", - "query": "AAPL" - } -} diff --git a/openbb_platform/core/openbb_core/app/example_generator.py b/openbb_platform/core/openbb_core/app/example_generator.py deleted file mode 100644 index c661936621d6..000000000000 --- a/openbb_platform/core/openbb_core/app/example_generator.py +++ /dev/null @@ -1,83 +0,0 @@ -"""OpenBB Platform example generator.""" - -import json -from pathlib import Path -from typing import ( - Any, - Dict, -) - -from pydantic.fields import FieldInfo -from pydantic_core import PydanticUndefined - -from openbb_core.app.constants import ASSETS_DIRECTORY -from openbb_core.app.provider_interface import ProviderInterface - -try: - with Path(ASSETS_DIRECTORY, "parameter_pool.json").open() as f: - PARAMETER_POOL = json.load(f) -except Exception: - PARAMETER_POOL = {} - - -class ExampleGenerator: - """Generate examples for the API.""" - - @staticmethod - def _get_value_from_pool(pool: dict, route: str, param: str) -> str: - """Get the value from the pool. - - The example parameters can be defined for: - - route: "crypto.historical.price": {"symbol": "CRYPTO_HISTORICAL_PRICE_SYMBOL"} - - sub-router: "crypto.historical": {"symbol": "CRYPTO_HISTORICAL_SYMBOL"} - - router: "crypto": {"symbol": "CRYPTO_SYMBOL"} - - The search for the 'key' is done in the following order: - - route - - sub-router - - router - """ - parts = route.split(".") - for i in range(len(parts), 0, -1): - partial_route = ".".join(parts[:i]) - if partial_route in pool and param in pool[partial_route]: - return pool[partial_route][param] - return "VALUE_NOT_FOUND" - - @classmethod - def generate( - cls, - route: str, - model: str, - ) -> str: - """Generate the example for the command.""" - if not route or not model: - return "" - - standard_params: Dict[str, FieldInfo] = ( - ProviderInterface() - .map.get(model, {}) - .get("openbb", {}) - .get("QueryParams", {}) - .get("fields", {}) - ) - - eg_params: Dict[str, Any] = {} - for p, v in standard_params.items(): - if v.default is not None: - if v.default is not PydanticUndefined and v.default != "": - eg_params[p] = v.default - else: - eg_params[p] = cls._get_value_from_pool(PARAMETER_POOL, route, p) - - example = f"obb.{route}(" - for n, v in eg_params.items(): - if isinstance(v, str): - v = f'"{v}"' # noqa: PLW2901 - example += f"{n}={v}, " - if eg_params: - example = example[:-2] + ")" - else: - example += ")" - - return example diff --git a/openbb_platform/core/openbb_core/app/model/example.py b/openbb_platform/core/openbb_core/app/model/example.py new file mode 100644 index 000000000000..27f0e77084ac --- /dev/null +++ b/openbb_platform/core/openbb_core/app/model/example.py @@ -0,0 +1,229 @@ +"""Example class to represent endpoint examples.""" + +from abc import abstractmethod +from datetime import date, datetime, timedelta +from typing import Any, Dict, List, Literal, Optional, Union, _GenericAlias + +from pydantic import ( + BaseModel, + ConfigDict, + Field, + computed_field, + model_validator, +) + +QUOTE_TYPES = {str, date} + + +class Example(BaseModel): + """Example model.""" + + scope: str + + model_config = ConfigDict(validate_assignment=True) + + @abstractmethod + def to_python(self, **kwargs) -> str: + """Return a Python code representation of the example.""" + + +class APIEx(Example): + """API Example model.""" + + scope: Literal["api"] = "api" + description: Optional[str] = Field( + default=None, description="Optional description unless more than 3 parameters" + ) + parameters: Dict[str, Union[str, int, float, bool, List[str], List[Dict[str, Any]]]] + + @computed_field # type: ignore[misc] + @property + def provider(self) -> Optional[str]: + """Return the provider from the parameters.""" + return self.parameters.get("provider") # type: ignore + + @model_validator(mode="before") + @classmethod + def validate_model(cls, values: dict) -> dict: + """Validate model.""" + parameters = values.get("parameters", {}) + if "provider" not in parameters and "data" not in parameters: + raise ValueError("API example must specify a provider.") + + provider = parameters.get("provider") + if provider and not isinstance(provider, str): + raise ValueError("Provider must be a string.") + + return values + + @staticmethod + def _unpack_type(type_: type) -> set: + """Unpack types from types, example Union[List[str], int] -> {str, int}.""" + if ( + hasattr(type_, "__args__") + and type(type_) # pylint: disable=unidiomatic-typecheck + is not _GenericAlias + ): + return set().union(*map(APIEx._unpack_type, type_.__args__)) + return {type_} if isinstance(type_, type) else {type(type_)} + + @staticmethod + def _shift(i: int) -> float: + """Return a transformation of the integer.""" + return 2 * (i + 1) / (2 * i) % 1 + 1 + + @staticmethod + def mock_data( + dataset: Literal["timeseries", "panel"], + size: int = 5, + sample: Optional[Dict[str, Any]] = None, + multiindex: Optional[Dict[str, Any]] = None, + ) -> List[Dict]: + """Generate mock data from a sample. + + Parameters + ---------- + dataset : str + The type of data to return: + - 'timeseries': Time series data + - 'panel': Panel data (multiindex) + + size : int + The size of the data to return, default is 5. + sample : Optional[Dict[str, Any]], optional + A sample of the data to return, by default None. + multiindex_names : Optional[List[str]], optional + The names of the multiindex, by default None. + + Timeseries default sample: + { + "date": "2023-01-01", + "open": 110.0, + "high": 120.0, + "low": 100.0, + "close": 115.0, + "volume": 10000, + } + + Panel default sample: + { + "portfolio_value": 100000, + "risk_free_rate": 0.02, + } + multiindex: {"asset_manager": "AM", "time": 0} + + Returns + ------- + List[Dict] + A list of dictionaries with the mock data. + """ + if dataset == "timeseries": + sample = sample or { + "date": "2023-01-01", + "open": 110.0, + "high": 120.0, + "low": 100.0, + "close": 115.0, + "volume": 10000, + } + result = [] + for i in range(1, size + 1): + s = APIEx._shift(i) + obs = {} + for k, v in sample.items(): + if k == "date": + obs[k] = ( + datetime.strptime(v, "%Y-%m-%d") + timedelta(days=i) + ).strftime("%Y-%m-%d") + else: + obs[k] = round(v * s, 2) + result.append(obs) + return result + if dataset == "panel": + sample = sample or { + "portfolio_value": 100000.0, + "risk_free_rate": 0.02, + } + multiindex = multiindex or {"asset_manager": "AM", "time": 0} + multiindex_names = list(multiindex.keys()) + idx_1 = multiindex_names[0] + idx_2 = multiindex_names[1] + items_per_idx = 2 + item: Dict[str, Any] = { + "is_multiindex": True, + "multiindex_names": str(multiindex_names), + } + # Iterate over the number of items to create and add them to the result + result = [] + for i in range(1, size + 1): + item[idx_1] = f"{idx_1}_{i}" + for j in range(items_per_idx): + item[idx_2] = j + for k, v in sample.items(): + if isinstance(v, str): + item[k] = f"{v}_{j}" + else: + item[k] = round(v * APIEx._shift(i + j), 2) + result.append(item.copy()) + return result + raise ValueError(f"Dataset '{dataset}' not found.") + + def to_python(self, **kwargs) -> str: + """Return a Python code representation of the example.""" + indentation = kwargs.get("indentation", "") + func_path = kwargs.get("func_path", ".func_router.func_name") + param_types: Dict[str, type] = kwargs.get("param_types", {}) + prompt = kwargs.get("prompt", "") + + eg = "" + if self.description: + eg += f"{indentation}{prompt}# {self.description}\n" + + eg += f"{indentation}{prompt}obb{func_path}(" + for k, v in self.parameters.items(): + if k in param_types and (type_ := param_types.get(k)): + if QUOTE_TYPES.intersection(self._unpack_type(type_)): + eg += f"{k}='{v}', " + else: + eg += f"{k}={v}, " + else: + eg += f"{k}={v}, " + + eg = indentation + eg.strip(", ") + ")\n" + + return eg + + +class PythonEx(Example): + """Python Example model.""" + + scope: Literal["python"] = "python" + description: str + code: List[str] + + def to_python(self, **kwargs) -> str: + """Return a Python code representation of the example.""" + indentation = kwargs.get("indentation", "") + prompt = kwargs.get("prompt", "") + + eg = "" + if self.description: + eg += f"{indentation}{prompt}# {self.description}\n" + + for line in self.code: + eg += f"{indentation}{prompt}{line}\n" + + return eg + + +def filter_list( + examples: List[Example], + providers: List[str], +) -> List[Example]: + """Filter list of examples.""" + return [ + e + for e in examples + if (isinstance(e, APIEx) and (not e.provider or e.provider in providers)) + or e.scope != "api" + ] diff --git a/openbb_platform/core/openbb_core/app/model/metadata.py b/openbb_platform/core/openbb_core/app/model/metadata.py index 27a6b8eb0dfa..e5ea6a0f5bf2 100644 --- a/openbb_platform/core/openbb_core/app/model/metadata.py +++ b/openbb_platform/core/openbb_core/app/model/metadata.py @@ -42,12 +42,12 @@ def scale_arguments(cls, v): if isclass(type(arg_val)) and issubclass(type(arg_val), Data): new_arg_val = { "type": f"{type(arg_val).__name__}", - "columns": list(arg_val.dict().keys()), + "columns": list(arg_val.model_dump().keys()), } # List[Data] if isinstance(arg_val, list) and issubclass(type(arg_val[0]), Data): - columns = [list(d.dict().keys()) for d in arg_val] + columns = [list(d.model_dump().keys()) for d in arg_val] columns = (item for sublist in columns for item in sublist) # flatten new_arg_val = { "type": f"List[{type(arg_val[0]).__name__}]", diff --git a/openbb_platform/core/openbb_core/app/router.py b/openbb_platform/core/openbb_core/app/router.py index 038697fdd83b..3968d5892a03 100644 --- a/openbb_platform/core/openbb_core/app/router.py +++ b/openbb_platform/core/openbb_core/app/router.py @@ -25,10 +25,10 @@ from typing_extensions import Annotated, ParamSpec, _AnnotatedAlias from openbb_core.app.deprecation import DeprecationSummary, OpenBBDeprecationWarning -from openbb_core.app.example_generator import ExampleGenerator from openbb_core.app.extension_loader import ExtensionLoader from openbb_core.app.model.abstract.warning import OpenBBWarning from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import filter_list from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -233,23 +233,16 @@ def command( api_router = self._api_router model = kwargs.pop("model", "") - examples = kwargs.pop("examples", []) - exclude_auto_examples = kwargs.pop("exclude_auto_examples", False) if func := SignatureInspector.complete(func, model): - if not exclude_auto_examples: - examples.insert( - 0, - ExampleGenerator.generate( - route=SignatureInspector.get_operation_id(func, sep="."), - model=model, - ), - ) kwargs["response_model_exclude_unset"] = True kwargs["openapi_extra"] = kwargs.get("openapi_extra", {}) kwargs["openapi_extra"]["model"] = model - kwargs["openapi_extra"]["examples"] = examples + kwargs["openapi_extra"]["examples"] = filter_list( + examples=kwargs.pop("examples", []), + providers=ProviderInterface().available_providers, + ) kwargs["operation_id"] = kwargs.get( "operation_id", SignatureInspector.get_operation_id(func) ) @@ -486,7 +479,7 @@ def get_description(func: Callable) -> str: if doc: description = doc.split(" Parameters\n ----------")[0] description = description.split(" Returns\n -------")[0] - description = description.split(" Example\n -------")[0] + description = description.split(" Examples\n -------")[0] description = "\n".join([line.strip() for line in description.split("\n")]) return description diff --git a/openbb_platform/core/openbb_core/app/static/package_builder.py b/openbb_platform/core/openbb_core/app/static/package_builder.py index a64c0fd1fd2e..b6e08c836969 100644 --- a/openbb_platform/core/openbb_core/app/static/package_builder.py +++ b/openbb_platform/core/openbb_core/app/static/package_builder.py @@ -10,7 +10,6 @@ from json import dumps, load from pathlib import Path from typing import ( - Any, Callable, Dict, List, @@ -23,7 +22,6 @@ TypeVar, Union, get_args, - get_origin, get_type_hints, ) @@ -40,8 +38,9 @@ OpenBBCustomChoices, OpenBBCustomParameter, ) +from openbb_core.app.model.example import Example from openbb_core.app.provider_interface import ProviderInterface -from openbb_core.app.router import CommandMap, RouterLoader +from openbb_core.app.router import RouterLoader from openbb_core.app.static.utils.console import Console from openbb_core.app.static.utils.linters import Linters from openbb_core.env import Env @@ -66,6 +65,13 @@ Data, ) +TAB = " " + + +def create_indent(n: int) -> str: + """Create n indentation space.""" + return TAB * n + class PackageBuilder: """Build the extension package for the Platform.""" @@ -405,8 +411,8 @@ def build(path: str, ext_map: Optional[Dict[str, List[str]]] = None) -> str: if route.openapi_extra else None ), - examples=route.openapi_extra.get("examples", None), - ) # type: ignore + examples=(route.openapi_extra.get("examples", []) or []), + ) else: doc += " /" if path else " /" doc += c.split("/")[-1] + "\n" @@ -550,9 +556,6 @@ def format_params( path: str, parameter_map: Dict[str, Parameter] ) -> OrderedDict[str, Parameter]: """Format the params.""" - DEFAULT_REPLACEMENT = { - "provider": None, - } parameter_map.pop("cc", None) # we need to add the chart parameter here bc of the docstring generation @@ -560,7 +563,12 @@ def format_params( parameter_map["chart"] = Parameter( name="chart", kind=Parameter.POSITIONAL_OR_KEYWORD, - annotation=bool, + annotation=Annotated[ + bool, + OpenBBCustomParameter( + description="Whether to create a chart or not, by default False." + ), + ], default=False, ) @@ -569,6 +577,28 @@ def format_params( for name, param in parameter_map.items(): if name == "extra_params": formatted[name] = Parameter(name="kwargs", kind=Parameter.VAR_KEYWORD) + elif name == "provider_choices": + fields = param.annotation.__args__[0].__dataclass_fields__ + field = fields["provider"] + type_ = getattr(field, "type") + args = getattr(type_, "__args__") + first = args[0] if args else None + formatted["provider"] = Parameter( + name="provider", + kind=Parameter.POSITIONAL_OR_KEYWORD, + annotation=Annotated[ + Union[MethodDefinition.get_type(field), None], + OpenBBCustomParameter( + description=( + "The provider to use for the query, by default None.\n" + f" If None, the provider specified in defaults is selected or '{first}' if there is\n" + " no default." + "" + ) + ), + ], + default=None, + ) elif MethodDefinition.is_annotated_dc(param.annotation): fields = param.annotation.__args__[0].__dataclass_fields__ for field_name, field in fields.items(): @@ -584,7 +614,7 @@ def format_params( name=field_name, kind=Parameter.POSITIONAL_OR_KEYWORD, annotation=updated_type, - default=DEFAULT_REPLACEMENT.get(field_name, default), + default=default, ) else: new_type = MethodDefinition.get_expanded_type(name) @@ -602,7 +632,7 @@ def format_params( name=name, kind=Parameter.POSITIONAL_OR_KEYWORD, annotation=updated_type, - default=DEFAULT_REPLACEMENT.get(name, param.default), + default=param.default, ) return MethodDefinition.reorder_params(params=formatted) @@ -719,20 +749,26 @@ def build_command_method_signature( @staticmethod def build_command_method_doc( + path: str, func: Callable, formatted_params: OrderedDict[str, Parameter], model_name: Optional[str] = None, - examples: Optional[List[str]] = None, + examples: Optional[List[Example]] = None, ): """Build the command method docstring.""" doc = func.__doc__ doc = DocstringGenerator.generate( + path=path, func=func, formatted_params=formatted_params, model_name=model_name, examples=examples, ) - code = f' """{doc} """ # noqa: E501\n\n' if doc else "" + code = ( + f'{create_indent(2)}"""{doc}{create_indent(2)}""" # noqa: E501\n\n' + if doc + else "" + ) return code @@ -770,9 +806,9 @@ def build_command_method_body(path: str, func: Callable): available = field.type.__args__ code += " provider_choices={\n" code += ' "provider": self._get_provider(\n' - code += " provider,\n" - code += f' "{path}",\n' - code += f" {available},\n" + code += " provider,\n" + code += f' "{path}",\n' + code += f" {available},\n" code += " )\n" code += " },\n" elif MethodDefinition.is_annotated_dc(param.annotation): @@ -812,7 +848,7 @@ def get_expanded_type( raise ValueError( "multiple_items_allowed requires the original type to be specified." ) - return List[original_type] + return List[original_type] # type: ignore return cls.TYPE_EXPANSION.get(field_name, ...) @classmethod @@ -821,7 +857,7 @@ def build_command_method( path: str, func: Callable, model_name: Optional[str] = None, - examples: Optional[List[str]] = None, + examples: Optional[List[Example]] = None, ) -> str: """Build the command method.""" func_name = func.__name__ @@ -839,6 +875,7 @@ def build_command_method( model_name=model_name, ) code += cls.build_command_method_doc( + path=path, func=func, formatted_params=formatted_params, model_name=model_name, @@ -856,37 +893,114 @@ class DocstringGenerator: provider_interface = ProviderInterface() @staticmethod - def get_OBBject_description(results_type: str, providers: Optional[str]) -> str: + def get_field_type( + field: FieldInfo, target: Literal["docstring", "website"] = "docstring" + ) -> str: + """Get the implicit data type of a defined Pydantic field. + + Args + ---- + field (FieldInfo): Pydantic field object containing field information. + target (Literal["docstring", "website"], optional): Target to return type for. Defaults to "docstring". + + Returns + ------- + str: String representation of the field type. + """ + is_optional = not field.is_required() if target == "docstring" else False + + try: + _type = field.annotation + + if "BeforeValidator" in str(_type): + _type = "Optional[int]" if is_optional else "int" # type: ignore + + field_type = ( + str(_type) + .replace("", "") + .replace("typing.", "") + .replace("pydantic.types.", "") + .replace("datetime.datetime", "datetime") + .replace("datetime.date", "date") + .replace("NoneType", "None") + .replace(", None", "") + ) + field_type = ( + f"Optional[{field_type}]" + if is_optional and "Optional" not in str(_type) + else field_type + ) + except TypeError: + # Fallback to the annotation if the repr fails + field_type = field.annotation # type: ignore + + return field_type + + @staticmethod + def get_OBBject_description( + results_type: str, + providers: Optional[str], + ) -> str: """Get the command output description.""" available_providers = providers or "Optional[str]" obbject_description = ( - " OBBject\n" - f" results : {results_type}\n" - " Serializable results.\n" - f" provider : {available_providers}\n" - " Provider name.\n" - " warnings : Optional[List[Warning_]]\n" - " List of warnings.\n" - " chart : Optional[Chart]\n" - " Chart object.\n" - " extra : Dict[str, Any]\n" - " Extra info.\n" + f"{create_indent(2)}OBBject\n" + f"{create_indent(3)}results : {results_type}\n" + f"{create_indent(4)}Serializable results.\n" + f"{create_indent(3)}provider : {available_providers}\n" + f"{create_indent(4)}Provider name.\n" + f"{create_indent(3)}warnings : Optional[List[Warning_]]\n" + f"{create_indent(4)}List of warnings.\n" + f"{create_indent(3)}chart : Optional[Chart]\n" + f"{create_indent(4)}Chart object.\n" + f"{create_indent(3)}extra : Dict[str, Any]\n" + f"{create_indent(4)}Extra info.\n" ) obbject_description = obbject_description.replace("NoneType", "None") return obbject_description + @staticmethod + def build_examples( + func_path: str, + param_types: Dict[str, type], + examples: Optional[List[Example]], + target: Literal["docstring", "website"] = "docstring", + ) -> str: + """Get the example section from the examples.""" + if examples: + if target == "docstring": + prompt = ">>> " + indent = create_indent(2) + else: + prompt = "\n```python\n" + indent = create_indent(0) + + doc = f"\n{indent}Examples\n" + doc += f"{indent}--------\n" + doc += f"{indent}{prompt}from openbb import obb\n" + + for e in examples: + doc += e.to_python( + func_path=func_path, + param_types=param_types, + indentation=indent, + prompt=">>> " if target == "docstring" else "", + ) + return doc if target == "docstring" else doc + "```\n\n" + return "" + @classmethod def generate_model_docstring( cls, model_name: str, summary: str, explicit_params: dict, - params: dict, + kwarg_params: dict, returns: Dict[str, FieldInfo], results_type: str, - examples: Optional[List[str]] = None, ) -> str: """Create the docstring for model.""" @@ -902,260 +1016,121 @@ def format_type(type_: str, char_limit: Optional[int] = None) -> str: def format_description(description: str) -> str: """Format description in docstrings.""" - description = description.replace("\n", "\n ") + description = description.replace("\n", f"\n{create_indent(2)}") return description - standard_dict = params["standard"].__dataclass_fields__ - extra_dict = params["extra"].__dataclass_fields__ - - if examples: - example_docstring = "\n Example\n -------\n" - example_docstring += " >>> from openbb import obb\n" - for example in examples: - example_docstring += f" >>> {example}\n" + def get_param_info(parameter: Parameter) -> Tuple[str, str]: + """Get the parameter info.""" + annotation = getattr(parameter, "_annotation", None) + if isinstance(annotation, _AnnotatedAlias): + args = getattr(annotation, "__args__", []) if annotation else [] + p_type = args[0] if args else None + else: + p_type = annotation + type_ = ( + getattr(p_type, "__name__", "") if inspect.isclass(p_type) else p_type + ) + metadata = getattr(annotation, "__metadata__", []) + description = getattr(metadata[0], "description", "") if metadata else "" + return type_, description - docstring = summary.strip("\n") + docstring = summary.strip("\n").replace("\n ", f"\n{create_indent(2)}") docstring += "\n\n" - docstring += " Parameters\n" - docstring += " ----------\n" + docstring += f"{create_indent(2)}Parameters\n" + docstring += f"{create_indent(2)}----------\n" # Explicit parameters for param_name, param in explicit_params.items(): - if param_name in standard_dict: - # pylint: disable=W0212 - p_type = param._annotation.__args__[0] - type_ = p_type.__name__ if inspect.isclass(p_type) else p_type - description = getattr( - param._annotation.__metadata__[0], "description", "" - ) - elif param_name == "provider": - # pylint: disable=W0212 - type_ = param._annotation - default = param._annotation.__args__[0].__args__[0] - description = f"""The provider to use for the query, by default None. - If None, the provider specified in defaults is selected or '{default}' if there is - no default.""" - elif param_name == "chart": - type_ = "bool" - description = "Whether to create a chart or not, by default False." - else: - type_ = "" - description = "" - - type_str = format_type(type_, char_limit=79) # type: ignore - docstring += f" {param_name} : {type_str}\n" - docstring += f" {format_description(description)}\n" + type_, description = get_param_info(param) + type_str = format_type(str(type_), char_limit=79) + docstring += f"{create_indent(2)}{param_name} : {type_str}\n" + docstring += f"{create_indent(3)}{format_description(description)}\n" # Kwargs - for param_name, param in extra_dict.items(): - p_type = param.type - type_ = p_type.__name__ if inspect.isclass(p_type) else p_type + for param_name, param in kwarg_params.items(): + p_type = getattr(param, "type", "") + type_ = ( + getattr(p_type, "__name__", "") if inspect.isclass(p_type) else p_type + ) if "NoneType" in str(type_): type_ = f"Optional[{type_}]".replace(", NoneType", "") - description = getattr(param.default, "description", "") - - docstring += f" {param_name} : {type_}\n" - docstring += f" {format_description(description)}\n" + default = getattr(param, "default", "") + description = getattr(default, "description", "") + docstring += f"{create_indent(2)}{param_name} : {type_}\n" + docstring += f"{create_indent(3)}{format_description(description)}\n" # Returns docstring += "\n" - docstring += " Returns\n" - docstring += " -------\n" - provider_param = explicit_params.get("provider", None) - available_providers = getattr(provider_param, "_annotation", None) - - docstring += cls.get_OBBject_description(results_type, available_providers) + docstring += f"{create_indent(2)}Returns\n" + docstring += f"{create_indent(2)}-------\n" + providers, _ = get_param_info(explicit_params.get("provider", None)) + docstring += cls.get_OBBject_description(results_type, providers) # Schema underline = "-" * len(model_name) - docstring += f"\n {model_name}\n {underline}\n" + docstring += f"\n{create_indent(2)}{model_name}\n" + docstring += f"{create_indent(2)}{underline}\n" for name, field in returns.items(): - try: - _type = field.annotation - is_optional = not field.is_required() - if "BeforeValidator" in str(_type): - _type = "Optional[int]" if is_optional else "int" # type: ignore - - field_type = ( - str(_type) - .replace("", "") - .replace("typing.", "") - .replace("pydantic.types.", "") - .replace("datetime.datetime", "datetime") - .replace("datetime.date", "date") - .replace("NoneType", "None") - .replace(", None", "") - ) - field_type = ( - f"Optional[{field_type}]" - if is_optional and "Optional" not in str(_type) - else field_type - ) - except TypeError: - # Fallback to the annotation if the repr fails - field_type = field.annotation # type: ignore - + field_type = cls.get_field_type(field) description = getattr(field, "description", "") - - docstring += f" {field.alias or name} : {field_type}\n" - docstring += f" {format_description(description)}\n" - - if examples: - docstring += example_docstring - + docstring += f"{create_indent(2)}{field.alias or name} : {field_type}\n" + docstring += f"{create_indent(3)}{format_description(description)}\n" return docstring @classmethod def generate( cls, + path: str, func: Callable, formatted_params: OrderedDict[str, Parameter], model_name: Optional[str] = None, - examples: Optional[List[str]] = None, + examples: Optional[List[Example]] = None, ) -> Optional[str]: """Generate the docstring for the function.""" - doc = func.__doc__ + doc = func.__doc__ or "" + param_types = {} + + # Parameters explicit in the function signature + explicit_params = dict(formatted_params) + explicit_params.pop("extra_params", None) + # Map of parameter names to types + param_types = {k: v.annotation for k, v in explicit_params.items()} + if model_name: - params = cls.provider_interface.params.get(model_name, None) + params = cls.provider_interface.params.get(model_name, {}) return_schema = cls.provider_interface.return_schema.get(model_name, None) if params and return_schema: - explicit_dict = dict(formatted_params) - explicit_dict.pop("extra_params", None) + # Parameters passed as **kwargs + kwarg_params = params["extra"].__dataclass_fields__ + param_types.update({k: v.type for k, v in kwarg_params.items()}) returns = return_schema.model_fields results_type = func.__annotations__.get("return", model_name) if hasattr(results_type, "results_type_repr"): results_type = results_type.results_type_repr() - return cls.generate_model_docstring( + doc = cls.generate_model_docstring( model_name=model_name, summary=func.__doc__ or "", - explicit_params=explicit_dict, - params=params, + explicit_params=explicit_params, + kwarg_params=kwarg_params, returns=returns, results_type=results_type, - examples=examples, ) - return doc - if examples and examples != [""] and doc: - doc += "\n Examples\n --------\n" - doc += " >>> from openbb import obb\n" - for example in examples: - if example != "": - doc += f" >>> {example}\n" - return doc - - @staticmethod - def get_model_standard_params(param_fields: Dict[str, FieldInfo]) -> Dict[str, Any]: - """Get the test params for the fetcher based on the required standard params.""" - test_params: Dict[str, Any] = {} - for field_name, field in param_fields.items(): - if field.default and field.default is not PydanticUndefined: - test_params[field_name] = field.default - elif field.default and field.default is PydanticUndefined: - example_dict = { - "symbol": "AAPL", - "symbols": "AAPL,MSFT", - "start_date": "2023-01-01", - "end_date": "2023-06-06", - "country": "Portugal", - "date": "2023-01-01", - "countries": ["portugal", "spain"], - } - if field_name in example_dict: - test_params[field_name] = example_dict[field_name] - elif field.annotation == str: - test_params[field_name] = "TEST_STRING" - elif field.annotation == int: - test_params[field_name] = 1 - elif field.annotation == float: - test_params[field_name] = 1.0 - elif field.annotation == bool: - test_params[field_name] = True - elif get_origin(field.annotation) is Literal: # type: ignore - option = field.annotation.__args__[0] # type: ignore - if isinstance(option, str): - test_params[field_name] = f'"{option}"' - else: - test_params[field_name] = option - - return test_params - - @staticmethod - def get_full_command_name(route: str) -> str: - """Get the full command name.""" - cmd_parts = route.split("/") - del cmd_parts[0] - - menu = cmd_parts[0] - command = cmd_parts[-1] - sub_menus = cmd_parts[1:-1] - - sub_menu_str_cmd = f".{'.'.join(sub_menus)}" if sub_menus else "" - - full_command = f"{menu}{sub_menu_str_cmd}.{command}" - - return full_command - - @classmethod - def generate_example( - cls, - model_name: str, - standard_params: Dict[str, FieldInfo], - ) -> str: - """Generate the example for the command.""" - # find the model router here - cm = CommandMap() - commands_model = cm.commands_model - route = [k for k, v in commands_model.items() if v == model_name] - - if not route: - return "" - - full_command_name = cls.get_full_command_name(route=route[0]) - example_params = cls.get_model_standard_params(param_fields=standard_params) - - # Edge cases (might find more) - if "crypto" in route[0] and "symbol" in example_params: - example_params["symbol"] = "BTCUSD" - elif "currency" in route[0] and "symbol" in example_params: - example_params["symbol"] = "EURUSD" - elif ( - "index" in route[0] - and "european" not in route[0] - and "symbol" in example_params - ): - example_params["symbol"] = "SPX" - elif ( - "index" in route[0] - and "european" in route[0] - and "symbol" in example_params - ): - example_params["symbol"] = "BUKBUS" - elif ( - "futures" in route[0] and "curve" in route[0] and "symbol" in example_params - ): - example_params["symbol"] = "VX" - elif "futures" in route[0] and "symbol" in example_params: - example_params["symbol"] = "ES" - - example = "\n Example\n -------\n" - example += " >>> from openbb import obb\n" - example += f" >>> obb.{full_command_name}(" - for param_name, param_value in example_params.items(): - if isinstance(param_value, str): - param_value = f'"{param_value}"' # noqa: PLW2901 - example += f"{param_name}={param_value}, " - if example_params: - example = example[:-2] + ")\n" else: - example += ")\n" + doc = doc.replace("\n ", f"\n{create_indent(2)}") + + if doc and examples: + doc += cls.build_examples( + path.replace("/", "."), + param_types, + examples, + ) - return example + return doc class PathHandler: diff --git a/openbb_platform/core/openbb_core/app/static/utils/decorators.py b/openbb_platform/core/openbb_core/app/static/utils/decorators.py index 0d44b87427c9..37b0291f404f 100644 --- a/openbb_platform/core/openbb_core/app/static/utils/decorators.py +++ b/openbb_platform/core/openbb_core/app/static/utils/decorators.py @@ -65,7 +65,7 @@ def wrapper(*f_args, **f_kwargs): arg = ".".join(map(str, error["loc"])) arg_error = f"Arg {arg} ->\n" error_details = ( - f" {error['msg']} " + f"{error['msg']} " f"[validation_error_type={error['type']}, " f"input_type={type(error['input']).__name__}, " f"input_value={error['input']}]\n" diff --git a/openbb_platform/core/openbb_core/provider/abstract/query_params.py b/openbb_platform/core/openbb_core/provider/abstract/query_params.py index 09714e3565a1..acca98737678 100644 --- a/openbb_platform/core/openbb_core/provider/abstract/query_params.py +++ b/openbb_platform/core/openbb_core/provider/abstract/query_params.py @@ -14,7 +14,9 @@ class QueryParams(BaseModel): Key Features: - Alias handling: Utilizes an aliasing mechanism to maintain compatibility with different naming conventions across various data formats. The alias is only applied when running `model_dump`. - - Json schema extra merging: Merge different json schema extra, identified by provider. + - Json schema extra merging: + + Merge different json schema extra, identified by provider. Example: FMP fetcher: __json_schema_extra__ = {"symbol": ["multiple_items_allowed"]} @@ -28,6 +30,13 @@ class QueryParams(BaseModel): ..., } + Multiple fields can be tagged with the same or multiple properties. + Example: + __json_schema_extra__ = { + "": ["some_prop", "another_prop"], + "": ["yet_another_prop"] + } + Attributes: __alias_dict__ (Dict[str, str]): A dictionary that maps field names to their aliases, diff --git a/openbb_platform/core/openbb_core/provider/standard_models/equity_short_interest.py b/openbb_platform/core/openbb_core/provider/standard_models/equity_short_interest.py index 7f841a5849f8..8d1ef4b34a2c 100644 --- a/openbb_platform/core/openbb_core/provider/standard_models/equity_short_interest.py +++ b/openbb_platform/core/openbb_core/provider/standard_models/equity_short_interest.py @@ -15,10 +15,7 @@ class ShortInterestQueryParams(QueryParams): """Equity Short Interest Query.""" - symbol: str = Field( - description=QUERY_DESCRIPTIONS.get("symbol", ""), - default=None, - ) + symbol: str = Field(description=QUERY_DESCRIPTIONS.get("symbol", "")) class ShortInterestData(Data): diff --git a/openbb_platform/core/openbb_core/provider/standard_models/short_volume.py b/openbb_platform/core/openbb_core/provider/standard_models/short_volume.py index d836e186085b..020f819da157 100644 --- a/openbb_platform/core/openbb_core/provider/standard_models/short_volume.py +++ b/openbb_platform/core/openbb_core/provider/standard_models/short_volume.py @@ -16,7 +16,7 @@ class ShortVolumeQueryParams(QueryParams): """Short Volume Query.""" - symbol: str = Field(default=None, description=QUERY_DESCRIPTIONS.get("symbol")) + symbol: str = Field(description=QUERY_DESCRIPTIONS.get("symbol")) class ShortVolumeData(Data): diff --git a/openbb_platform/core/openbb_core/provider/standard_models/symbol_map.py b/openbb_platform/core/openbb_core/provider/standard_models/symbol_map.py new file mode 100644 index 000000000000..b47d43827672 --- /dev/null +++ b/openbb_platform/core/openbb_core/provider/standard_models/symbol_map.py @@ -0,0 +1,17 @@ +"""Commitment of Traders Reports Search Standard Model.""" + +from typing import Optional + +from pydantic import Field + +from openbb_core.provider.abstract.query_params import QueryParams + + +class SymbolMapQueryParams(QueryParams): + """Commitment of Traders Reports Search Query.""" + + query: str = Field(description="Search query.") + use_cache: Optional[bool] = Field( + default=True, + description="Whether or not to use cache. If True, cache will store for seven days.", + ) diff --git a/openbb_platform/core/openbb_core/provider/standard_models/trailing_dividend_yield.py b/openbb_platform/core/openbb_core/provider/standard_models/trailing_dividend_yield.py index 473d276d5e65..b3aa8ebed660 100644 --- a/openbb_platform/core/openbb_core/provider/standard_models/trailing_dividend_yield.py +++ b/openbb_platform/core/openbb_core/provider/standard_models/trailing_dividend_yield.py @@ -16,9 +16,7 @@ class TrailingDivYieldQueryParams(QueryParams): """Trailing Dividend Yield Query.""" - symbol: Optional[str] = Field( - default=None, description=QUERY_DESCRIPTIONS.get("symbol", "") - ) + symbol: str = Field(description=QUERY_DESCRIPTIONS.get("symbol", "")) limit: Optional[int] = Field( default=252, description=f"{QUERY_DESCRIPTIONS.get('limit', '')}" diff --git a/openbb_platform/core/tests/app/static/test_example_generator.py b/openbb_platform/core/tests/app/static/test_example_generator.py deleted file mode 100644 index 86029fabe13f..000000000000 --- a/openbb_platform/core/tests/app/static/test_example_generator.py +++ /dev/null @@ -1,59 +0,0 @@ -"""Test the example_generator.py file.""" - -# pylint: disable=redefined-outer-name, protected-access - - -import pytest -from openbb_core.app.example_generator import ExampleGenerator - - -@pytest.fixture(scope="module") -def example_generator(): - """Return example generator.""" - return ExampleGenerator() - - -def test_docstring_generator_init(example_generator): - """Test example generator init.""" - assert example_generator - - -TEST_POOL = { - "crypto": {"symbol": "CRYPTO_SYMBOL"}, - "crypto.search": {"symbol": "CRYPTO_SEARCH_SYMBOL"}, - "crypto.price.historical": {"symbol": "CRYPTO_HISTORICAL_PRICE_SYMBOL"}, -} - - -@pytest.mark.parametrize( - "route, param, expected", - [ - ("", "", "VALUE_NOT_FOUND"), - ("random_route", "", "VALUE_NOT_FOUND"), - ("crypto", "symbol", "CRYPTO_SYMBOL"), - ("crypto.search", "symbol", "CRYPTO_SEARCH_SYMBOL"), - ("crypto.price.historical", "symbol", "CRYPTO_HISTORICAL_PRICE_SYMBOL"), - ("crypto.price.historical", "random_param", "VALUE_NOT_FOUND"), - ], -) -def test_get_value_from_pool(example_generator, route, param, expected): - """Test get value from pool.""" - assert example_generator._get_value_from_pool(TEST_POOL, route, param) == expected - - -@pytest.mark.parametrize( - "route, model, expected", - [ - ("", "", ""), - ("random", "test", "obb.random()"), - ("crypto.search", "CryptoSearch", "obb.crypto.search()"), - ( - "crypto.price.historical", - "CryptoHistorical", - 'obb.crypto.price.historical(symbol="BTCUSD")', - ), - ], -) -def test_generate(example_generator, route, model, expected): - """Test generate example.""" - assert example_generator.generate(route, model) == expected diff --git a/openbb_platform/core/tests/app/static/test_package_builder.py b/openbb_platform/core/tests/app/static/test_package_builder.py index 9057c932bcc8..eb1fe3a1d2e2 100644 --- a/openbb_platform/core/tests/app/static/test_package_builder.py +++ b/openbb_platform/core/tests/app/static/test_package_builder.py @@ -311,7 +311,7 @@ def some_func(): } output = method_definition.build_command_method_doc( - func=some_func, formatted_params=formatted_params + path="/menu/submenu/command", func=some_func, formatted_params=formatted_params ) assert output assert isinstance(output, str) @@ -499,7 +499,7 @@ def test_generate_model_docstring(docstring_generator): summary = "This is a summary." pi = docstring_generator.provider_interface - params = pi.params[model_name] + kwarg_params = pi.params[model_name]["extra"].__dataclass_fields__ return_schema = pi.return_schema[model_name] returns = return_schema.model_fields @@ -513,7 +513,7 @@ def test_generate_model_docstring(docstring_generator): model_name=model_name, summary=summary, explicit_params=explicit_dict, - params=params, + kwarg_params=kwarg_params, returns=returns, results_type="List[WorldNews]", ) @@ -537,7 +537,10 @@ def some_func(): } doc = docstring_generator.generate( - func=some_func, formatted_params=formatted_params, model_name="WorldNews" + path="/menu/submenu/command", + func=some_func, + formatted_params=formatted_params, + model_name="WorldNews", ) assert doc assert "Parameters" in doc diff --git a/openbb_platform/extensions/commodity/openbb_commodity/commodity_router.py b/openbb_platform/extensions/commodity/openbb_commodity/commodity_router.py index 6d9a7e63b86d..ebf5401c28f7 100644 --- a/openbb_platform/extensions/commodity/openbb_commodity/commodity_router.py +++ b/openbb_platform/extensions/commodity/openbb_commodity/commodity_router.py @@ -1,6 +1,7 @@ """The Commodity router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -15,7 +16,23 @@ # pylint: disable=unused-argument -@router.command(model="LbmaFixing") +@router.command( + model="LbmaFixing", + examples=[ + APIEx(parameters={"provider": "nasdaq"}), + APIEx( + description="Get the daily LBMA fixing prices for silver in 2023.", + parameters={ + "asset": "silver", + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "transform": "rdiff", + "collapse": "monthly", + "provider": "nasdaq", + }, + ), + ], +) async def lbma_fixing( cc: CommandContext, provider_choices: ProviderChoices, diff --git a/openbb_platform/extensions/crypto/openbb_crypto/crypto_router.py b/openbb_platform/extensions/crypto/openbb_crypto/crypto_router.py index e4f6d24ed317..1f92af05c972 100644 --- a/openbb_platform/extensions/crypto/openbb_crypto/crypto_router.py +++ b/openbb_platform/extensions/crypto/openbb_crypto/crypto_router.py @@ -1,6 +1,7 @@ """Crypto Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -19,7 +20,10 @@ # pylint: disable=unused-argument @router.command( model="CryptoSearch", - examples=['obb.crypto.search("BTCUSD")', 'obb.crypto.search("ETH-USD")'], + examples=[ + APIEx(parameters={"provider": "fmp"}), + APIEx(parameters={"query": "BTCUSD", "provider": "fmp"}), + ], ) async def search( cc: CommandContext, diff --git a/openbb_platform/extensions/crypto/openbb_crypto/price/price_router.py b/openbb_platform/extensions/crypto/openbb_crypto/price/price_router.py index 6c95097c0752..efce03361499 100644 --- a/openbb_platform/extensions/crypto/openbb_crypto/price/price_router.py +++ b/openbb_platform/extensions/crypto/openbb_crypto/price/price_router.py @@ -2,6 +2,7 @@ """Crypto Price Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -18,10 +19,33 @@ @router.command( model="CryptoHistorical", examples=[ - 'obb.crypto.price.historical("BTCUSD", start_date="2024-01-01", end_date="2024-01-31")', - 'obb.crypto.price.historical("ETH-USD", provider="yfinance", interval="1mo", start_date="2024-01-01", end_date="2024-12-31")', # noqa: E501 - 'obb.crypto.price.historical("BTCUSD,ETH-USD", provider="yfinance", interval="1d", start_date="2024-01-01", end_date="2024-01-31")', # noqa: E501 - 'obb.crypto.price.historical(["BTCUSD", "ETH-USD"], start_date="2024-01-01", end_date="2024-01-31")', + APIEx(parameters={"symbol": "BTCUSD", "provider": "fmp"}), + APIEx( + parameters={ + "symbol": "BTCUSD", + "start_date": "2024-01-01", + "end_date": "2024-01-31", + "provider": "fmp", + }, + ), + APIEx( + parameters={ + "symbol": "BTCUSD,ETHUSD", + "start_date": "2024-01-01", + "end_date": "2024-01-31", + "provider": "polygon", + }, + ), + APIEx( + description="Get monthly historical prices from Yahoo Finance for Ethereum.", + parameters={ + "symbol": "ETH-USD", + "interval": "1m", + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "provider": "yfinance", + }, + ), ], ) async def historical( diff --git a/openbb_platform/extensions/currency/openbb_currency/currency_router.py b/openbb_platform/extensions/currency/openbb_currency/currency_router.py index 40a82e870c58..669b463869af 100644 --- a/openbb_platform/extensions/currency/openbb_currency/currency_router.py +++ b/openbb_platform/extensions/currency/openbb_currency/currency_router.py @@ -1,6 +1,7 @@ """The Currency router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -20,12 +21,19 @@ @router.command( model="CurrencyPairs", examples=[ - "# Search for 'EURUSD' currency pair using 'polygon' as provider.", - "obb.currency.search(provider='polygon', symbol='EURUSD')", - "# Search for terms using 'polygon' as provider.", - "obb.currency.search(provider='polygon', search='Euro zone')", - "# Search for actively traded currency pairs on the queried date using 'polygon' as provider.", - "obb.currency.search(provider='polygon', date='2024-01-02', active=True)", + APIEx(parameters={"provider": "intrinio"}), + APIEx( + description="Search for 'EURUSD' currency pair using 'intrinio' as provider.", + parameters={"provider": "intrinio", "symbol": "EURUSD"}, + ), + APIEx( + description="Search for actively traded currency pairs on the queried date using 'polygon' as provider.", + parameters={"provider": "polygon", "date": "2024-01-02", "active": True}, + ), + APIEx( + description="Search for terms using 'polygon' as provider.", + parameters={"provider": "polygon", "search": "Euro zone"}, + ), ], ) async def search( @@ -34,8 +42,7 @@ async def search( standard_params: StandardParams, extra_params: ExtraParams, ) -> OBBject: - """ - Currency Search. + """Currency Search. Search available currency pairs. Currency pairs are the national currencies from two countries coupled for trading on @@ -48,7 +55,10 @@ async def search( return await OBBject.from_query(Query(**locals())) -@router.command(model="CurrencyReferenceRates") +@router.command( + model="CurrencyReferenceRates", + examples=[APIEx(parameters={"provider": "ecb"})], +) async def reference_rates( cc: CommandContext, provider_choices: ProviderChoices, @@ -70,11 +80,17 @@ async def reference_rates( @router.command( model="CurrencySnapshots", - exclude_auto_examples=True, examples=[ - "obb.currency.snapshots(", - 'provider="fmp", base="USD,XAU", counter_currencies="EUR,JPY,GBP", quote_type="indirect"', - ")", + APIEx(parameters={"provider": "fmp"}), + APIEx( + description="Get exchange rates from USD and XAU to EUR, JPY, and GBP using 'fmp' as provider.", + parameters={ + "provider": "fmp", + "base": "USD,XAU", + "counter_currencies": "EUR,JPY,GBP", + "quote_type": "indirect", + }, + ), ], ) async def snapshots( diff --git a/openbb_platform/extensions/currency/openbb_currency/price/price_router.py b/openbb_platform/extensions/currency/openbb_currency/price/price_router.py index 86b029b720d3..fe84f8c7d8c6 100644 --- a/openbb_platform/extensions/currency/openbb_currency/price/price_router.py +++ b/openbb_platform/extensions/currency/openbb_currency/price/price_router.py @@ -2,6 +2,7 @@ # pylint: disable=unused-argument from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -18,10 +19,20 @@ @router.command( model="CurrencyHistorical", examples=[ - "# Filter historical data with specific start and end date.", - "obb.currency.price.historical(symbol='EURUSD', start_date='2023-01-01', end_date='20213-12-31')", - "# Get data with different granularity.", - "obb.currency.price.historical(symbol='EURUSD', interval='15m', provider='polygon')", + APIEx(parameters={"symbol": "EURUSD", "provider": "fmp"}), + APIEx( + description="Filter historical data with specific start and end date.", + parameters={ + "symbol": "EURUSD", + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "provider": "fmp", + }, + ), + APIEx( + description="Get data with different granularity.", + parameters={"symbol": "EURUSD", "provider": "polygon", "interval": "15m"}, + ), ], ) async def historical( diff --git a/openbb_platform/extensions/derivatives/openbb_derivatives/futures/futures_router.py b/openbb_platform/extensions/derivatives/openbb_derivatives/futures/futures_router.py index 1ea63586701d..bc47e4531a94 100644 --- a/openbb_platform/extensions/derivatives/openbb_derivatives/futures/futures_router.py +++ b/openbb_platform/extensions/derivatives/openbb_derivatives/futures/futures_router.py @@ -1,6 +1,7 @@ """Futures Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -16,13 +17,20 @@ # pylint: disable=unused-argument @router.command( model="FuturesHistorical", - exclude_auto_examples=True, examples=[ - 'obb.derivatives.futures.historical("ES", provider="yfinance")', - '#### Enter expiration dates as "YYYY-MM" ####', - 'obb.derivatives.futures.historical("ES", provider="yfinance", expiration="2025-12")', - "#### Enter multiple symbols as a list. ####", - 'obb.derivatives.futures.historical(["ES", "NQ", "ESZ24.CME", "NQZ24.CME"], provider="yfinance")', + APIEx(parameters={"symbol": "ES", "provider": "yfinance"}), + APIEx( + description="Enter multiple symbols.", + parameters={"symbol": "ES,NQ", "provider": "yfinance"}, + ), + APIEx( + description='Enter expiration dates as "YYYY-MM".', + parameters={ + "symbol": "ES", + "provider": "yfinance", + "expiration": "2025-12", + }, + ), ], ) async def historical( @@ -37,11 +45,12 @@ async def historical( @router.command( model="FuturesCurve", - exclude_auto_examples=True, examples=[ - 'obb.derivatives.futures.curve("NG", provider="yfinance")', - "#### Enter a date to get the term structure from a historical date. ####", - 'obb.derivatives.futures.curve("NG", provider="yfinance", date="2023-01-01")', + APIEx(parameters={"symbol": "VX", "provider": "cboe"}), + APIEx( + description="Enter a date to get the term structure from a historical date.", + parameters={"symbol": "NG", "provider": "yfinance", "date": "2023-01-01"}, + ), ], ) async def curve( diff --git a/openbb_platform/extensions/derivatives/openbb_derivatives/options/options_router.py b/openbb_platform/extensions/derivatives/openbb_derivatives/options/options_router.py index 925caf5be49b..ec6ecf29186c 100644 --- a/openbb_platform/extensions/derivatives/openbb_derivatives/options/options_router.py +++ b/openbb_platform/extensions/derivatives/openbb_derivatives/options/options_router.py @@ -1,6 +1,7 @@ """Options Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -17,11 +18,12 @@ @router.command( model="OptionsChains", - exclude_auto_examples=True, examples=[ - 'chains = obb.derivatives.options.chains(symbol="AAPL", provider="intrinio").to_df()', - '#### Use the "date" parameter to get the end-of-day-data for a specific date, where supported. ####', - 'eod_chains = obb.derivatives.options.chains(symbol="AAPL", date="2023-01-25", provider="intrinio").to_df()', + APIEx(parameters={"symbol": "AAPL", "provider": "intrinio"}), + APIEx( + description='Use the "date" parameter to get the end-of-day-data for a specific date, where supported.', + parameters={"symbol": "AAPL", "date": "2023-01-25", "provider": "intrinio"}, + ), ], ) async def chains( @@ -36,11 +38,12 @@ async def chains( @router.command( model="OptionsUnusual", - exclude_auto_examples=True, examples=[ - "options = obb.derivatives.options.unusual().to_df()", - '#### Use the "symbol" parameter to get the most recent activity for a specific symbol. ####', - 'options = obb.derivatives.options.unusual(symbol="TSLA").to_df()', + APIEx(parameters={"provider": "intrinio"}), + APIEx( + description="Use the 'symbol' parameter to get the most recent activity for a specific symbol.", + parameters={"symbol": "TSLA", "provider": "intrinio"}, + ), ], ) async def unusual( diff --git a/openbb_platform/extensions/econometrics/openbb_econometrics/econometrics_router.py b/openbb_platform/extensions/econometrics/openbb_econometrics/econometrics_router.py index 2a1a941e553d..21e44275d870 100644 --- a/openbb_platform/extensions/econometrics/openbb_econometrics/econometrics_router.py +++ b/openbb_platform/extensions/econometrics/openbb_econometrics/econometrics_router.py @@ -15,6 +15,7 @@ PooledOLS, RandomEffects, ) +from openbb_core.app.model.example import APIEx, PythonEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.router import Router from openbb_core.app.utils import basemodel_to_df, get_target_column, get_target_columns @@ -32,8 +33,14 @@ @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", - "obb.econometrics.correlation_matrix(data=stock_data)", + PythonEx( + description="Get the correlation matrix of a dataset.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 + "obb.econometrics.correlation_matrix(data=stock_data)", + ], + ), + APIEx(parameters={"data": APIEx.mock_data("timeseries")}), ], ) def correlation_matrix(data: List[Data]) -> OBBject[List[Data]]: @@ -74,8 +81,20 @@ def correlation_matrix(data: List[Data]) -> OBBject[List[Data]]: methods=["POST"], include_in_schema=False, examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", - 'obb.econometrics.ols_regression(data=stock_data, y_column="close", x_columns=["open", "high", "low"])', + PythonEx( + description="Perform Ordinary Least Squares (OLS) regression.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 + 'obb.econometrics.ols_regression(data=stock_data, y_column="close", x_columns=["open", "high", "low"])', + ], + ), + APIEx( + parameters={ + "y_column": "close", + "x_columns": ["open", "high", "low"], + "data": APIEx.mock_data("timeseries"), + } + ), ], ) def ols_regression( @@ -114,8 +133,20 @@ def ols_regression( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", - 'obb.econometrics.ols_regression_summary(data=stock_data, y_column="close", x_columns=["open", "high", "low"])', + PythonEx( + description="Perform Ordinary Least Squares (OLS) regression and return the summary.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 pylint: disable=line-too-long + 'obb.econometrics.ols_regression_summary(data=stock_data, y_column="close", x_columns=["open", "high", "low"])', # noqa: E501 pylint: disable=line-too-long + ], + ), + APIEx( + parameters={ + "y_column": "close", + "x_columns": ["open", "high", "low"], + "data": APIEx.mock_data("timeseries"), + } + ), ], ) def ols_regression_summary( @@ -187,8 +218,20 @@ def ols_regression_summary( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", - 'obb.econometrics.autocorrelation(data=stock_data, y_column="close", x_columns=["open", "high", "low"])', + PythonEx( + description="Perform Durbin-Watson test for autocorrelation.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 + 'obb.econometrics.autocorrelation(data=stock_data, y_column="close", x_columns=["open", "high", "low"])', + ], + ), + APIEx( + parameters={ + "y_column": "close", + "x_columns": ["open", "high", "low"], + "data": APIEx.mock_data("timeseries"), + } + ), ], ) def autocorrelation( @@ -229,8 +272,20 @@ def autocorrelation( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", - 'obb.econometrics.residual_autocorrelation(data=stock_data, y_column="close", x_columns=["open", "high", "low"])', + PythonEx( + description="Perform Breusch-Godfrey Lagrange Multiplier tests for residual autocorrelation.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 + 'obb.econometrics.residual_autocorrelation(data=stock_data, y_column="close", x_columns=["open", "high", "low"])', # noqa: E501 pylint: disable=line-too-long + ], + ), + APIEx( + parameters={ + "y_column": "close", + "x_columns": ["open", "high", "low"], + "data": APIEx.mock_data("timeseries"), + } + ), ], ) def residual_autocorrelation( @@ -284,8 +339,19 @@ def residual_autocorrelation( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", - 'obb.econometrics.cointegration(data=stock_data, columns=["open", "close"])', + PythonEx( + description="Perform co-integration test between two timeseries.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 + 'obb.econometrics.cointegration(data=stock_data, columns=["open", "close"])', + ], + ), + APIEx( + parameters={ + "columns": ["open", "close"], + "data": APIEx.mock_data("timeseries"), + } + ), ], ) def cointegration( @@ -343,8 +409,22 @@ def cointegration( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", - 'obb.econometrics.causality(data=stock_data, y_column="close", x_column="open")', + PythonEx( + description="Perform Granger causality test to determine if X 'causes' y.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 + 'obb.econometrics.causality(data=stock_data, y_column="close", x_column="open")', + ], + ), + APIEx( + description="Example with mock data.", + parameters={ + "y_column": "close", + "x_column": "open", + "lag": 1, + "data": APIEx.mock_data("timeseries"), + }, + ), ], ) def causality( @@ -400,9 +480,20 @@ def causality( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", - 'obb.econometrics.unit_root(data=stock_data, column="close")', - 'obb.econometrics.unit_root(data=stock_data, column="close", regression="ct")', + PythonEx( + description="Perform Augmented Dickey-Fuller (ADF) unit root test.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 + 'obb.econometrics.unit_root(data=stock_data, column="close")', + 'obb.econometrics.unit_root(data=stock_data, column="close", regression="ct")', + ], + ), + APIEx( + parameters={ + "column": "close", + "data": APIEx.mock_data("timeseries"), + } + ), ], ) def unit_root( @@ -448,7 +539,18 @@ def unit_root( return OBBject(results=results) -@router.command(methods=["POST"], include_in_schema=False) +@router.command( + methods=["POST"], + examples=[ + APIEx( + parameters={ + "y_column": "portfolio_value", + "x_columns": ["risk_free_rate"], + "data": APIEx.mock_data("panel"), + } + ), + ], +) def panel_random_effects( data: List[Data], y_column: str, @@ -476,13 +578,26 @@ def panel_random_effects( OBBject with the fit model returned """ X = get_target_columns(basemodel_to_df(data), x_columns) + if len(X) < 3: + raise ValueError("This analysis requires at least 3 items in the dataset.") y = get_target_column(basemodel_to_df(data), y_column) exogenous = sm.add_constant(X) results = RandomEffects(y, exogenous).fit() return OBBject(results={"results": results}) -@router.command(methods=["POST"], include_in_schema=False) +@router.command( + methods=["POST"], + examples=[ + APIEx( + parameters={ + "y_column": "portfolio_value", + "x_columns": ["risk_free_rate"], + "data": APIEx.mock_data("panel"), + } + ), + ], +) def panel_between( data: List[Data], y_column: str, @@ -516,7 +631,18 @@ def panel_between( return OBBject(results={"results": results}) -@router.command(methods=["POST"], include_in_schema=False) +@router.command( + methods=["POST"], + examples=[ + APIEx( + parameters={ + "y_column": "portfolio_value", + "x_columns": ["risk_free_rate"], + "data": APIEx.mock_data("panel"), + } + ), + ], +) def panel_pooled( data: List[Data], y_column: str, @@ -551,7 +677,18 @@ def panel_pooled( return OBBject(results={"results": results}) -@router.command(methods=["POST"], include_in_schema=False) +@router.command( + methods=["POST"], + examples=[ + APIEx( + parameters={ + "y_column": "portfolio_value", + "x_columns": ["risk_free_rate"], + "data": APIEx.mock_data("panel"), + } + ), + ], +) def panel_fixed( data: List[Data], y_column: str, @@ -585,7 +722,18 @@ def panel_fixed( return OBBject(results={"results": results}) -@router.command(methods=["POST"], include_in_schema=False) +@router.command( + methods=["POST"], + examples=[ + APIEx( + parameters={ + "y_column": "portfolio_value", + "x_columns": ["risk_free_rate"], + "data": APIEx.mock_data("panel"), + } + ), + ], +) def panel_first_difference( data: List[Data], y_column: str, @@ -619,7 +767,18 @@ def panel_first_difference( return OBBject(results={"results": results}) -@router.command(methods=["POST"], include_in_schema=False) +@router.command( + methods=["POST"], + examples=[ + APIEx( + parameters={ + "y_column": "portfolio_value", + "x_columns": ["risk_free_rate"], + "data": APIEx.mock_data("panel"), + } + ), + ], +) def panel_fmac( data: List[Data], y_column: str, diff --git a/openbb_platform/extensions/economy/openbb_economy/economy_router.py b/openbb_platform/extensions/economy/openbb_economy/economy_router.py index b6f0bde05d54..9cf8fdfcfd8d 100644 --- a/openbb_platform/extensions/economy/openbb_economy/economy_router.py +++ b/openbb_platform/extensions/economy/openbb_economy/economy_router.py @@ -1,6 +1,7 @@ """Economy Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -20,11 +21,22 @@ @router.command( model="EconomicCalendar", - exclude_auto_examples=True, examples=[ - 'obb.economy.calendar(provider="fmp", start_date="2020-03-01", end_date="2020-03-31")', - "#### By default, the calendar will be forward-looking. ####", - 'obb.economy.calendar(provider="nasdaq")', + APIEx( + parameters={"provider": "fmp"}, + description="By default, the calendar will be forward-looking.", + ), + APIEx( + parameters={ + "provider": "fmp", + "start_date": "2020-03-01", + "end_date": "2020-03-31", + } + ), + APIEx( + description="By default, the calendar will be forward-looking.", + parameters={"provider": "nasdaq"}, + ), ], ) async def calendar( @@ -39,11 +51,16 @@ async def calendar( @router.command( model="ConsumerPriceIndex", - exclude_auto_examples=True, examples=[ - 'obb.economy.cpi(countries=["japan", "china", "turkey"]).to_df()', - "#### Use the `units` parameter to define the reference period for the change in values. ####", - 'obb.economy.cpi(countries=["united_states", "united_kingdom"], units="growth_previous").to_df()', + APIEx(parameters={"country": "japan,china,turkey", "provider": "fred"}), + APIEx( + description="Use the `units` parameter to define the reference period for the change in values.", + parameters={ + "country": "united_states,united_kingdom", + "units": "growth_previous", + "provider": "fred", + }, + ), ], ) async def cpi( @@ -58,8 +75,7 @@ async def cpi( @router.command( model="RiskPremium", - exclude_auto_examples=True, - examples=["obb.economy.risk_premium().to_df()"], + examples=[APIEx(parameters={"provider": "fmp"})], ) async def risk_premium( cc: CommandContext, @@ -73,11 +89,13 @@ async def risk_premium( @router.command( model="BalanceOfPayments", - exclude_auto_examples=True, examples=[ - 'obb.economy.balance_of_payments(report_type="summary").to_df().set_index("period").T', - "#### The `country` parameter will override the `report_type`. ####", - 'obb.economy.balance_of_payments(country="united_states", provider="ecb").to_df().set_index("period").T', + APIEx(parameters={"provider": "ecb"}), + APIEx(parameters={"report_type": "summary", "provider": "ecb"}), + APIEx( + description="The `country` parameter will override the `report_type`.", + parameters={"country": "united_states", "provider": "ecb"}, + ), ], ) async def balance_of_payments( @@ -90,7 +108,7 @@ async def balance_of_payments( return await OBBject.from_query(Query(**locals())) -@router.command(model="FredSearch") +@router.command(model="FredSearch", examples=[APIEx(parameters={"provider": "fred"})]) async def fred_search( cc: CommandContext, provider_choices: ProviderChoices, @@ -107,13 +125,16 @@ async def fred_search( @router.command( model="FredSeries", - exclude_auto_examples=True, examples=[ - 'obb.economy.fred_series("NFCI").to_df()', - "#### Multiple series can be passed in as a list. ####", - 'obb.economy.fred_series(["NFCI","STLFSI4"]).to_df()', - "#### Use the `transform` parameter to transform the data as change, log, or percent change. ####", - 'obb.economy.fred_series("CBBTCUSD", transform="pc1").to_df()', + APIEx(parameters={"symbol": "NFCI", "provider": "fred"}), + APIEx( + description="Multiple series can be passed in as a list.", + parameters={"symbol": "NFCI,STLFSI4", "provider": "fred"}, + ), + APIEx( + description="Use the `transform` parameter to transform the data as change, log, or percent change.", + parameters={"symbol": "CBBTCUSD", "transform": "pc1", "provider": "fred"}, + ), ], ) async def fred_series( @@ -128,9 +149,9 @@ async def fred_series( @router.command( model="MoneyMeasures", - exclude_auto_examples=True, examples=[ - "obb.economy.money_measures(adjusted=False).to_df()", + APIEx(parameters={"provider": "federal_reserve"}), + APIEx(parameters={"adjusted": False, "provider": "federal_reserve"}), ], ) async def money_measures( @@ -145,13 +166,20 @@ async def money_measures( @router.command( model="Unemployment", - exclude_auto_examples=True, examples=[ - 'obb.economy.unemployment(country="all", frequency="quarterly")', - "#### Demographics for the statistics are selected with the `age` and `sex` parameters. ####", - "obb.economy.unemployment(", - 'country="all", frequency="quarterly", age="25-54"', - ').to_df().pivot(columns="country", values="value")', + APIEx(parameters={"provider": "oecd"}), + APIEx( + parameters={"country": "all", "frequency": "quarterly", "provider": "oecd"} + ), + APIEx( + description="Demographics for the statistics are selected with the `age` parameter.", + parameters={ + "country": "all", + "frequency": "quarterly", + "age": "25-54", + "provider": "oecd", + }, + ), ], ) async def unemployment( @@ -166,9 +194,9 @@ async def unemployment( @router.command( model="CLI", - exclude_auto_examples=True, examples=[ - 'obb.economy.composite_leading_indicator(country="all").to_df()', + APIEx(parameters={"provider": "oecd"}), + APIEx(parameters={"country": "all", "provider": "oecd"}), ], ) async def composite_leading_indicator( @@ -186,9 +214,11 @@ async def composite_leading_indicator( @router.command( model="STIR", - exclude_auto_examples=True, examples=[ - 'obb.economy.short_term_interest_rate(country="all", frequency="quarterly").to_df()', + APIEx(parameters={"provider": "oecd"}), + APIEx( + parameters={"country": "all", "frequency": "quarterly", "provider": "oecd"} + ), ], ) async def short_term_interest_rate( @@ -209,9 +239,11 @@ async def short_term_interest_rate( @router.command( model="LTIR", - exclude_auto_examples=True, examples=[ - 'obb.economy.long_term_interest_rate(country="all", frequency="quarterly").to_df()', + APIEx(parameters={"provider": "oecd"}), + APIEx( + parameters={"country": "all", "frequency": "quarterly", "provider": "oecd"} + ), ], ) async def long_term_interest_rate( @@ -235,12 +267,20 @@ async def long_term_interest_rate( @router.command( model="FredRegional", - exclude_auto_examples=True, examples=[ - "#### With no date, the most recent report is returned. ####", - 'obb.economy.fred_regional("NYICLAIMS")', - "#### With a date, time series data is returned. ####", - 'obb.economy.fred_regional("NYICLAIMS", start_date="2021-01-01")', + APIEx( + parameters={"symbol": "NYICLAIMS", "provider": "fred"}, + ), + APIEx( + description="With a date, time series data is returned.", + parameters={ + "symbol": "NYICLAIMS", + "start_date": "2021-01-01", + "end_date": "2021-12-31", + "limit": 10, + "provider": "fred", + }, + ), ], ) async def fred_regional( diff --git a/openbb_platform/extensions/economy/openbb_economy/gdp/gdp_router.py b/openbb_platform/extensions/economy/openbb_economy/gdp/gdp_router.py index 4f3b5340ef3d..024fc8e2ff86 100644 --- a/openbb_platform/extensions/economy/openbb_economy/gdp/gdp_router.py +++ b/openbb_platform/extensions/economy/openbb_economy/gdp/gdp_router.py @@ -1,6 +1,7 @@ """Economy GDP Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -15,7 +16,13 @@ # pylint: disable=unused-argument -@router.command(model="GdpForecast") +@router.command( + model="GdpForecast", + examples=[ + APIEx(parameters={"provider": "oecd"}), + APIEx(parameters={"period": "annual", "type": "real", "provider": "oecd"}), + ], +) async def forecast( cc: CommandContext, provider_choices: ProviderChoices, @@ -26,7 +33,13 @@ async def forecast( return await OBBject.from_query(Query(**locals())) -@router.command(model="GdpNominal") +@router.command( + model="GdpNominal", + examples=[ + APIEx(parameters={"provider": "oecd"}), + APIEx(parameters={"units": "usd", "provider": "oecd"}), + ], +) async def nominal( cc: CommandContext, provider_choices: ProviderChoices, @@ -37,7 +50,13 @@ async def nominal( return await OBBject.from_query(Query(**locals())) -@router.command(model="GdpReal") +@router.command( + model="GdpReal", + examples=[ + APIEx(parameters={"provider": "oecd"}), + APIEx(parameters={"units": "yoy", "provider": "oecd"}), + ], +) async def real( cc: CommandContext, provider_choices: ProviderChoices, diff --git a/openbb_platform/extensions/equity/openbb_equity/calendar/calendar_router.py b/openbb_platform/extensions/equity/openbb_equity/calendar/calendar_router.py index 6693aecb2024..7c9395dde3c6 100644 --- a/openbb_platform/extensions/equity/openbb_equity/calendar/calendar_router.py +++ b/openbb_platform/extensions/equity/openbb_equity/calendar/calendar_router.py @@ -1,6 +1,7 @@ """Calendar Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -18,10 +19,19 @@ @router.command( model="CalendarIpo", examples=[ - "# Get all IPOs available.", - "obb.equity.calendar.ipo()", - "# Get IPOs for specific dates.", - "obb.equity.calendar.ipo(start_date='2024-02-01', end_date='2024-02-07')", + APIEx(parameters={"provider": "intrinio"}), + APIEx(parameters={"limit": 100, "provider": "nasdaq"}), + APIEx( + description="Get all IPOs available.", parameters={"provider": "intrinio"} + ), + APIEx( + description="Get IPOs for specific dates.", + parameters={ + "start_date": "2024-02-01", + "end_date": "2024-02-07", + "provider": "nasdaq", + }, + ), ], ) async def ipo( @@ -37,8 +47,15 @@ async def ipo( @router.command( model="CalendarDividend", examples=[ - "# Get dividend calendar for specific dates.", - "obb.equity.calendar.dividend(start_date='2024-02-01', end_date='2024-02-07')", + APIEx(parameters={"provider": "fmp"}), + APIEx( + description="Get dividend calendar for specific dates.", + parameters={ + "start_date": "2024-02-01", + "end_date": "2024-02-07", + "provider": "nasdaq", + }, + ), ], ) async def dividend( @@ -54,8 +71,15 @@ async def dividend( @router.command( model="CalendarSplits", examples=[ - "# Get stock splits calendar for specific dates.", - "obb.equity.calendar.splits(start_date='2024-02-01', end_date='2024-02-07')", + APIEx(parameters={"provider": "fmp"}), + APIEx( + description="Get stock splits calendar for specific dates.", + parameters={ + "start_date": "2024-02-01", + "end_date": "2024-02-07", + "provider": "fmp", + }, + ), ], ) async def splits( @@ -71,8 +95,15 @@ async def splits( @router.command( model="CalendarEarnings", examples=[ - "# Get earnings calendar for specific dates.", - "obb.equity.calendar.earnings(start_date='2024-02-01', end_date='2024-02-07')", + APIEx(parameters={"provider": "fmp"}), + APIEx( + description="Get earnings calendar for specific dates.", + parameters={ + "start_date": "2024-02-01", + "end_date": "2024-02-07", + "provider": "fmp", + }, + ), ], ) async def earnings( diff --git a/openbb_platform/extensions/equity/openbb_equity/compare/compare_router.py b/openbb_platform/extensions/equity/openbb_equity/compare/compare_router.py index da08a4cf110e..2f585055e3fb 100644 --- a/openbb_platform/extensions/equity/openbb_equity/compare/compare_router.py +++ b/openbb_platform/extensions/equity/openbb_equity/compare/compare_router.py @@ -2,6 +2,7 @@ """Comparison Analysis Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -14,7 +15,10 @@ router = Router(prefix="/compare") -@router.command(model="EquityPeers") +@router.command( + model="EquityPeers", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def peers( cc: CommandContext, provider_choices: ProviderChoices, @@ -31,12 +35,27 @@ async def peers( @router.command( model="CompareGroups", examples=[ - "# Group by sector and analyze valuation", - "obb.equity.compare.groups(group='sector', metric='valuation')", - "# Group by industry and analyze performance", - "obb.equity.compare.groups(group='industry', metric='performance')", - "# Group by country and analyze valuation", - "obb.equity.compare.groups(group='country', metric='valuation')", + APIEx(parameters={"provider": "finviz"}), + APIEx( + description="Group by sector and analyze valuation.", + parameters={"group": "sector", "metric": "valuation", "provider": "finviz"}, + ), + APIEx( + description="Group by industry and analyze performance.", + parameters={ + "group": "industry", + "metric": "performance", + "provider": "finviz", + }, + ), + APIEx( + description="Group by country and analyze valuation.", + parameters={ + "group": "country", + "metric": "valuation", + "provider": "finviz", + }, + ), ], ) async def groups( diff --git a/openbb_platform/extensions/equity/openbb_equity/darkpool/darkpool_router.py b/openbb_platform/extensions/equity/openbb_equity/darkpool/darkpool_router.py index 1cda9b50ec58..67307cbeec0e 100644 --- a/openbb_platform/extensions/equity/openbb_equity/darkpool/darkpool_router.py +++ b/openbb_platform/extensions/equity/openbb_equity/darkpool/darkpool_router.py @@ -1,6 +1,7 @@ """Dark Pool Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -18,8 +19,11 @@ @router.command( model="OTCAggregate", examples=[ - "# Get OTC data for a symbol", - "obb.equity.darkpool.otc(symbol='AAPL')", + APIEx(parameters={"provider": "finra"}), + APIEx( + description="Get OTC data for a symbol", + parameters={"symbol": "AAPL", "provider": "finra"}, + ), ], ) async def otc( diff --git a/openbb_platform/extensions/equity/openbb_equity/discovery/discovery_router.py b/openbb_platform/extensions/equity/openbb_equity/discovery/discovery_router.py index 58247da48c86..86ccde2857d2 100644 --- a/openbb_platform/extensions/equity/openbb_equity/discovery/discovery_router.py +++ b/openbb_platform/extensions/equity/openbb_equity/discovery/discovery_router.py @@ -2,6 +2,7 @@ # pylint: disable=unused-argument from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -14,7 +15,13 @@ router = Router(prefix="/discovery") -@router.command(model="EquityGainers") +@router.command( + model="EquityGainers", + examples=[ + APIEx(parameters={"provider": "yfinance"}), + APIEx(parameters={"sort": "desc", "provider": "yfinance"}), + ], +) async def gainers( cc: CommandContext, provider_choices: ProviderChoices, @@ -25,7 +32,13 @@ async def gainers( return await OBBject.from_query(Query(**locals())) -@router.command(model="EquityLosers") +@router.command( + model="EquityLosers", + examples=[ + APIEx(parameters={"provider": "yfinance"}), + APIEx(parameters={"sort": "desc", "provider": "yfinance"}), + ], +) async def losers( cc: CommandContext, provider_choices: ProviderChoices, @@ -36,7 +49,13 @@ async def losers( return await OBBject.from_query(Query(**locals())) -@router.command(model="EquityActive") +@router.command( + model="EquityActive", + examples=[ + APIEx(parameters={"provider": "yfinance"}), + APIEx(parameters={"sort": "desc", "provider": "yfinance"}), + ], +) async def active( cc: CommandContext, provider_choices: ProviderChoices, @@ -47,7 +66,13 @@ async def active( return await OBBject.from_query(Query(**locals())) -@router.command(model="EquityUndervaluedLargeCaps") +@router.command( + model="EquityUndervaluedLargeCaps", + examples=[ + APIEx(parameters={"provider": "yfinance"}), + APIEx(parameters={"sort": "desc", "provider": "yfinance"}), + ], +) async def undervalued_large_caps( cc: CommandContext, provider_choices: ProviderChoices, @@ -58,7 +83,13 @@ async def undervalued_large_caps( return await OBBject.from_query(Query(**locals())) -@router.command(model="EquityUndervaluedGrowth") +@router.command( + model="EquityUndervaluedGrowth", + examples=[ + APIEx(parameters={"provider": "yfinance"}), + APIEx(parameters={"sort": "desc", "provider": "yfinance"}), + ], +) async def undervalued_growth( cc: CommandContext, provider_choices: ProviderChoices, @@ -69,7 +100,13 @@ async def undervalued_growth( return await OBBject.from_query(Query(**locals())) -@router.command(model="EquityAggressiveSmallCaps") +@router.command( + model="EquityAggressiveSmallCaps", + examples=[ + APIEx(parameters={"provider": "yfinance"}), + APIEx(parameters={"sort": "desc", "provider": "yfinance"}), + ], +) async def aggressive_small_caps( cc: CommandContext, provider_choices: ProviderChoices, @@ -80,7 +117,13 @@ async def aggressive_small_caps( return await OBBject.from_query(Query(**locals())) -@router.command(model="GrowthTechEquities") +@router.command( + model="GrowthTechEquities", + examples=[ + APIEx(parameters={"provider": "yfinance"}), + APIEx(parameters={"sort": "desc", "provider": "yfinance"}), + ], +) async def growth_tech( cc: CommandContext, provider_choices: ProviderChoices, @@ -91,7 +134,10 @@ async def growth_tech( return await OBBject.from_query(Query(**locals())) -@router.command(model="TopRetail") +@router.command( + model="TopRetail", + examples=[APIEx(parameters={"provider": "nasdaq"})], +) async def top_retail( cc: CommandContext, provider_choices: ProviderChoices, @@ -105,7 +151,10 @@ async def top_retail( return await OBBject.from_query(Query(**locals())) -@router.command(model="UpcomingReleaseDays") +@router.command( + model="UpcomingReleaseDays", + examples=[APIEx(parameters={"provider": "seeking_alpha"})], +) async def upcoming_release_days( cc: CommandContext, provider_choices: ProviderChoices, @@ -119,8 +168,16 @@ async def upcoming_release_days( @router.command( model="DiscoveryFilings", examples=[ - "# Get filings for the year 2023, limited to 100 results", - "obb.equity.discovery.filings(start_date='2023-01-01', end_date='2023-12-31')", + APIEx(parameters={"provider": "fmp"}), + APIEx( + description="Get filings for the year 2023, limited to 100 results", + parameters={ + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "limit": 100, + "provider": "fmp", + }, + ), ], ) async def filings( diff --git a/openbb_platform/extensions/equity/openbb_equity/equity_router.py b/openbb_platform/extensions/equity/openbb_equity/equity_router.py index d47e2e5dcd46..9da54b7678c8 100644 --- a/openbb_platform/extensions/equity/openbb_equity/equity_router.py +++ b/openbb_platform/extensions/equity/openbb_equity/equity_router.py @@ -1,6 +1,7 @@ """Equity Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -34,7 +35,20 @@ # pylint: disable=import-outside-toplevel, W0613:unused-argument -@router.command(model="EquitySearch") +@router.command( + model="EquitySearch", + examples=[ + APIEx(parameters={"provider": "intrinio"}), + APIEx( + parameters={ + "query": "AAPL", + "is_symbol": False, + "use_cache": True, + "provider": "nasdaq", + } + ), + ], +) async def search( cc: CommandContext, provider_choices: ProviderChoices, @@ -45,7 +59,9 @@ async def search( return await OBBject.from_query(Query(**locals())) -@router.command(model="EquityScreener") +@router.command( + model="EquityScreener", examples=[APIEx(parameters={"provider": "fmp"})] +) async def screener( cc: CommandContext, provider_choices: ProviderChoices, @@ -57,7 +73,10 @@ async def screener( return await OBBject.from_query(Query(**locals())) -@router.command(model="EquityInfo") +@router.command( + model="EquityInfo", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def profile( cc: CommandContext, provider_choices: ProviderChoices, @@ -68,7 +87,9 @@ async def profile( return await OBBject.from_query(Query(**locals())) -@router.command(model="MarketSnapshots") +@router.command( + model="MarketSnapshots", examples=[APIEx(parameters={"provider": "fmp"})] +) async def market_snapshots( cc: CommandContext, provider_choices: ProviderChoices, diff --git a/openbb_platform/extensions/equity/openbb_equity/estimates/estimates_router.py b/openbb_platform/extensions/equity/openbb_equity/estimates/estimates_router.py index 4d6f8902fe67..07c328c334c8 100644 --- a/openbb_platform/extensions/equity/openbb_equity/estimates/estimates_router.py +++ b/openbb_platform/extensions/equity/openbb_equity/estimates/estimates_router.py @@ -1,6 +1,7 @@ """Estimates Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -17,9 +18,19 @@ @router.command( model="PriceTarget", - exclude_auto_examples=True, examples=[ - 'obb.equity.estimates.price_target(start_date="2020-01-01", end_date="2024-02-16",limit=10, symbol="msft", provider="benzinga",action="downgrades").to_df()' # noqa: E501 pylint: disable=line-too-long + APIEx(parameters={"provider": "benzinga"}), + APIEx( + description="Get price targets for Microsoft using 'benzinga' as provider.", + parameters={ + "start_date": "2020-01-01", + "end_date": "2024-02-16", + "limit": 10, + "symbol": "msft", + "provider": "benzinga", + "action": "downgrades", + }, + ), ], ) async def price_target( @@ -34,9 +45,8 @@ async def price_target( @router.command( model="AnalystEstimates", - exclude_auto_examples=True, examples=[ - 'obb.equity.estimates.historical("AAPL", period="quarter", provider="fmp").to_df()', + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), ], ) async def historical( @@ -51,9 +61,9 @@ async def historical( @router.command( model="PriceTargetConsensus", - exclude_auto_examples=True, examples=[ - 'obb.equity.estimates.consensus("AAPL,MSFT", provider="yfinance").to_df()' + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx(parameters={"symbol": "AAPL,MSFT", "provider": "yfinance"}), ], ) async def consensus( @@ -68,9 +78,9 @@ async def consensus( @router.command( model="AnalystSearch", - exclude_auto_examples=True, examples=[ - 'obb.equity.estimates.analyst_search(firm_name="Wedbush", provider="benzinga").to_df()', + APIEx(parameters={"provider": "benzinga"}), + APIEx(parameters={"firm_name": "Wedbush", "provider": "benzinga"}), ], ) async def analyst_search( diff --git a/openbb_platform/extensions/equity/openbb_equity/fundamental/fundamental_router.py b/openbb_platform/extensions/equity/openbb_equity/fundamental/fundamental_router.py index eb36250b484c..e2cf2b7f97ad 100644 --- a/openbb_platform/extensions/equity/openbb_equity/fundamental/fundamental_router.py +++ b/openbb_platform/extensions/equity/openbb_equity/fundamental/fundamental_router.py @@ -3,6 +3,7 @@ from openbb_core.app.deprecation import OpenBBDeprecationWarning from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -15,7 +16,10 @@ router = Router(prefix="/fundamental") -@router.command(model="EquityValuationMultiples") +@router.command( + model="EquityValuationMultiples", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def multiples( cc: CommandContext, provider_choices: ProviderChoices, @@ -26,7 +30,20 @@ async def multiples( return await OBBject.from_query(Query(**locals())) -@router.command(model="BalanceSheet") +@router.command( + model="BalanceSheet", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx( + parameters={ + "symbol": "AAPL", + "period": "annual", + "limit": 5, + "provider": "intrinio", + } + ), + ], +) async def balance( cc: CommandContext, provider_choices: ProviderChoices, @@ -37,7 +54,13 @@ async def balance( return await OBBject.from_query(Query(**locals())) -@router.command(model="BalanceSheetGrowth") +@router.command( + model="BalanceSheetGrowth", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx(parameters={"symbol": "AAPL", "limit": 10, "provider": "fmp"}), + ], +) async def balance_growth( cc: CommandContext, provider_choices: ProviderChoices, @@ -48,7 +71,20 @@ async def balance_growth( return await OBBject.from_query(Query(**locals())) -@router.command(model="CashFlowStatement") +@router.command( + model="CashFlowStatement", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx( + parameters={ + "symbol": "AAPL", + "period": "annual", + "limit": 5, + "provider": "intrinio", + } + ), + ], +) async def cash( cc: CommandContext, provider_choices: ProviderChoices, @@ -62,10 +98,33 @@ async def cash( @router.command( model="ReportedFinancials", examples=[ - "# Get reported income statement", - "obb.equity.fundamental.reported_financials(symbol='AAPL', statement_type='income)", - "# Get reported cash flow statement", - "obb.equity.fundamental.reported_financials(symbol='AAPL', statement_type='cash')", + APIEx(parameters={"symbol": "AAPL", "provider": "intrinio"}), + APIEx( + description="Get AAPL balance sheet with a limit of 10 items.", + parameters={ + "symbol": "AAPL", + "period": "annual", + "statement_type": "balance", + "limit": 10, + "provider": "intrinio", + }, + ), + APIEx( + description="Get reported income statement", + parameters={ + "symbol": "AAPL", + "statement_type": "income", + "provider": "intrinio", + }, + ), + APIEx( + description="Get reported cash flow statement", + parameters={ + "symbol": "AAPL", + "statement_type": "cash", + "provider": "intrinio", + }, + ), ], ) async def reported_financials( @@ -78,7 +137,13 @@ async def reported_financials( return await OBBject.from_query(Query(**locals())) -@router.command(model="CashFlowStatementGrowth") +@router.command( + model="CashFlowStatementGrowth", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx(parameters={"symbol": "AAPL", "limit": 10, "provider": "fmp"}), + ], +) async def cash_growth( cc: CommandContext, provider_choices: ProviderChoices, @@ -89,7 +154,10 @@ async def cash_growth( return await OBBject.from_query(Query(**locals())) -@router.command(model="HistoricalDividends") +@router.command( + model="HistoricalDividends", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "intrinio"})], +) async def dividends( cc: CommandContext, provider_choices: ProviderChoices, @@ -100,7 +168,10 @@ async def dividends( return await OBBject.from_query(Query(**locals())) -@router.command(model="HistoricalEps") +@router.command( + model="HistoricalEps", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def historical_eps( cc: CommandContext, provider_choices: ProviderChoices, @@ -111,7 +182,10 @@ async def historical_eps( return await OBBject.from_query(Query(**locals())) -@router.command(model="HistoricalEmployees") +@router.command( + model="HistoricalEmployees", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def employee_count( cc: CommandContext, provider_choices: ProviderChoices, @@ -124,10 +198,7 @@ async def employee_count( @router.command( model="SearchAttributes", - exclude_auto_examples=True, - examples=[ - "obb.equity.fundamental.search_attributes(query='ebitda')", - ], + examples=[APIEx(parameters={"query": "ebitda", "provider": "intrinio"})], ) async def search_attributes( cc: CommandContext, @@ -141,9 +212,8 @@ async def search_attributes( @router.command( model="LatestAttributes", - exclude_auto_examples=True, examples=[ - "obb.equity.fundamental.latest_attributes(tag='ceo')", + APIEx(parameters={"symbol": "AAPL", "tag": "ceo", "provider": "intrinio"}) ], ) async def latest_attributes( @@ -158,9 +228,8 @@ async def latest_attributes( @router.command( model="HistoricalAttributes", - exclude_auto_examples=True, examples=[ - "obb.equity.fundamental.historical_attributes(tag='ebitda')", + APIEx(parameters={"symbol": "AAPL", "tag": "ebitda", "provider": "intrinio"}) ], ) async def historical_attributes( @@ -173,7 +242,20 @@ async def historical_attributes( return await OBBject.from_query(Query(**locals())) -@router.command(model="IncomeStatement") +@router.command( + model="IncomeStatement", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx( + parameters={ + "symbol": "AAPL", + "period": "annual", + "limit": 5, + "provider": "intrinio", + } + ), + ], +) async def income( cc: CommandContext, provider_choices: ProviderChoices, @@ -184,7 +266,20 @@ async def income( return await OBBject.from_query(Query(**locals())) -@router.command(model="IncomeStatementGrowth") +@router.command( + model="IncomeStatementGrowth", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx( + parameters={ + "symbol": "AAPL", + "limit": 10, + "period": "annual", + "provider": "fmp", + } + ), + ], +) async def income_growth( cc: CommandContext, provider_choices: ProviderChoices, @@ -195,7 +290,20 @@ async def income_growth( return await OBBject.from_query(Query(**locals())) -@router.command(model="KeyMetrics") +@router.command( + model="KeyMetrics", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx( + parameters={ + "symbol": "AAPL", + "period": "annual", + "limit": 100, + "provider": "intrinio", + } + ), + ], +) async def metrics( cc: CommandContext, provider_choices: ProviderChoices, @@ -206,7 +314,10 @@ async def metrics( return await OBBject.from_query(Query(**locals())) -@router.command(model="KeyExecutives") +@router.command( + model="KeyExecutives", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def management( cc: CommandContext, provider_choices: ProviderChoices, @@ -217,7 +328,10 @@ async def management( return await OBBject.from_query(Query(**locals())) -@router.command(model="ExecutiveCompensation") +@router.command( + model="ExecutiveCompensation", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def management_compensation( cc: CommandContext, provider_choices: ProviderChoices, @@ -236,6 +350,7 @@ async def management_compensation( since=(4, 1), expected_removal=(4, 3), ), + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], ) async def overview( cc: CommandContext, @@ -247,7 +362,20 @@ async def overview( return await OBBject.from_query(Query(**locals())) -@router.command(model="FinancialRatios") +@router.command( + model="FinancialRatios", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx( + parameters={ + "symbol": "AAPL", + "period": "annual", + "limit": 12, + "provider": "intrinio", + } + ), + ], +) async def ratios( cc: CommandContext, provider_choices: ProviderChoices, @@ -258,7 +386,20 @@ async def ratios( return await OBBject.from_query(Query(**locals())) -@router.command(model="RevenueGeographic") +@router.command( + model="RevenueGeographic", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx( + parameters={ + "symbol": "AAPL", + "period": "annual", + "structure": "flat", + "provider": "fmp", + } + ), + ], +) async def revenue_per_geography( cc: CommandContext, provider_choices: ProviderChoices, @@ -269,7 +410,20 @@ async def revenue_per_geography( return await OBBject.from_query(Query(**locals())) -@router.command(model="RevenueBusinessLine") +@router.command( + model="RevenueBusinessLine", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx( + parameters={ + "symbol": "AAPL", + "period": "annual", + "structure": "flat", + "provider": "fmp", + } + ), + ], +) async def revenue_per_segment( cc: CommandContext, provider_choices: ProviderChoices, @@ -280,7 +434,13 @@ async def revenue_per_segment( return await OBBject.from_query(Query(**locals())) -@router.command(model="CompanyFilings") +@router.command( + model="CompanyFilings", + examples=[ + APIEx(parameters={"provider": "fmp"}), + APIEx(parameters={"limit": 100, "provider": "fmp"}), + ], +) async def filings( cc: CommandContext, provider_choices: ProviderChoices, @@ -296,7 +456,10 @@ async def filings( return await OBBject.from_query(Query(**locals())) -@router.command(model="HistoricalSplits") +@router.command( + model="HistoricalSplits", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def historical_splits( cc: CommandContext, provider_choices: ProviderChoices, @@ -309,10 +472,7 @@ async def historical_splits( @router.command( model="EarningsCallTranscript", - exclude_auto_examples=True, - examples=[ - "obb.equity.fundamental.transcript(symbol='AAPL', year=2020)", - ], + examples=[APIEx(parameters={"symbol": "AAPL", "year": 2020, "provider": "fmp"})], ) async def transcript( cc: CommandContext, @@ -324,7 +484,13 @@ async def transcript( return await OBBject.from_query(Query(**locals())) -@router.command(model="TrailingDividendYield") +@router.command( + model="TrailingDividendYield", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "tiingo"}), + APIEx(parameters={"symbol": "AAPL", "limit": 252, "provider": "tiingo"}), + ], +) async def trailing_dividend_yield( cc: CommandContext, provider_choices: ProviderChoices, diff --git a/openbb_platform/extensions/equity/openbb_equity/ownership/ownership_router.py b/openbb_platform/extensions/equity/openbb_equity/ownership/ownership_router.py index e88daab971c1..8095164823e0 100644 --- a/openbb_platform/extensions/equity/openbb_equity/ownership/ownership_router.py +++ b/openbb_platform/extensions/equity/openbb_equity/ownership/ownership_router.py @@ -1,6 +1,7 @@ """Ownership Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx, PythonEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -15,7 +16,13 @@ # pylint: disable=unused-argument -@router.command(model="EquityOwnership") +@router.command( + model="EquityOwnership", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx(parameters={"symbol": "AAPL", "page": 0, "provider": "fmp"}), + ], +) async def major_holders( cc: CommandContext, provider_choices: ProviderChoices, @@ -26,7 +33,10 @@ async def major_holders( return await OBBject.from_query(Query(**locals())) -@router.command(model="InstitutionalOwnership") +@router.command( + model="InstitutionalOwnership", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def institutional( cc: CommandContext, provider_choices: ProviderChoices, @@ -37,7 +47,13 @@ async def institutional( return await OBBject.from_query(Query(**locals())) -@router.command(model="InsiderTrading") +@router.command( + model="InsiderTrading", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx(parameters={"symbol": "AAPL", "limit": 500, "provider": "intrinio"}), + ], +) async def insider_trading( cc: CommandContext, provider_choices: ProviderChoices, @@ -48,7 +64,10 @@ async def insider_trading( return await OBBject.from_query(Query(**locals())) -@router.command(model="ShareStatistics") +@router.command( + model="ShareStatistics", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def share_statistics( cc: CommandContext, provider_choices: ProviderChoices, @@ -61,16 +80,20 @@ async def share_statistics( @router.command( model="Form13FHR", - exclude_auto_examples=True, examples=[ - "### Enter the symbol as either the stock ticker or the CIK number as a string. ###", - 'obb.equity.ownership.form_13f(symbol="NVDA").to_df()', - "### Enter a date (calendar quarter ending) for a specific report. ###", - 'obb.equity.ownership.form_13f(symbol="BRK-A", date="2016-09-30")', - "### Use the `limit` parameter to return N number of reports from the most recent. ###", - "### Example finding Michael Burry's filings. ###", - 'cik = obb.regulators.sec.institutions_search("Scion Asset Management").results[0].cik', - "obb.equity.ownership.form_13f(cik, limit=2).to_df()", + APIEx(parameters={"symbol": "NVDA", "provider": "sec"}), + APIEx( + description="Enter a date (calendar quarter ending) for a specific report.", + parameters={"symbol": "BRK-A", "date": "2016-09-30", "provider": "sec"}, + ), + PythonEx( + description="Example finding Michael Burry's filings.", + code=[ + 'cik = obb.regulators.sec.institutions_search("Scion Asset Management").results[0].cik', + "# Use the `limit` parameter to return N number of reports from the most recent.", + "obb.equity.ownership.form_13f(cik, limit=2).to_df()", + ], + ), ], ) async def form_13f( diff --git a/openbb_platform/extensions/equity/openbb_equity/price/price_router.py b/openbb_platform/extensions/equity/openbb_equity/price/price_router.py index bae1fc26cec1..b52b0f7a730b 100644 --- a/openbb_platform/extensions/equity/openbb_equity/price/price_router.py +++ b/openbb_platform/extensions/equity/openbb_equity/price/price_router.py @@ -1,6 +1,7 @@ """Price Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -15,7 +16,10 @@ # pylint: disable=unused-argument -@router.command(model="EquityQuote") +@router.command( + model="EquityQuote", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def quote( cc: CommandContext, provider_choices: ProviderChoices, @@ -26,7 +30,10 @@ async def quote( return await OBBject.from_query(Query(**locals())) -@router.command(model="EquityNBBO") +@router.command( + model="EquityNBBO", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "polygon"})], +) async def nbbo( cc: CommandContext, provider_choices: ProviderChoices, @@ -37,7 +44,13 @@ async def nbbo( return await OBBject.from_query(Query(**locals())) -@router.command(model="EquityHistorical") +@router.command( + model="EquityHistorical", + examples=[ + APIEx(parameters={"symbol": "AAPL", "provider": "fmp"}), + APIEx(parameters={"symbol": "AAPL", "interval": "1d", "provider": "intrinio"}), + ], +) async def historical( cc: CommandContext, provider_choices: ProviderChoices, @@ -48,7 +61,10 @@ async def historical( return await OBBject.from_query(Query(**locals())) -@router.command(model="PricePerformance") +@router.command( + model="PricePerformance", + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "fmp"})], +) async def performance( cc: CommandContext, provider_choices: ProviderChoices, diff --git a/openbb_platform/extensions/equity/openbb_equity/shorts/shorts_router.py b/openbb_platform/extensions/equity/openbb_equity/shorts/shorts_router.py index c5283a947eea..1a08323b7bd2 100644 --- a/openbb_platform/extensions/equity/openbb_equity/shorts/shorts_router.py +++ b/openbb_platform/extensions/equity/openbb_equity/shorts/shorts_router.py @@ -1,6 +1,7 @@ """Shorts Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -17,8 +18,7 @@ @router.command( model="EquityFTD", - exclude_auto_examples=True, - examples=["obb.equity.shorts.fails_to_deliver(symbol='AAPL')"], + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "sec"})], ) async def fails_to_deliver( cc: CommandContext, @@ -32,8 +32,7 @@ async def fails_to_deliver( @router.command( model="ShortVolume", - exclude_auto_examples=True, - examples=["obb.equity.shorts.short_volume(symbol='AAPL')"], + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "stockgrid"})], ) async def short_volume( cc: CommandContext, @@ -47,8 +46,7 @@ async def short_volume( @router.command( model="EquityShortInterest", - exclude_auto_examples=True, - examples=["obb.equity.shorts.short_interest(symbol='AAPL')"], + examples=[APIEx(parameters={"symbol": "AAPL", "provider": "finra"})], ) async def short_interest( cc: CommandContext, diff --git a/openbb_platform/extensions/etf/openbb_etf/discovery/discovery_router.py b/openbb_platform/extensions/etf/openbb_etf/discovery/discovery_router.py index 21e60286f491..7963e7129475 100644 --- a/openbb_platform/extensions/etf/openbb_etf/discovery/discovery_router.py +++ b/openbb_platform/extensions/etf/openbb_etf/discovery/discovery_router.py @@ -1,6 +1,7 @@ """Disc router for ETFs.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -19,8 +20,7 @@ model="ETFGainers", operation_id="etf_gainers", examples=[ - "### Get the top ETF gainers. ###", - 'obb.etf.discovery.gainers(provider="wsj")', + APIEx(description="Get the top ETF gainers.", parameters={"provider": "wsj"}), ], ) async def gainers( @@ -37,8 +37,7 @@ async def gainers( model="ETFLosers", operation_id="etf_losers", examples=[ - "### Get the top ETF losers. ###", - 'obb.etf.discovery.losers(provider="wsj")', + APIEx(description="Get the top ETF losers.", parameters={"provider": "wsj"}), ], ) async def losers( @@ -55,8 +54,7 @@ async def losers( model="ETFActive", operation_id="etf_active", examples=[ - "### Get the most active ETFs. ###", - 'obb.etf.discovery.active(provider="wsj")', + APIEx(description="Get the most active ETFs.", parameters={"provider": "wsj"}), ], ) async def active( diff --git a/openbb_platform/extensions/etf/openbb_etf/etf_router.py b/openbb_platform/extensions/etf/openbb_etf/etf_router.py index 8a528a885cf3..caa8c90938b5 100644 --- a/openbb_platform/extensions/etf/openbb_etf/etf_router.py +++ b/openbb_platform/extensions/etf/openbb_etf/etf_router.py @@ -1,6 +1,7 @@ """ETF Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -20,12 +21,15 @@ @router.command( model="EtfSearch", - exclude_auto_examples=True, examples=[ - "### An empty query returns the full list of ETFs from the provider. ###", - 'obb.etf.search("", provider="fmp")', - "#### The query will return results from text-based fields containing the term. ####" - 'obb.etf.search("commercial real estate", provider="fmp")', + APIEx( + description="An empty query returns the full list of ETFs from the provider.", + parameters={"provider": "fmp"}, + ), + APIEx( + description="The query will return results from text-based fields containing the term.", + parameters={"query": "commercial real estate", "provider": "fmp"}, + ), ], ) async def search( @@ -45,9 +49,12 @@ async def search( model="EtfHistorical", operation_id="etf_historical", examples=[ - 'obb.etf.historical("SPY", provider="yfinance")', - "#### This function accepts multiple tickers. ####", - 'obb.etf.historical("SPY,IWM,QQQ,DJIA", provider="yfinance")', + APIEx(parameters={"symbol": "SPY", "provider": "fmp"}), + APIEx(parameters={"symbol": "SPY", "provider": "yfinance"}), + APIEx( + description="This function accepts multiple tickers.", + parameters={"symbol": "SPY,IWM,QQQ,DJIA", "provider": "yfinance"}, + ), ], ) async def historical( @@ -62,11 +69,12 @@ async def historical( @router.command( model="EtfInfo", - exclude_auto_examples=True, examples=[ - 'obb.etf.info("SPY", provider="fmp")', - "#### This function accepts multiple tickers. ####", - 'obb.etf.info("SPY,IWM,QQQ,DJIA", provider="fmp")', + APIEx(parameters={"symbol": "SPY", "provider": "fmp"}), + APIEx( + description="This function accepts multiple tickers.", + parameters={"symbol": "SPY,IWM,QQQ,DJIA", "provider": "fmp"}, + ), ], ) async def info( @@ -81,10 +89,7 @@ async def info( @router.command( model="EtfSectors", - exclude_auto_examples=True, - examples=[ - 'obb.etf.sectors("SPY", provider="fmp")', - ], + examples=[APIEx(parameters={"symbol": "SPY", "provider": "fmp"})], ) async def sectors( cc: CommandContext, @@ -98,10 +103,7 @@ async def sectors( @router.command( model="EtfCountries", - exclude_auto_examples=True, - examples=[ - 'obb.etf.countries("VT", provider="fmp")', - ], + examples=[APIEx(parameters={"symbol": "VT", "provider": "fmp"})], ) async def countries( cc: CommandContext, @@ -115,9 +117,9 @@ async def countries( @router.command( model="PricePerformance", - exclude_auto_examples=True, examples=[ - 'obb.etf.price_performance("SPY,QQQ,IWM,DJIA", provider="fmp")', + APIEx(parameters={"symbol": "QQQ", "provider": "fmp"}), + APIEx(parameters={"symbol": "SPY,QQQ,IWM,DJIA", "provider": "fmp"}), ], ) async def price_performance( @@ -132,13 +134,16 @@ async def price_performance( @router.command( model="EtfHoldings", - exclude_auto_examples=True, examples=[ - 'obb.etf.holdings("XLK", provider="fmp").to_df()', - "#### Including a date (FMP, SEC) will return the holdings as per NPORT-P filings. ####", - 'obb.etf.holdings("XLK", date="2022-03-31",provider="fmp").to_df()', - "#### The same data can be returned from the SEC directly. ####", - 'obb.etf.holdings("XLK", date="2022-03-31",provider="sec").to_df()', + APIEx(parameters={"symbol": "XLK", "provider": "fmp"}), + APIEx( + description="Including a date (FMP, SEC) will return the holdings as per NPORT-P filings.", + parameters={"symbol": "XLK", "date": "2022-03-31", "provider": "fmp"}, + ), + APIEx( + description="The same data can be returned from the SEC directly.", + parameters={"symbol": "XLK", "date": "2022-03-31", "provider": "sec"}, + ), ], ) async def holdings( @@ -153,10 +158,7 @@ async def holdings( @router.command( model="EtfHoldingsDate", - exclude_auto_examples=True, - examples=[ - 'obb.etf.holdings_date("XLK", provider="fmp").results', - ], + examples=[APIEx(parameters={"symbol": "XLK", "provider": "fmp"})], ) async def holdings_date( cc: CommandContext, @@ -170,10 +172,7 @@ async def holdings_date( @router.command( model="EtfHoldingsPerformance", - exclude_auto_examples=True, - examples=[ - 'obb.etf.holdings_performance("XLK", provider="fmp")', - ], + examples=[APIEx(parameters={"symbol": "XLK", "provider": "fmp"})], ) async def holdings_performance( cc: CommandContext, @@ -187,11 +186,12 @@ async def holdings_performance( @router.command( model="EtfEquityExposure", - exclude_auto_examples=True, examples=[ - 'obb.etf.equity_exposure("MSFT", provider="fmp")', - "#### This function accepts multiple tickers. ####", - 'obb.etf.equity_exposure("MSFT,AAPL", provider="fmp")', + APIEx(parameters={"symbol": "MSFT", "provider": "fmp"}), + APIEx( + description="This function accepts multiple tickers.", + parameters={"symbol": "MSFT,AAPL", "provider": "fmp"}, + ), ], ) async def equity_exposure( diff --git a/openbb_platform/extensions/fixedincome/openbb_fixedincome/corporate/corporate_router.py b/openbb_platform/extensions/fixedincome/openbb_fixedincome/corporate/corporate_router.py index a655e66f64e7..18631946f2eb 100644 --- a/openbb_platform/extensions/fixedincome/openbb_fixedincome/corporate/corporate_router.py +++ b/openbb_platform/extensions/fixedincome/openbb_fixedincome/corporate/corporate_router.py @@ -1,6 +1,7 @@ """Fixed Income Corporate Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -17,9 +18,9 @@ @router.command( model="ICEBofA", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.corporate.ice_bofa(index_type="yield_to_worst")', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"index_type": "yield_to_worst", "provider": "fred"}), ], ) async def ice_bofa( @@ -41,9 +42,9 @@ async def ice_bofa( @router.command( model="MoodyCorporateBondIndex", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.corporate.moody(index_type="baa")', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"index_type": "baa", "provider": "fred"}), ], ) async def moody( @@ -64,8 +65,10 @@ async def moody( @router.command( model="HighQualityMarketCorporateBond", - exclude_auto_examples=True, - examples=['obb.fixedincome.corporate.hqm(yield_curve="par")'], + examples=[ + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"yield_curve": "par", "provider": "fred"}), + ], ) async def hqm( cc: CommandContext, @@ -85,9 +88,9 @@ async def hqm( @router.command( model="SpotRate", - exclude_auto_examples=True, examples=[ - "obb.fixedincome.corporate.spot_rates(maturity=[10,20,30,50])", + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"maturity": "10,20,30,50", "provider": "fred"}), ], ) async def spot_rates( @@ -108,9 +111,9 @@ async def spot_rates( @router.command( model="CommercialPaper", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.corporate.commercial_paper(maturity="15d")', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"maturity": "15d", "provider": "fred"}), ], ) async def commercial_paper( @@ -129,7 +132,7 @@ async def commercial_paper( return await OBBject.from_query(Query(**locals())) -@router.command(model="BondPrices") +@router.command(model="BondPrices", examples=[APIEx(parameters={"provider": "tmx"})]) async def bond_prices( cc: CommandContext, provider_choices: ProviderChoices, diff --git a/openbb_platform/extensions/fixedincome/openbb_fixedincome/fixedincome_router.py b/openbb_platform/extensions/fixedincome/openbb_fixedincome/fixedincome_router.py index 01182a13666e..feac9a5898ec 100644 --- a/openbb_platform/extensions/fixedincome/openbb_fixedincome/fixedincome_router.py +++ b/openbb_platform/extensions/fixedincome/openbb_fixedincome/fixedincome_router.py @@ -3,6 +3,7 @@ # pylint: disable=W0613:unused-argument from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -26,9 +27,9 @@ @router.command( model="SOFR", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.fixedincome.sofr(period="overnight")', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"period": "overnight", "provider": "fred"}), ], ) async def sofr( diff --git a/openbb_platform/extensions/fixedincome/openbb_fixedincome/government/government_router.py b/openbb_platform/extensions/fixedincome/openbb_fixedincome/government/government_router.py index a817f7933f03..7d7a325eb7ad 100644 --- a/openbb_platform/extensions/fixedincome/openbb_fixedincome/government/government_router.py +++ b/openbb_platform/extensions/fixedincome/openbb_fixedincome/government/government_router.py @@ -1,6 +1,7 @@ """Fixed Income Government Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -17,9 +18,9 @@ @router.command( model="USYieldCurve", - exclude_auto_examples=True, examples=[ - "obb.fixedincome.government.us_yield_curve(inflation_adjusted=True)", + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"inflation_adjusted": True, "provider": "fred"}), ], ) async def us_yield_curve( @@ -34,9 +35,9 @@ async def us_yield_curve( @router.command( model="EUYieldCurve", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.government.eu_yield_curve(yield_curve_type="spot_rate")', + APIEx(parameters={"provider": "ecb"}), + APIEx(parameters={"yield_curve_type": "spot_rate", "provider": "ecb"}), ], ) async def eu_yield_curve( @@ -70,10 +71,7 @@ async def eu_yield_curve( @router.command( model="TreasuryRates", - exclude_auto_examples=True, - examples=[ - 'obb.fixedincome.government.treasury_rates(provider="federal_reserve")', - ], + examples=[APIEx(parameters={"provider": "fmp"})], ) async def treasury_rates( cc: CommandContext, @@ -87,10 +85,16 @@ async def treasury_rates( @router.command( model="TreasuryAuctions", - exclude_auto_examples=True, examples=[ - "obb.fixedincome.government.treasury_auctions(" - + 'security_type="Bill", start_date="2022-01-01", end_date="2023-01-01', + APIEx(parameters={"provider": "government_us"}), + APIEx( + parameters={ + "security_type": "Bill", + "start_date": "2022-01-01", + "end_date": "2023-01-01", + "provider": "government_us", + } + ), ], ) async def treasury_auctions( @@ -105,9 +109,9 @@ async def treasury_auctions( @router.command( model="TreasuryPrices", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.government.treasury_prices(date="2019-02-05")', + APIEx(parameters={"provider": "government_us"}), + APIEx(parameters={"date": "2019-02-05", "provider": "government_us"}), ], ) async def treasury_prices( diff --git a/openbb_platform/extensions/fixedincome/openbb_fixedincome/rate/rate_router.py b/openbb_platform/extensions/fixedincome/openbb_fixedincome/rate/rate_router.py index d192b7d4c08d..709b9c279049 100644 --- a/openbb_platform/extensions/fixedincome/openbb_fixedincome/rate/rate_router.py +++ b/openbb_platform/extensions/fixedincome/openbb_fixedincome/rate/rate_router.py @@ -1,6 +1,7 @@ """Fixed Income Rate Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -17,9 +18,9 @@ @router.command( model="AMERIBOR", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.rate.ameribor(parameter="30_day_ma").to_df()', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"parameter": "30_day_ma", "provider": "fred"}), ], ) async def ameribor( @@ -39,9 +40,9 @@ async def ameribor( @router.command( model="SONIA", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.rate.sonia(parameter="total_nominal_value")', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"parameter": "total_nominal_value", "provider": "fred"}), ], ) async def sonia( @@ -61,10 +62,7 @@ async def sonia( @router.command( model="IORB", - exclude_auto_examples=True, - examples=[ - "obb.fixedincome.rate.iorb()", - ], + examples=[APIEx(parameters={"provider": "fred"})], ) async def iorb( cc: CommandContext, @@ -83,9 +81,9 @@ async def iorb( @router.command( model="FEDFUNDS", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.rate.effr(parameter="daily", provider="fred").to_df()', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"parameter": "daily", "provider": "fred"}), ], ) async def effr( @@ -105,9 +103,9 @@ async def effr( @router.command( model="PROJECTIONS", - exclude_auto_examples=True, examples=[ - "obb.fixedincome.rate.effr_forecast(long_run=True)", + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"long_run": True, "provider": "fred"}), ], ) async def effr_forecast( @@ -128,9 +126,9 @@ async def effr_forecast( @router.command( model="ESTR", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.rate.estr(parameter="number_of_active_banks")', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"parameter": "number_of_active_banks", "provider": "fred"}), ], ) async def estr( @@ -151,9 +149,9 @@ async def estr( @router.command( model="EuropeanCentralBankInterestRates", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.rate.ecb(interest_rate_type="refinancing")', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"interest_rate_type": "refinancing", "provider": "fred"}), ], ) async def ecb( @@ -176,9 +174,15 @@ async def ecb( @router.command( model="DiscountWindowPrimaryCreditRate", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.rate.dpcredit(start_date="2023-02-01", end_date="2023-05-01").to_df()', + APIEx(parameters={"provider": "fred"}), + APIEx( + parameters={ + "start_date": "2023-02-01", + "end_date": "2023-05-01", + "provider": "fred", + } + ), ], ) async def dpcredit( diff --git a/openbb_platform/extensions/fixedincome/openbb_fixedincome/spreads/spreads_router.py b/openbb_platform/extensions/fixedincome/openbb_fixedincome/spreads/spreads_router.py index b45705465926..1c0ee460911f 100644 --- a/openbb_platform/extensions/fixedincome/openbb_fixedincome/spreads/spreads_router.py +++ b/openbb_platform/extensions/fixedincome/openbb_fixedincome/spreads/spreads_router.py @@ -1,6 +1,7 @@ """Fixed Income Corporate Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -17,9 +18,9 @@ @router.command( model="TreasuryConstantMaturity", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.fixedincome.spreads.tcm(maturity="2y")', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"maturity": "2y", "provider": "fred"}), ], ) async def tcm( @@ -40,9 +41,9 @@ async def tcm( @router.command( model="SelectedTreasuryConstantMaturity", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.fixedincome.spreads.tcm_effr(maturity="10y")', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"maturity": "10y", "provider": "fred"}), ], ) async def tcm_effr( @@ -63,9 +64,9 @@ async def tcm_effr( @router.command( model="SelectedTreasuryBill", - exclude_auto_examples=True, examples=[ - 'obb.fixedincome.fixedincome.spreads.treasury_effr(maturity="6m")', + APIEx(parameters={"provider": "fred"}), + APIEx(parameters={"maturity": "6m", "provider": "fred"}), ], ) async def treasury_effr( diff --git a/openbb_platform/extensions/index/openbb_index/index_router.py b/openbb_platform/extensions/index/openbb_index/index_router.py index cd85c4de9694..80c4b7bae5e6 100644 --- a/openbb_platform/extensions/index/openbb_index/index_router.py +++ b/openbb_platform/extensions/index/openbb_index/index_router.py @@ -2,6 +2,7 @@ from openbb_core.app.deprecation import OpenBBDeprecationWarning from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -27,6 +28,7 @@ since=(4, 1), expected_removal=(4, 3), ), + examples=[APIEx(parameters={"symbol": "^IBEX", "provider": "fmp"})], ) async def market( cc: CommandContext, @@ -40,11 +42,12 @@ async def market( @router.command( model="IndexConstituents", - exclude_auto_examples=True, examples=[ - 'obb.index.constituents("dowjones", provider="fmp").to_df()', - "#### Providers other than FMP will use the ticker symbol. ####", - 'obb.index.constituents("BEP50P", provider="cboe").to_df()', + APIEx(parameters={"symbol": "dowjones", "provider": "fmp"}), + APIEx( + description="Providers other than FMP will use the ticker symbol.", + parameters={"symbol": "BEP50P", "provider": "cboe"}, + ), ], ) async def constituents( @@ -59,9 +62,9 @@ async def constituents( @router.command( model="IndexSnapshots", - exclude_auto_examples=True, examples=[ - 'obb.index.snapshots(region="us",provider="cboe").to_df()', + APIEx(parameters={"provider": "tmx"}), + APIEx(parameters={"region": "us", "provider": "cboe"}), ], ) async def snapshots( @@ -76,9 +79,9 @@ async def snapshots( @router.command( model="AvailableIndices", - exclude_auto_examples=True, examples=[ - 'obb.index.available(provider="yfinance").to_df()', + APIEx(parameters={"provider": "fmp"}), + APIEx(parameters={"provider": "yfinance"}), ], ) async def available( @@ -93,9 +96,9 @@ async def available( @router.command( model="IndexSearch", - exclude_auto_examples=True, examples=[ - "obb.index.search(query='SPX', provider='cboe').to_df()", + APIEx(parameters={"provider": "cboe"}), + APIEx(parameters={"query": "SPX", "provider": "cboe"}), ], ) async def search( @@ -110,9 +113,9 @@ async def search( @router.command( model="SP500Multiples", - exclude_auto_examples=True, examples=[ - 'obb.index.sp500_multiples(series_name="shiller_pe_year", provider="nasdaq").to_df()', + APIEx(parameters={"provider": "nasdaq"}), + APIEx(parameters={"series_name": "shiller_pe_year", "provider": "nasdaq"}), ], ) async def sp500_multiples( @@ -127,10 +130,7 @@ async def sp500_multiples( @router.command( model="IndexSectors", - exclude_auto_examples=True, - examples=[ - 'obb.index.sectors(symbol="^TX60", provider="tmx").to_df()', - ], + examples=[APIEx(parameters={"symbol": "^TX60", "provider": "tmx"})], ) async def sectors( cc: CommandContext, diff --git a/openbb_platform/extensions/index/openbb_index/price/price_router.py b/openbb_platform/extensions/index/openbb_index/price/price_router.py index c5f44332eff7..883427d5f4cc 100644 --- a/openbb_platform/extensions/index/openbb_index/price/price_router.py +++ b/openbb_platform/extensions/index/openbb_index/price/price_router.py @@ -1,6 +1,7 @@ """Price Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -17,11 +18,12 @@ @router.command( model="IndexHistorical", - exclude_auto_examples=True, examples=[ - 'obb.index.price.historical("^GSPC", provider="fmp").to_df()', - "#### Not all providers have the same symbols. ####", - 'obb.index.price.historical("SPX", provider="intrinio").to_df()', + APIEx(parameters={"symbol": "^GSPC", "provider": "fmp"}), + APIEx( + description="Not all providers have the same symbols.", + parameters={"symbol": "SPX", "provider": "intrinio"}, + ), ], ) async def historical( diff --git a/openbb_platform/extensions/news/openbb_news/news_router.py b/openbb_platform/extensions/news/openbb_news/news_router.py index 00546ac6602a..1a964f363b9b 100644 --- a/openbb_platform/extensions/news/openbb_news/news_router.py +++ b/openbb_platform/extensions/news/openbb_news/news_router.py @@ -2,6 +2,7 @@ """News Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -17,16 +18,32 @@ @router.command( model="WorldNews", examples=[ - "# Get news on the specified dates.", - "obb.news.world(start_date='2024-02-01', end_date='2024-02-07')", - "# Display the headlines of the news.", - "obb.news.world(display='headline', provider='benzinga')", - "# Get news by topics.", - "obb.news.world(topics='finance', provider='benzinga')", - "# Get news by source using 'tingo' as provider.", - "obb.news.world(provider='tiingo', source='bloomberg')", - "# Filter aticles by term using 'biztoc' as provider.", - "obb.news.world(provider='biztoc', term='apple')", + APIEx(parameters={"provider": "fmp"}), + APIEx(parameters={"limit": 100, "provider": "intrinio"}), + APIEx( + description="Get news on the specified dates.", + parameters={ + "start_date": "2024-02-01", + "end_date": "2024-02-07", + "provider": "intrinio", + }, + ), + APIEx( + description="Display the headlines of the news.", + parameters={"display": "headline", "provider": "benzinga"}, + ), + APIEx( + description="Get news by topics.", + parameters={"topics": "finance", "provider": "benzinga"}, + ), + APIEx( + description="Get news by source using 'tingo' as provider.", + parameters={"provider": "tiingo", "source": "bloomberg"}, + ), + APIEx( + description="Filter aticles by term using 'biztoc' as provider.", + parameters={"provider": "biztoc", "term": "apple"}, + ), ], ) async def world( @@ -42,14 +59,37 @@ async def world( @router.command( model="CompanyNews", examples=[ - "# Get news on the specified dates.", - "obb.news.company(symbol='AAPL', start_date='2024-02-01', end_date='2024-02-07')", - "# Display the headlines of the news.", - "obb.news.company(symbol='AAPL', display='headline', provider='benzinga')", - "# Get news for multiple symbols.", - "obb.news.company(symbol='aapl,tsla')", - "# Get news company's ISIN.", - "obb.news.company(symbol='NVDA', isin='US0378331005')", + APIEx(parameters={"provider": "benzinga"}), + APIEx(parameters={"limit": 100, "provider": "benzinga"}), + APIEx( + description="Get news on the specified dates.", + parameters={ + "symbol": "AAPL", + "start_date": "2024-02-01", + "end_date": "2024-02-07", + "provider": "intrinio", + }, + ), + APIEx( + description="Display the headlines of the news.", + parameters={ + "symbol": "AAPL", + "display": "headline", + "provider": "benzinga", + }, + ), + APIEx( + description="Get news for multiple symbols.", + parameters={"symbol": "aapl,tsla", "provider": "fmp"}, + ), + APIEx( + description="Get news company's ISIN.", + parameters={ + "symbol": "NVDA", + "isin": "US0378331005", + "provider": "benzinga", + }, + ), ], ) async def company( diff --git a/openbb_platform/extensions/quantitative/openbb_quantitative/performance/performance_router.py b/openbb_platform/extensions/quantitative/openbb_quantitative/performance/performance_router.py index 92bd611a3802..025df52bb20a 100644 --- a/openbb_platform/extensions/quantitative/openbb_quantitative/performance/performance_router.py +++ b/openbb_platform/extensions/quantitative/openbb_quantitative/performance/performance_router.py @@ -2,6 +2,7 @@ import numpy as np import pandas as pd +from openbb_core.app.model.example import APIEx, PythonEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.router import Router from openbb_core.app.utils import ( @@ -22,9 +23,23 @@ @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.omega_ratio(data=returns, target="close")', + PythonEx( + description="Get Omega Ratio.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.performance.omega_ratio(data=returns, target="close")', + ], + ), + APIEx( + parameters={ + "target": "close", + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + }, + ), ], ) def omega_ratio( @@ -81,9 +96,24 @@ def get_omega_ratio(df_target: pd.Series, threshold: float) -> float: @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.sharpe_ratio(data=returns, target="close")', + PythonEx( + description="Get Rolling Sharpe Ratio.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 # pylint: disable=line-too-long + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.performance.sharpe_ratio(data=returns, target="close")', + ], + ), + APIEx( + parameters={ + "target": "close", + "window": 2, + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + }, + ), ], ) def sharpe_ratio( @@ -135,10 +165,25 @@ def sharpe_ratio( @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.sortino_ratio(data=stock_data, target="close")', - 'obb.quantitative.sortino_ratio(data=stock_data, target="close", target_return=0.01, window=126, adjusted=True)', + PythonEx( + description="Get Rolling Sortino Ratio.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.performance.sortino_ratio(data=stock_data, target="close")', + 'obb.quantitative.performance.sortino_ratio(data=stock_data, target="close", target_return=0.01, window=126, adjusted=True)', # noqa: E501 pylint: disable=line-too-long + ], + ), + APIEx( + parameters={ + "target": "close", + "window": 2, + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + }, + ), ], ) def sortino_ratio( @@ -185,7 +230,7 @@ def sortino_ratio( df = basemodel_to_df(data, index=index) series_target = get_target_column(df, target) validate_window(series_target, window) - returns = series_target.pct_change().dropna().rolling(window).sum() + returns = series_target.pct_change().dropna().rolling(window).sum().dropna() downside_deviation = returns.rolling(window).apply( lambda x: (x.values[x.values < 0]).std() / np.sqrt(252) * 100 ) @@ -196,8 +241,9 @@ def sortino_ratio( ) if adjusted: - results = results / np.sqrt(2) - + results = results.applymap( + lambda x: x / np.sqrt(2) if isinstance(x, float) else x + ) results_ = df_to_basemodel(results) return OBBject(results=results_) diff --git a/openbb_platform/extensions/quantitative/openbb_quantitative/quantitative_router.py b/openbb_platform/extensions/quantitative/openbb_quantitative/quantitative_router.py index bede1e9ac84e..0065ec62011b 100644 --- a/openbb_platform/extensions/quantitative/openbb_quantitative/quantitative_router.py +++ b/openbb_platform/extensions/quantitative/openbb_quantitative/quantitative_router.py @@ -3,6 +3,7 @@ from typing import List, Literal import pandas as pd +from openbb_core.app.model.example import APIEx, PythonEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.router import Router from openbb_core.app.utils import ( @@ -38,8 +39,14 @@ @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", - "obb.quantitative.normality(data=stock_data, target='close')", + PythonEx( + description="Get Normality Statistics.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 + "obb.quantitative.normality(data=stock_data, target='close')", + ], + ), + APIEx(parameters={"target": "close", "data": APIEx.mock_data("timeseries", 8)}), ], ) def normality(data: List[Data], target: str) -> OBBject[NormalityModel]: @@ -88,8 +95,16 @@ def normality(data: List[Data], target: str) -> OBBject[NormalityModel]: @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", - "obb.quantitative.capm(data=stock_data, target='close')", + PythonEx( + description="Get Capital Asset Pricing Model (CAPM).", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 + "obb.quantitative.capm(data=stock_data, target='close')", + ], + ), + APIEx( + parameters={"target": "close", "data": APIEx.mock_data("timeseries", 31)} + ), ], ) def capm(data: List[Data], target: str) -> OBBject[CAPMModel]: @@ -142,7 +157,19 @@ def capm(data: List[Data], target: str) -> OBBject[CAPMModel]: return OBBject(results=results) -@router.command(methods=["POST"]) +@router.command( + methods=["POST"], + examples=[ + PythonEx( + description="Get Unit Root Test.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 + "obb.quantitative.unitroot_test(data=stock_data, target='close')", + ], + ), + APIEx(parameters={"target": "close", "data": APIEx.mock_data("timeseries", 5)}), + ], +) def unitroot_test( data: List[Data], target: str, @@ -201,7 +228,19 @@ def unitroot_test( return OBBject(results=unitroot_summary) -@router.command(methods=["POST"]) +@router.command( + methods=["POST"], + examples=[ + PythonEx( + description="Get Summary Statistics.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501 + "obb.quantitative.summary(data=stock_data, target='close')", + ], + ), + APIEx(parameters={"target": "close", "data": APIEx.mock_data("timeseries", 5)}), + ], +) def summary(data: List[Data], target: str) -> OBBject[SummaryModel]: """Get Summary Statistics. diff --git a/openbb_platform/extensions/quantitative/openbb_quantitative/rolling/rolling_router.py b/openbb_platform/extensions/quantitative/openbb_quantitative/rolling/rolling_router.py index c2cc5c7a1aed..fb02b5f051a7 100644 --- a/openbb_platform/extensions/quantitative/openbb_quantitative/rolling/rolling_router.py +++ b/openbb_platform/extensions/quantitative/openbb_quantitative/rolling/rolling_router.py @@ -3,6 +3,7 @@ from typing import List import pandas as pd +from openbb_core.app.model.example import APIEx, PythonEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.router import Router from openbb_core.app.utils import ( @@ -27,9 +28,24 @@ @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.rolling.skew(data=returns, target="close")', + PythonEx( + description="Get Rolling Mean.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.rolling.skew(data=returns, target="close")', + ], + ), + APIEx( + parameters={ + "target": "close", + "window": 2, + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def skew( @@ -76,9 +92,24 @@ def skew( @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.rolling.variance(data=returns, target="close", window=252)', + PythonEx( + description="Get Rolling Variance.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.rolling.variance(data=returns, target="close", window=252)', + ], + ), + APIEx( + parameters={ + "target": "close", + "window": 2, + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def variance( @@ -90,15 +121,16 @@ def variance( Variance measures the dispersion of a set of data points around their mean. It is a key metric for assessing the volatility and stability of financial returns or other time series data over a specified rolling window. - Parameters: - data: List[Data] - The time series data as a list of data points. - target: str - The name of the column for which to calculate variance. - window: PositiveInt - The number of observations used for calculating the rolling measure. - index: str, optional - The name of the index column, default is "date". + Parameters + ---------- + data: List[Data] + The time series data as a list of data points. + target: str + The name of the column for which to calculate variance. + window: PositiveInt + The number of observations used for calculating the rolling measure. + index: str, optional + The name of the index column, default is "date". Returns: ------- @@ -118,9 +150,24 @@ def variance( @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.rolling.stdev(data=returns, target="close", window=252)', + PythonEx( + description="Get Rolling Standard Deviation.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.rolling.stdev(data=returns, target="close", window=252)', + ], + ), + APIEx( + parameters={ + "target": "close", + "window": 2, + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def stdev( @@ -133,15 +180,16 @@ def stdev( It is widely used to assess the risk and volatility of financial returns or other time series data over a specified rolling window. It is the square root of the variance. - Parameters: - data: List[Data] - The time series data as a list of data points. - target: str - The name of the column for which to calculate standard deviation. - window: PositiveInt - The number of observations used for calculating the rolling measure. - index: str, optional - The name of the index column, default is "date". + Parameters + ---------- + data: List[Data] + The time series data as a list of data points. + target: str + The name of the column for which to calculate standard deviation. + window: PositiveInt + The number of observations used for calculating the rolling measure. + index: str, optional + The name of the index column, default is "date". Returns: ------- @@ -164,9 +212,24 @@ def stdev( @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.rolling.kurtosis(data=returns, target="close", window=252)', + PythonEx( + description="Get Rolling Kurtosis.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.rolling.kurtosis(data=returns, target="close", window=252)', + ], + ), + APIEx( + parameters={ + "target": "close", + "window": 2, + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def kurtosis( @@ -181,15 +244,16 @@ def kurtosis( This function helps in assessing the risk of outliers in financial returns or other time series data over a specified rolling window. - Parameters: - data: List[Data] - The time series data as a list of data points. - target: str - The name of the column for which to calculate kurtosis. - window: PositiveInt - The number of observations used for calculating the rolling measure. - index: str, optional - The name of the index column, default is "date". + Parameters + ---------- + data: List[Data] + The time series data as a list of data points. + target: str + The name of the column for which to calculate kurtosis. + window: PositiveInt + The number of observations used for calculating the rolling measure. + index: str, optional + The name of the index column, default is "date". Returns: ------- @@ -212,10 +276,25 @@ def kurtosis( @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.rolling.quantile(data=returns, target="close", window=252, quantile_pct=0.25)', - 'obb.quantitative.rolling.quantile(data=returns, target="close", window=252, quantile_pct=0.75)', + PythonEx( + description="Get Rolling Quantile.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.rolling.quantile(data=returns, target="close", window=252, quantile_pct=0.25)', + 'obb.quantitative.rolling.quantile(data=returns, target="close", window=252, quantile_pct=0.75)', + ], + ), + APIEx( + parameters={ + "target": "close", + "window": 2, + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def quantile( @@ -232,17 +311,18 @@ def quantile( or dividing the sample in the same way. This function is useful for understanding the distribution of data within a specified window, allowing for analysis of trends, identification of outliers, and assessment of risk. - Parameters: - data: List[Data] - The time series data as a list of data points. - target: str - The name of the column for which to calculate the quantile. - window: PositiveInt - The number of observations used for calculating the rolling measure. - quantile_pct: NonNegativeFloat, optional - The quantile percentage to calculate (e.g., 0.5 for median), default is 0.5. - index: str, optional - The name of the index column, default is "date". + Parameters + ---------- + data: List[Data] + The time series data as a list of data points. + target: str + The name of the column for which to calculate the quantile. + window: PositiveInt + The number of observations used for calculating the rolling measure. + quantile_pct: NonNegativeFloat, optional + The quantile percentage to calculate (e.g., 0.5 for median), default is 0.5. + index: str, optional + The name of the index column, default is "date". Returns: ------- @@ -277,9 +357,24 @@ def quantile( @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.rolling.mean(data=returns, target="close", window=252)', + PythonEx( + description="Get Rolling Mean.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.rolling.mean(data=returns, target="close", window=252)', + ], + ), + APIEx( + parameters={ + "target": "close", + "window": 2, + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def mean( @@ -292,15 +387,16 @@ def mean( This function is widely used in financial analysis to smooth short-term fluctuations and highlight longer-term trends or cycles in time series data. - Parameters: - data: List[Data] - The time series data as a list of data points. - target: str - The name of the column for which to calculate the mean. - window: PositiveInt - The number of observations used for calculating the rolling measure. - index: str, optional - The name of the index column, default is "date". + Parameters + ---------- + data: List[Data] + The time series data as a list of data points. + target: str + The name of the column for which to calculate the mean. + window: PositiveInt + The number of observations used for calculating the rolling measure. + index: str, optional + The name of the index column, default is "date". Returns: OBBject[List[Data]] diff --git a/openbb_platform/extensions/quantitative/openbb_quantitative/stats/stats_router.py b/openbb_platform/extensions/quantitative/openbb_quantitative/stats/stats_router.py index 56ab1017ecfb..41e93a160208 100644 --- a/openbb_platform/extensions/quantitative/openbb_quantitative/stats/stats_router.py +++ b/openbb_platform/extensions/quantitative/openbb_quantitative/stats/stats_router.py @@ -3,6 +3,7 @@ from typing import List import pandas as pd +from openbb_core.app.model.example import APIEx, PythonEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.router import Router from openbb_core.app.utils import ( @@ -26,9 +27,23 @@ @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.stats.skew(data=returns, target="close")', + PythonEx( + description="Get Skewness.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.stats.skew(data=returns, target="close")', + ], + ), + APIEx( + parameters={ + "target": "close", + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def skew( @@ -67,9 +82,23 @@ def skew( @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.stats.variance(data=returns, target="close")', + PythonEx( + description="Get Variance.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.stats.variance(data=returns, target="close")', + ], + ), + APIEx( + parameters={ + "target": "close", + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def variance(data: List[Data], target: str) -> OBBject[List[Data]]: @@ -102,9 +131,23 @@ def variance(data: List[Data], target: str) -> OBBject[List[Data]]: @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.stats.stdev(data=returns, target="close")', + PythonEx( + description="Get Standard Deviation.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.stats.stdev(data=returns, target="close")', + ], + ), + APIEx( + parameters={ + "target": "close", + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def stdev(data: List[Data], target: str) -> OBBject[List[Data]]: @@ -112,8 +155,8 @@ def stdev(data: List[Data], target: str) -> OBBject[List[Data]]: Calculate the rolling standard deviation of a target column. Standard deviation is a measure of the amount of variation or dispersion of a set of values. - It is widely used to assess the risk and volatility of financial returns or other time series data - It is the square root of the variance. + It is widely used to assess the risk and volatility of financial returns or other time series data + It is the square root of the variance. Parameters ---------- @@ -139,9 +182,23 @@ def stdev(data: List[Data], target: str) -> OBBject[List[Data]]: @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.stats.kurtosis(data=returns, target="close")', + PythonEx( + description="Get Kurtosis.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.stats.kurtosis(data=returns, target="close")', + ], + ), + APIEx( + parameters={ + "target": "close", + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def kurtosis(data: List[Data], target: str) -> OBBject[List[Data]]: @@ -177,9 +234,23 @@ def kurtosis(data: List[Data], target: str) -> OBBject[List[Data]]: @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.stats.quantile(data=returns, target="close", quantile_pct=0.75)', + PythonEx( + description="Get Quantile.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.stats.quantile(data=returns, target="close", quantile_pct=0.75)', + ], + ), + APIEx( + parameters={ + "target": "close", + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def quantile( @@ -222,9 +293,23 @@ def quantile( @router.command( methods=["POST"], examples=[ - 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', - 'returns = stock_data["close"].pct_change().dropna()', - 'obb.quantitative.stats.mean(data=returns, target="close")', + PythonEx( + description="Get Mean.", + code=[ + 'stock_data = obb.equity.price.historical(symbol="TSLA", start_date="2023-01-01", provider="fmp").to_df()', # noqa: E501 + 'returns = stock_data["close"].pct_change().dropna()', + 'obb.quantitative.stats.mean(data=returns, target="close")', + ], + ), + APIEx( + parameters={ + "target": "close", + "data": APIEx.mock_data( + "timeseries", + sample={"date": "2023-01-01", "close": 0.05}, + ), + } + ), ], ) def mean( diff --git a/openbb_platform/extensions/regulators/openbb_regulators/cftc/cftc_router.py b/openbb_platform/extensions/regulators/openbb_regulators/cftc/cftc_router.py index 4ed99f219654..eb5e1e642aae 100644 --- a/openbb_platform/extensions/regulators/openbb_regulators/cftc/cftc_router.py +++ b/openbb_platform/extensions/regulators/openbb_regulators/cftc/cftc_router.py @@ -2,6 +2,7 @@ """Commodity Futures Trading Commission (CFTC) Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -16,9 +17,9 @@ @router.command( model="COTSearch", - exclude_auto_examples=True, examples=[ - 'obb.regulators.cftc.cot_search(query="gold")', + APIEx(parameters={"provider": "nasdaq"}), + APIEx(parameters={"query": "gold", "provider": "nasdaq"}), ], ) async def cot_search( @@ -36,13 +37,20 @@ async def cot_search( @router.command( model="COT", - exclude_auto_examples=True, examples=[ - 'obb.regulators.cftc.cot(series_id="GC=F").to_df()', - "#### Enter the report ID by the Nasdaq Data Link Code. ####", - 'obb.regulators.cftc.cot(series_id="088691").to_df()', - "### Get the report for futures only. ####", - 'obb.regulators.cftc.cot(series_id="088691", data_type="F").to_df()', + APIEx(parameters={"provider": "nasdaq"}), + APIEx( + description="Get the Commitment of Traders Report for Gold.", + parameters={"id": "GC=F", "provider": "nasdaq"}, + ), + APIEx( + description="Enter the report ID by the Nasdaq Data Link Code.", + parameters={"id": "088691", "provider": "nasdaq"}, + ), + APIEx( + description="Get the report for futures only.", + parameters={"id": "088691", "data_type": "F", "provider": "nasdaq"}, + ), ], ) async def cot( diff --git a/openbb_platform/extensions/regulators/openbb_regulators/sec/sec_router.py b/openbb_platform/extensions/regulators/openbb_regulators/sec/sec_router.py index cd03a1c53a07..df212ad35c72 100644 --- a/openbb_platform/extensions/regulators/openbb_regulators/sec/sec_router.py +++ b/openbb_platform/extensions/regulators/openbb_regulators/sec/sec_router.py @@ -2,6 +2,7 @@ """SEC Router.""" from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx, PythonEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.provider_interface import ( ExtraParams, @@ -16,11 +17,7 @@ @router.command( model="CikMap", - exclude_auto_examples=True, - examples=[ - 'obb.regulators.sec.cik_map(symbol="MSFT").results.cik', - " 0000789019", - ], + examples=[APIEx(parameters={"symbol": "MSFT", "provider": "sec"})], ) async def cik_map( cc: CommandContext, @@ -34,9 +31,9 @@ async def cik_map( @router.command( model="InstitutionsSearch", - exclude_auto_examples=True, examples=[ - 'obb.regulators.sec.institutions_search(query="blackstone real estate").to_df()' + APIEx(parameters={"provider": "sec"}), + APIEx(parameters={"query": "blackstone real estate", "provider": "sec"}), ], ) async def institutions_search( @@ -51,25 +48,30 @@ async def institutions_search( @router.command( model="SchemaFiles", - exclude_auto_examples=True, examples=[ - "data = obb.regulators.sec.schema_files()", - "data.files[0]", - " https://xbrl.fasb.org/us-gaap/", - "#### The directory structure can be navigated by constructing a URL from the 'results' list. ####", - "url = data.files[0]+data.files[-1]", - "#### The URL base will always be the 0 position in the list, feed the URL back in as a parameter. ####", - "obb.regulators.sec.schema_files(url=url).results.files", - " ['https://xbrl.fasb.org/us-gaap/2024/'", - " 'USGAAP2024FileList.xml'", - " 'dis/'", - " 'dqcrules/'", - " 'ebp/'", - " 'elts/'", - " 'entire/'", - " 'meta/'", - " 'stm/'", - " 'us-gaap-2024.zip']", + APIEx(parameters={"provider": "sec"}), + PythonEx( + description="Get a list of schema files.", + code=[ + "data = obb.regulators.sec.schema_files().results", + "data.files[0]", + "'https://xbrl.fasb.org/us-gaap/'", + "# The directory structure can be navigated by constructing a URL from the 'results' list.", + "url = data.files[0]+data.files[-1]", + "# The URL base will always be the 0 position in the list, feed the URL back in as a parameter.", + "obb.regulators.sec.schema_files(url=url).results.files", + "['https://xbrl.fasb.org/us-gaap/2024/'", + "'USGAAP2024FileList.xml'", + "'dis/'", + "'dqcrules/'", + "'ebp/'", + "'elts/'", + "'entire/'", + "'meta/'", + "'stm/'", + "'us-gaap-2024.zip']", + ], + ), ], ) async def schema_files( @@ -84,8 +86,7 @@ async def schema_files( @router.command( model="SymbolMap", - exclude_auto_examples=True, - examples=['obb.regulators.sec.symbol_map("0000789019").results.symbol', " MSFT"], + examples=[APIEx(parameters={"query": "0000789019", "provider": "sec"})], ) async def symbol_map( cc: CommandContext, @@ -99,8 +100,7 @@ async def symbol_map( @router.command( model="RssLitigation", - exclude_auto_examples=True, - examples=['obb.regulators.sec.rss_litigation().to_dict("records")[0]'], + examples=[APIEx(parameters={"provider": "sec"})], ) async def rss_litigation( cc: CommandContext, @@ -114,9 +114,9 @@ async def rss_litigation( @router.command( model="SicSearch", - exclude_auto_examples=True, examples=[ - 'obb.regulators.sec.sic_search("real estate investment trusts").results', + APIEx(parameters={"provider": "sec"}), + APIEx(parameters={"query": "real estate investment trusts", "provider": "sec"}), ], ) async def sic_search( diff --git a/openbb_platform/extensions/technical/openbb_technical/helpers.py b/openbb_platform/extensions/technical/openbb_technical/helpers.py index 3bf3363665e6..c6a22f3fd170 100644 --- a/openbb_platform/extensions/technical/openbb_technical/helpers.py +++ b/openbb_platform/extensions/technical/openbb_technical/helpers.py @@ -1,7 +1,7 @@ """Technical Analysis Helpers.""" import warnings -from typing import Any, Literal, Optional, Tuple +from typing import Any, List, Literal, Optional, Tuple, Union import numpy as np import pandas as pd @@ -9,6 +9,17 @@ _warn = warnings.warn +def validate_data(data: list, length: Union[int, List[int]]) -> None: + """Validate data.""" + if isinstance(length, int): + length = [length] + for item in length: + if item > len(data): + raise ValueError( + f"Data length is less than required by parameters: {max(length)}" + ) + + def parkinson( data: pd.DataFrame, window: int = 30, diff --git a/openbb_platform/extensions/technical/openbb_technical/technical_router.py b/openbb_platform/extensions/technical/openbb_technical/technical_router.py index 245ac33c7994..53cd2a2e91e0 100644 --- a/openbb_platform/extensions/technical/openbb_technical/technical_router.py +++ b/openbb_platform/extensions/technical/openbb_technical/technical_router.py @@ -5,6 +5,7 @@ import pandas as pd import pandas_ta as ta +from openbb_core.app.model.example import APIEx, PythonEx from openbb_core.app.model.obbject import OBBject from openbb_core.app.router import Router from openbb_core.app.utils import ( @@ -16,7 +17,12 @@ from openbb_core.provider.abstract.data import Data from pydantic import NonNegativeFloat, NonNegativeInt, PositiveFloat, PositiveInt -from . import helpers +from .helpers import ( + calculate_cones, + calculate_fib_levels, + clenow_momentum, + validate_data, +) # TODO: Split this into multiple files router = Router(prefix="") @@ -25,8 +31,14 @@ @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "atr_data = obb.technical.atr(data=stock_data.results)", + PythonEx( + description="Get the Average True Range.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "atr_data = obb.technical.atr(data=stock_data.results)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def atr( @@ -67,6 +79,7 @@ def atr( OBBject[List[Data]] List of data with the indicator applied. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["high", "low", "close"]) df_atr = pd.DataFrame( @@ -82,8 +95,14 @@ def atr( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "fib_data = obb.technical.fib(data=stock_data.results, period=120)", + PythonEx( + description="Get the Bollinger Band Width.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "fib_data = obb.technical.fib(data=stock_data.results, period=120)", + ], + ), + APIEx(parameters={"data": APIEx.mock_data("timeseries")}), ], ) def fib( @@ -125,7 +144,7 @@ def fib( min_pr, max_pr, lvl_text, - ) = helpers.calculate_fib_levels( + ) = calculate_fib_levels( data=df, close_col=close_column, limit=period, @@ -147,8 +166,14 @@ def fib( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "obv_data = obb.technical.obv(data=stock_data.results, offset=0)", + PythonEx( + description="Get the On Balance Volume (OBV).", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "obv_data = obb.technical.obv(data=stock_data.results, offset=0)", + ], + ), + APIEx(parameters={"data": APIEx.mock_data("timeseries")}), ], ) def obv( @@ -194,8 +219,14 @@ def obv( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "fisher_data = obb.technical.fisher(data=stock_data.results, length=14, signal=1)", + PythonEx( + description="Perform the Fisher Transform.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "fisher_data = obb.technical.fisher(data=stock_data.results, length=14, signal=1)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def fisher( @@ -228,6 +259,7 @@ def fisher( OBBject[List[Data]] List of data with the indicator applied. """ + validate_data(data, [length, signal]) df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["high", "low"]) df_fisher = pd.DataFrame(df_target.ta.fisher(length=length, signal=signal)) @@ -241,8 +273,14 @@ def fisher( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "adosc_data = obb.technical.adosc(data=stock_data.results, fast=3, slow=10, offset=0)", + PythonEx( + description="Get the Accumulation/Distribution Oscillator.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "adosc_data = obb.technical.adosc(data=stock_data.results, fast=3, slow=10, offset=0)", + ], + ), + APIEx(parameters={"fast": 2, "slow": 4, "data": APIEx.mock_data("timeseries")}), ], ) def adosc( @@ -278,8 +316,9 @@ def adosc( ------- OBBject[List[Data]] """ + validate_data(data, [fast, slow]) df = basemodel_to_df(data, index=index) - df_target = get_target_columns(df, ["high", "low", "close", "volume", "open"]) + df_target = get_target_columns(df, ["open", "high", "low", "close", "volume"]) df_adosc = pd.DataFrame(df_target.ta.adosc(fast=fast, slow=slow, offset=offset)) output = pd.concat([df, df_adosc], axis=1) @@ -291,8 +330,14 @@ def adosc( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "bbands_data = obb.technical.bbands(data=stock_data.results, target='close', length=50, std=2, mamode='sma')", + PythonEx( + description="Get the Chande Momentum Oscillator.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "bbands_data = obb.technical.bbands(data=stock_data.results, target='close', length=50, std=2, mamode='sma')", # noqa: E501 + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def bbands( @@ -341,6 +386,7 @@ def bbands( OBBject[List[Data]] The calculated data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() bbands_df = pd.DataFrame( @@ -363,8 +409,14 @@ def bbands( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "zlma_data = obb.technical.zlma(data=stock_data.results, target='close', length=50, offset=0)", + PythonEx( + description="Get the Chande Momentum Oscillator.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "zlma_data = obb.technical.zlma(data=stock_data.results, target='close', length=50, offset=0)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def zlma( @@ -401,6 +453,7 @@ def zlma( OBBject[List[Data]] The calculated data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() zlma_df = pd.DataFrame( @@ -421,8 +474,14 @@ def zlma( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "aaron_data = obb.technical.aroon(data=stock_data.results, length=25, scalar=100)", + PythonEx( + description="Get the Chande Momentum Oscillator.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "aaron_data = obb.technical.aroon(data=stock_data.results, length=25, scalar=100)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def aroon( @@ -461,11 +520,12 @@ def aroon( OBBject[List[Data]] The calculated data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["high", "low", "close"]) - aroon_df = pd.DataFrame(df_target.ta.aroon(length=length, scalar=scalar)).dropna() + df_aroon = pd.DataFrame(df_target.ta.aroon(length=length, scalar=scalar)).dropna() - output = pd.concat([df, aroon_df], axis=1) + output = pd.concat([df, df_aroon], axis=1) results = df_to_basemodel(output.reset_index()) return OBBject(results=results) @@ -474,8 +534,14 @@ def aroon( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "sma_data = obb.technical.sma(data=stock_data.results, target='close', length=50, offset=0)", + PythonEx( + description="Get the Chande Momentum Oscillator.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "sma_data = obb.technical.sma(data=stock_data.results, target='close', length=50, offset=0)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def sma( @@ -513,6 +579,7 @@ def sma( OBBject[List[Data]] The calculated data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() sma_df = pd.DataFrame( @@ -533,8 +600,14 @@ def sma( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "demark_data = obb.technical.demark(data=stock_data.results, offset=0)", + PythonEx( + description="Get the Demark Sequential Indicator.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "demark_data = obb.technical.demark(data=stock_data.results, offset=0)", + ], + ), + APIEx(parameters={"data": APIEx.mock_data("timeseries")}), ], ) def demark( @@ -587,8 +660,14 @@ def demark( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "vwap_data = obb.technical.vwap(data=stock_data.results, anchor='D', offset=0)", + PythonEx( + description="Get the Volume Weighted Average Price (VWAP).", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "vwap_data = obb.technical.vwap(data=stock_data.results, anchor='D', offset=0)", + ], + ), + APIEx(parameters={"data": APIEx.mock_data("timeseries")}), ], ) def vwap( @@ -637,8 +716,22 @@ def vwap( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "macd_data = obb.technical.macd(data=stock_data.results, target='close', fast=12, slow=26, signal=9)", + PythonEx( + description="Get the Moving Average Convergence Divergence (MACD).", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "macd_data = obb.technical.macd(data=stock_data.results, target='close', fast=12, slow=26, signal=9)", + ], + ), + APIEx( + description="Example with mock data.", + parameters={ + "fast": 2, + "slow": 3, + "signal": 1, + "data": APIEx.mock_data("timeseries"), + }, + ), ], ) def macd( @@ -680,6 +773,7 @@ def macd( OBBject[List[Data]] The calculated data. """ + validate_data(data, [fast, slow, signal]) df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() macd_df = pd.DataFrame( @@ -700,8 +794,13 @@ def macd( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "hma_data = obb.technical.hma(data=stock_data.results, target='close', length=50, offset=0)", + PythonEx( + description="Calculate HMA with historical stock data.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "hma_data = obb.technical.hma(data=stock_data.results, target='close', length=50, offset=0)", + ], + ), ], ) def hma( @@ -736,6 +835,7 @@ def hma( OBBject[List[Data]] The calculated data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() hma_df = pd.DataFrame( @@ -756,8 +856,20 @@ def hma( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "donchian_data = obb.technical.donchian(data=stock_data.results, lower_length=20, upper_length=20, offset=0)", + PythonEx( + description="Get the Donchian Channels.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "donchian_data = obb.technical.donchian(data=stock_data.results, lower_length=20, upper_length=20, offset=0)", # noqa: E501 + ], + ), + APIEx( + parameters={ + "lower_length": 1, + "upper_length": 3, + "data": APIEx.mock_data("timeseries"), + } + ), ], ) def donchian( @@ -793,6 +905,7 @@ def donchian( OBBject[List[Data]] The calculated data. """ + validate_data(data, [lower_length, upper_length]) df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["high", "low"]) donchian_df = pd.DataFrame( @@ -810,8 +923,14 @@ def donchian( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "ichimoku_data = obb.technical.ichimoku(data=stock_data.results, conversion=9, base=26, lookahead=False)", + PythonEx( + description="Get the Ichimoku Cloud.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "ichimoku_data = obb.technical.ichimoku(data=stock_data.results, conversion=9, base=26, lookahead=False)", + ], + ), + APIEx(parameters={"data": APIEx.mock_data("timeseries")}), ], ) def ichimoku( @@ -874,8 +993,14 @@ def ichimoku( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "clenow_data = obb.technical.clenow(data=stock_data.results, period=90)", + PythonEx( + description="Get the Clenow Volatility Adjusted Momentum.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "clenow_data = obb.technical.clenow(data=stock_data.results, period=90)", + ], + ), + APIEx(parameters={"period": 2, "data": APIEx.mock_data("timeseries")}), ], ) def clenow( @@ -906,10 +1031,11 @@ def clenow( OBBject[List[Data]] The calculated data. """ + validate_data(data, period) df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target) - r2, coef, _ = helpers.clenow_momentum(df_target, period) + r2, coef, _ = clenow_momentum(df_target, period) df_clenow = pd.DataFrame.from_dict( { @@ -929,8 +1055,14 @@ def clenow( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "ad_data = obb.technical.ad(data=stock_data.results, offset=0)", + PythonEx( + description="Get the Accumulation/Distribution Line.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "ad_data = obb.technical.ad(data=stock_data.results, offset=0)", + ], + ), + APIEx(parameters={"data": APIEx.mock_data("timeseries")}), ], ) def ad(data: List[Data], index: str = "date", offset: int = 0) -> OBBject[List[Data]]: @@ -975,8 +1107,14 @@ def ad(data: List[Data], index: str = "date", offset: int = 0) -> OBBject[List[D @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "adx_data = obb.technical.adx(data=stock_data.results, length=50, scalar=100.0, drift=1)", + PythonEx( + description="Get the Average Directional Index (ADX).", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "adx_data = obb.technical.adx(data=stock_data.results, length=50, scalar=100.0, drift=1)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def adx( @@ -1010,13 +1148,14 @@ def adx( OBBject[List[Data]] The calculated data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["close", "high", "low"]) - adx_df = pd.DataFrame( + df_adx = pd.DataFrame( df_target.ta.adx(length=length, scalar=scalar, drift=drift).dropna() ) - output = pd.concat([df, adx_df], axis=1) + output = pd.concat([df, df_adx], axis=1) results = df_to_basemodel(output.reset_index()) return OBBject(results=results) @@ -1025,8 +1164,14 @@ def adx( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "wma_data = obb.technical.wma(data=stock_data.results, target='close', length=50, offset=0)", + PythonEx( + description="Get the Average True Range (ATR).", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "wma_data = obb.technical.wma(data=stock_data.results, target='close', length=50, offset=0)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def wma( @@ -1061,9 +1206,10 @@ def wma( OBBject[List[Data]] The WMA data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() - wma_df = pd.DataFrame( + df_wma = pd.DataFrame( df_target.ta.wma( length=length, offset=offset, @@ -1072,7 +1218,7 @@ def wma( ).dropna() ) - output = pd.concat([df, wma_df], axis=1) + output = pd.concat([df, df_wma], axis=1) results = df_to_basemodel(output.reset_index()) return OBBject(results=results) @@ -1081,8 +1227,14 @@ def wma( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "cci_data = obb.technical.cci(data=stock_data.results, length=14, scalar=0.015)", + PythonEx( + description="Get the Commodity Channel Index (CCI).", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "cci_data = obb.technical.cci(data=stock_data.results, length=14, scalar=0.015)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def cci( @@ -1115,6 +1267,7 @@ def cci( OBBject[List[Data]] The CCI data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["close", "high", "low"]) cci_df = pd.DataFrame(df_target.ta.cci(length=length, scalar=scalar).dropna()) @@ -1128,8 +1281,14 @@ def cci( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "rsi_data = obb.technical.rsi(data=stock_data.results, target='close', length=14, scalar=100.0, drift=1)", + PythonEx( + description="Get the Relative Strength Index (RSI).", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "rsi_data = obb.technical.rsi(data=stock_data.results, target='close', length=14, scalar=100.0, drift=1)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def rsi( @@ -1168,6 +1327,7 @@ def rsi( OBBject[List[Data]] The RSI data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() rsi_df = pd.DataFrame( @@ -1189,8 +1349,13 @@ def rsi( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "stoch_data = obb.technical.stoch(data=stock_data.results, fast_k_period=14, slow_d_period=3, slow_k_period=3)", + PythonEx( + description="Get the Stochastic Oscillator.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "stoch_data = obb.technical.stoch(data=stock_data.results, fast_k_period=14, slow_d_period=3, slow_k_period=3)", # noqa: E501 # pylint: disable=line-too-long + ], + ), ], ) def stoch( @@ -1227,6 +1392,7 @@ def stoch( OBBject[List[Data]] The Stochastic Oscillator data. """ + validate_data(data, [fast_k_period, slow_d_period, slow_k_period]) df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["close", "high", "low"]) stoch_df = pd.DataFrame( @@ -1246,8 +1412,14 @@ def stoch( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "kc_data = obb.technical.kc(data=stock_data.results, length=20, scalar=20, mamode='ema', offset=0)", + PythonEx( + description="Get the Keltner Channels.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "kc_data = obb.technical.kc(data=stock_data.results, length=20, scalar=20, mamode='ema', offset=0)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def kc( @@ -1286,6 +1458,7 @@ def kc( OBBject[List[Data]] The Keltner Channels data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["high", "low", "close"]) kc_df = pd.DataFrame( @@ -1305,8 +1478,14 @@ def kc( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "cg_data = obb.technical.cg(data=stock_data.results, length=14)", + PythonEx( + description="Get the Center of Gravity (CG).", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "cg_data = obb.technical.cg(data=stock_data.results, length=14)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def cg( @@ -1334,6 +1513,7 @@ def cg( OBBject[List[Data]] The COG data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_columns(df, ["high", "low", "close"]) cg_df = pd.DataFrame(df_target.ta.cg(length=length).dropna()) @@ -1347,8 +1527,14 @@ def cg( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "cones_data = obb.technical.cones(data=stock_data.results, lower_q=0.25, upper_q=0.75, model='STD')", + PythonEx( + description="Get the cones indicator.", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "cones_data = obb.technical.cones(data=stock_data.results, lower_q=0.25, upper_q=0.75, model='STD')", + ], + ), + APIEx(parameters={"data": APIEx.mock_data("timeseries")}), ], ) def cones( @@ -1429,7 +1615,7 @@ def cones( lower_q, upper_q = upper_q, lower_q df = basemodel_to_df(data, index=index) - df_cones = helpers.calculate_cones( + df_cones = calculate_cones( data=df, lower_q=lower_q, upper_q=upper_q, @@ -1446,8 +1632,14 @@ def cones( @router.command( methods=["POST"], examples=[ - "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", - "ema_data = obb.technical.ema(data=stock_data.results, target='close', length=50, offset=0)", + PythonEx( + description="Get the Exponential Moving Average (EMA).", + code=[ + "stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')", + "ema_data = obb.technical.ema(data=stock_data.results, target='close', length=50, offset=0)", + ], + ), + APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}), ], ) def ema( @@ -1482,6 +1674,7 @@ def ema( OBBject[List[Data]] The calculated data. """ + validate_data(data, length) df = basemodel_to_df(data, index=index) df_target = get_target_column(df, target).to_frame() ema_df = pd.DataFrame( diff --git a/openbb_platform/extensions/tests/test_routers.py b/openbb_platform/extensions/tests/test_routers.py index 31c690ce1b91..863979dc4ffb 100644 --- a/openbb_platform/extensions/tests/test_routers.py +++ b/openbb_platform/extensions/tests/test_routers.py @@ -1,6 +1,7 @@ """Test the routers.""" from extensions.tests.utils.router_testers import ( + check_router_command_examples, check_router_function_models, check_router_model_functions_signature, ) @@ -16,3 +17,14 @@ def test_router_model_functions_signature() -> None: """Test if the router functions have the correct signature.""" missing_args = check_router_model_functions_signature() assert not missing_args, "\n".join(missing_args) + + +def test_router_examples_rules() -> None: + """Test if the router examples follow certain rules. + + Rules: + - All endpoints should have examples. + - At least one example using all required parameters. + """ + invalid_examples = check_router_command_examples() + assert not invalid_examples, "\n".join(sorted(invalid_examples)) diff --git a/openbb_platform/extensions/tests/utils/helpers.py b/openbb_platform/extensions/tests/utils/helpers.py index ad15ae75fb5b..14ee9126f789 100644 --- a/openbb_platform/extensions/tests/utils/helpers.py +++ b/openbb_platform/extensions/tests/utils/helpers.py @@ -1,12 +1,20 @@ """Test helpers.""" +import ast import doctest import glob import importlib +import inspect import logging import os +import re from importlib.metadata import entry_points -from typing import Dict, List, Set, Tuple +from inspect import getmembers, isfunction +from typing import Any, Dict, List, Set, Tuple + +from openbb_core.app.provider_interface import ProviderInterface + +pi = ProviderInterface() logging.basicConfig(level=logging.INFO) @@ -25,37 +33,21 @@ def get_packages_info() -> Dict[str, str]: return paths_and_names -def execute_docstring_examples( - module_name: str, file_path: str, verbose: bool = False -) -> List[str]: +def execute_docstring_examples(module_name: str, path: str) -> List[str]: """Execute the docstring examples of a module.""" errors = [] - module_name = f"openbb.package.{module_name}" - module = importlib.import_module(module_name) - examples = doctest.DocTestFinder().find(module) + module = importlib.import_module(f"openbb.package.{module_name}") + doc_tests = doctest.DocTestFinder().find(module) - def execute_script(script, source_info): + for dt in doc_tests: + code = "".join([ex.source for ex in dt.examples]) try: - local_namespace = {} - exec( # noqa: S102 pylint: disable=exec-used - script, local_namespace, local_namespace - ) - if verbose: - logging.info("Executed a test from %s", source_info) + exec(code) # pylint: disable=exec-used # noqa: S102 except Exception as e: errors.append( - f"An exception occurred while executing script from {source_info} - {str(e)}" + f"\n\n{'_'*136}\nPath: {path}\nCode:\n{code}\nError: {str(e)}" ) - for example in examples: - script_lines = [] - - for test in example.examples: - script_lines.append(test.source) - - script_content = "".join(script_lines) - execute_script(script_content, file_path) - return errors @@ -65,7 +57,7 @@ def check_docstring_examples() -> List[str]: paths_and_names = get_packages_info() for path, name in paths_and_names.items(): - result = execute_docstring_examples(name, path, verbose=True) + result = execute_docstring_examples(name, path) if result: errors.extend(result) @@ -73,8 +65,7 @@ def check_docstring_examples() -> List[str]: def list_openbb_extensions() -> Tuple[Set[str], Set[str], Set[str]]: - """ - Lists installed openbb extensions and providers. + """List installed openbb extensions and providers. Returns ------- @@ -99,3 +90,184 @@ def list_openbb_extensions() -> Tuple[Set[str], Set[str], Set[str]]: obbject_extensions.add(f"{entry_point.name}") return core_extensions, provider_extensions, obbject_extensions + + +def collect_routers(target_dir: str) -> List[str]: + """Collect all routers in the target directory.""" + current_dir = os.path.dirname(__file__) + base_path = os.path.abspath(os.path.join(current_dir, "../../../")) + + full_target_path = os.path.abspath(os.path.join(base_path, target_dir)) + routers = [] + + for root, _, files in os.walk(full_target_path): + for name in files: + if name.endswith("_router.py"): + full_path = os.path.join(root, name) + # Convert the full path to a module path + relative_path = os.path.relpath(full_path, base_path) + module_path = relative_path.replace("/", ".").replace(".py", "") + routers.append(module_path) + + return routers + + +def import_routers(routers: List) -> List: + """Import all routers.""" + loaded_routers: List = [] + for router in routers: + module = importlib.import_module(router) + loaded_routers.append(module) + + return loaded_routers + + +def collect_router_functions(loaded_routers: List) -> Dict: + """Collect all router functions.""" + router_functions = {} + for router in loaded_routers: + router_functions[router.__name__] = [ + function[1] + for function in getmembers(router, isfunction) + if function[0] != "router" + ] + + return router_functions + + +def find_decorator(file_path: str, function_name: str) -> str: + """Find the @router.command decorator of the function in the file, supporting multiline decorators.""" + this_dir = os.path.dirname(os.path.abspath(__file__)) + file_path = os.path.join( + this_dir.split("openbb_platform/")[0], "openbb_platform", file_path + ) + + with open(file_path) as file: + lines = file.readlines() + + decorator_lines = [] + capturing_decorator = False + for line in lines: + stripped_line = line.strip() + # Start capturing lines if we encounter a decorator + if stripped_line.startswith("@router.command"): + capturing_decorator = True + decorator_lines.append(stripped_line) + elif capturing_decorator: + # If we're currently capturing a decorator and the line is part of it (indentation or open parenthesis) + if ( + stripped_line.startswith("@") + or "def" in stripped_line + and function_name in stripped_line + ): + # If we've reached another decorator or the function definition, stop capturing + capturing_decorator = False + # If it's the target function, break, else clear decorator_lines for the next decorator + if "def" in stripped_line and function_name in stripped_line: + break + decorator_lines = [] + else: + # It's part of the multiline decorator + decorator_lines.append(stripped_line) + + decorator = " ".join(decorator_lines) + return decorator + + +def get_decorator_details(function): + """Extract decorators and their arguments from a function as dictionaries.""" + source = inspect.getsource(function) + parsed_source = ast.parse(source) + + if isinstance(parsed_source.body[0], (ast.FunctionDef, ast.AsyncFunctionDef)): + func_def = parsed_source.body[0] + for decorator in func_def.decorator_list: + decorator_detail = {"decorator": "", "args": {}, "keywords": {}} + if isinstance(decorator, ast.Call): + decorator_detail["decorator"] = ( + decorator.func.id + if isinstance(decorator.func, ast.Name) + else ast.unparse(decorator.func) + ) + decorator_detail["args"] = { + i: ast.unparse(arg) for i, arg in enumerate(decorator.args) + } + decorator_detail["keywords"] = { + kw.arg: ast.unparse(kw.value) for kw in decorator.keywords + } + else: + decorator_detail["decorator"] = ( + decorator.id + if isinstance(decorator, ast.Name) + else ast.unparse(decorator) + ) + + return decorator_detail + + +def find_missing_router_function_models( + router_functions: Dict, pi_map: Dict +) -> List[str]: + """Find the missing models in the router functions.""" + missing_models: List[str] = [] + for router_name, functions in router_functions.items(): + for function in functions: + decorator = find_decorator( + os.path.join(*router_name.split(".")) + ".py", + function.__name__, + ) + if ( + decorator + and "model" in decorator + and "POST" not in decorator + and "GET" not in decorator + ): + model = decorator.split("model=")[1].split(",")[0].strip('"') + if ( + model not in pi_map + and "POST" not in decorator + and "GET" not in decorator + ): + missing_models.append( + f"{function.__name__} in {router_name} model doesn't exist in the provider interface map." + ) + + return missing_models + + +def parse_example_string(example_string: str) -> Dict[str, Any]: + """Parses a string of examples into nested dictionaries. + + This is capturing all instances of PythonEx and APIEx, including their "parameters", "code", and "description". + """ + # Initialize the result dictionary + result = {} + + # Regular expression patterns to find PythonEx and APIEx examples + pythonex_pattern = r"PythonEx\(.*?code=(\[.*?\]).*?\)" + apiex_pattern = r"APIEx\(.*?parameters=(\{.*?\}).*?\)" + + # Function to parse individual examples + def parse_examples(matches, example_type): + examples = [] + for match in matches: + examples.append( + {"code": [match]} if example_type == "PythonEx" else {"params": match} + ) + return examples + + # Find and parse all PythonEx examples + pythonex_matches = re.findall(pythonex_pattern, example_string, re.DOTALL) + result["PythonEx"] = parse_examples(pythonex_matches, "PythonEx") + + # Find and parse all APIEx examples + apiex_matches = re.findall(apiex_pattern, example_string, re.DOTALL) + result["APIEx"] = parse_examples(apiex_matches, "APIEx") + + return result + + +def get_required_fields(model: str) -> List[str]: + """Get the required fields of a model.""" + fields = pi.map[model]["openbb"]["QueryParams"]["fields"] + return [field for field, info in fields.items() if info.is_required()] diff --git a/openbb_platform/extensions/tests/utils/router_testers.py b/openbb_platform/extensions/tests/utils/router_testers.py index bbc9ff3b7ec5..918b9e7850d6 100644 --- a/openbb_platform/extensions/tests/utils/router_testers.py +++ b/openbb_platform/extensions/tests/utils/router_testers.py @@ -1,97 +1,21 @@ """Router testers.""" -import importlib +import ast import os -from inspect import getmembers, isfunction -from typing import Dict, List, Optional +from typing import Any, Dict, List, Optional from openbb_core.app.provider_interface import ProviderInterface - -def collect_routers(target_dir: str) -> List[str]: - """Collect all routers in the target directory.""" - current_dir = os.path.dirname(__file__) - base_path = os.path.abspath(os.path.join(current_dir, "../../../")) - - full_target_path = os.path.abspath(os.path.join(base_path, target_dir)) - routers = [] - - for root, _, files in os.walk(full_target_path): - for name in files: - if name.endswith("_router.py"): - full_path = os.path.join(root, name) - # Convert the full path to a module path - relative_path = os.path.relpath(full_path, base_path) - module_path = relative_path.replace("/", ".").replace(".py", "") - routers.append(module_path) - - return routers - - -def import_routers(routers: List) -> List: - """Import all routers.""" - loaded_routers: List = [] - for router in routers: - module = importlib.import_module(router) - loaded_routers.append(module) - - return loaded_routers - - -def collect_router_functions(loaded_routers: List) -> Dict: - """Collect all router functions.""" - router_functions = {} - for router in loaded_routers: - router_functions[router.__name__] = [ - function[1] - for function in getmembers(router, isfunction) - if function[0] != "router" - ] - - return router_functions - - -def find_decorator(file_path: str, function_name: str) -> Optional[str]: - """Find the decorator of the function in the file.""" - this_dir = os.path.dirname(os.path.abspath(__file__)) - file_path = os.path.join( - this_dir.split("openbb_platform/")[0], "openbb_platform", file_path - ) - with open(file_path) as file: - lines = file.readlines() - for index, line in enumerate(lines): - if function_name in line: - decorator = lines[index - 1] - if "@" not in decorator: - continue - decorator = decorator.split('"')[1] - return decorator - - return None - - -def find_missing_router_function_models( - router_functions: Dict, pi_map: Dict -) -> List[str]: - """Find the missing models in the router functions.""" - missing_models: List[str] = [] - for router_name, functions in router_functions.items(): - for function in functions: - decorator = find_decorator( - os.path.join(*router_name.split(".")) + ".py", - function.__name__, - ) - if ( - decorator not in pi_map - and decorator is not None - and "POST" not in decorator - and "GET" not in decorator - ): - missing_models.append( - f"{function.__name__} in {router_name} model doesn't exist in the provider interface map." - ) - - return missing_models +from extensions.tests.utils.helpers import ( + collect_router_functions, + collect_routers, + find_decorator, + find_missing_router_function_models, + get_decorator_details, + get_required_fields, + import_routers, + parse_example_string, +) def check_router_function_models() -> List[str]: @@ -119,16 +43,17 @@ def check_router_model_functions_signature() -> List[str]: for router_name, functions in router_functions.items(): for function in functions: - decorator_filer = ["POST", "GET", None] decorator = find_decorator( os.path.join(*router_name.split(".")) + ".py", function.__name__, ) if decorator: + if "POST" in decorator or "GET" in decorator: + continue args = list(function.__code__.co_varnames) - if args != expected_args and decorator not in decorator_filer: + if args != expected_args and "model" in decorator: missing_args.append( - f"{function.__name__} in {router_name} doesn't have the expected args: {expected_args}" + f"{function.__name__} in {router_name} missing expected args: {expected_args}" ) if expected_return_type not in str(function.__annotations__["return"]): missing_return_type.append( @@ -137,3 +62,80 @@ def check_router_model_functions_signature() -> List[str]: ) return missing_args + missing_return_type + + +def check_general( + keywords: Dict, examples: List, router_name: str, function: Any +) -> List[str]: + """Check for general violations in the router command examples.""" + general_violation: List[str] = [] + + # Check if the endpoint has examples + if "examples" not in keywords or not examples: + general_violation.append( + f"'{router_name}' > '{function.__name__}': missing examples" + ) + return general_violation + + return general_violation + + +def check_api( + examples: str, router_name: str, model: Optional[str], function: Any +) -> List[str]: + """Check for API examples.""" + # Check if the endpoint has at least 1 example with all required fields + api_example_violation: List[str] = [] + parsed_examples = parse_example_string(examples) + if model and "APIEx" in parsed_examples: + required_fields = get_required_fields(model.strip("'")) + for api_example in parsed_examples["APIEx"]: + params = ast.literal_eval(api_example.get("params", "{}")) + if len(set(params.keys()) - set(required_fields) - {"provider"}) == 0: + break + else: + api_example_violation.append( + f"'{router_name}' > '{function.__name__}': missing example with required fields only > {required_fields}" + ) + + return api_example_violation + + +def check_router_command_examples() -> List[str]: + """Check if the router command examples satisfy criteria.""" + general_violation: List[str] = [] + api_example_violation: List[str] = [] + python_example_violation: List[str] = [] + + routers = collect_routers("extensions") + loaded_routers = import_routers(routers) + router_functions = collect_router_functions(loaded_routers) + + for router_name, functions in router_functions.items(): + for function in functions: + if ( + "basemodel_to_df" in function.__name__ + or "router" not in function.__module__ + ): + continue + decorator = find_decorator( + os.path.join(*router_name.split(".")) + ".py", + function.__name__, + ) + if decorator: + decorator_details = get_decorator_details(function) + if decorator_details["decorator"] == "router.command": + keywords = decorator_details["keywords"] + examples = keywords.get("examples", []) + # General checks + general_violation += check_general( + keywords, examples, router_name, function + ) + if examples: + # API example checks + model = keywords.get("model", None) + api_example_violation += check_api( + examples, router_name, model, function + ) + + return general_violation + api_example_violation + python_example_violation diff --git a/openbb_platform/openbb/package/crypto.py b/openbb_platform/openbb/package/crypto.py index f55c7884a884..7fe45375b17e 100644 --- a/openbb_platform/openbb/package/crypto.py +++ b/openbb_platform/openbb/package/crypto.py @@ -33,7 +33,12 @@ def search( query: Annotated[ Optional[str], OpenBBCustomParameter(description="Search query.") ] = None, - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Search available cryptocurrency pairs within a provider. @@ -74,12 +79,11 @@ def search( exchange_name : Optional[str] The short name of the exchange the crypto trades on. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.crypto.search() - >>> obb.crypto.search("BTCUSD") - >>> obb.crypto.search("ETH-USD") + >>> obb.crypto.search(provider='fmp') + >>> obb.crypto.search(query='BTCUSD', provider='fmp') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/crypto_price.py b/openbb_platform/openbb/package/crypto_price.py index 0572eacd4ef1..5d7e02ef8ef9 100644 --- a/openbb_platform/openbb/package/crypto_price.py +++ b/openbb_platform/openbb/package/crypto_price.py @@ -41,7 +41,12 @@ def historical( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fmp", "polygon", "tiingo", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "polygon", "tiingo", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get historical price data for cryptocurrency pair(s) within a provider. @@ -108,14 +113,14 @@ def historical( volume_notional : Optional[float] The last size done for the asset on the specific date in the quote currency. The volume of the asset on the specific date in the quote currency. (provider: tiingo) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.crypto.price.historical(symbol="BTCUSD") - >>> obb.crypto.price.historical("BTCUSD", start_date="2024-01-01", end_date="2024-01-31") - >>> obb.crypto.price.historical("ETH-USD", provider="yfinance", interval="1mo", start_date="2024-01-01", end_date="2024-12-31") - >>> obb.crypto.price.historical("BTCUSD,ETH-USD", provider="yfinance", interval="1d", start_date="2024-01-01", end_date="2024-01-31") - >>> obb.crypto.price.historical(["BTCUSD", "ETH-USD"], start_date="2024-01-01", end_date="2024-01-31") + >>> obb.crypto.price.historical(symbol='BTCUSD', provider='fmp') + >>> obb.crypto.price.historical(symbol='BTCUSD', start_date='2024-01-01', end_date='2024-01-31', provider='fmp') + >>> obb.crypto.price.historical(symbol='BTCUSD,ETHUSD', start_date='2024-01-01', end_date='2024-01-31', provider='polygon') + >>> # Get monthly historical prices from Yahoo Finance for Ethereum. + >>> obb.crypto.price.historical(symbol='ETH-USD', interval='1m', start_date='2024-01-01', end_date='2024-12-31', provider='yfinance') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/currency.py b/openbb_platform/openbb/package/currency.py index c30b0e2a54e7..aae2308b9a29 100644 --- a/openbb_platform/openbb/package/currency.py +++ b/openbb_platform/openbb/package/currency.py @@ -30,7 +30,14 @@ def price(self): @exception_handler @validate def search( - self, provider: Optional[Literal["fmp", "intrinio", "polygon"]] = None, **kwargs + self, + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "polygon"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, + **kwargs ) -> OBBject: """Currency Search. @@ -113,16 +120,16 @@ def search( delisted_utc : Optional[datetime] The delisted timestamp in UTC. (provider: polygon) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.currency.search() - >>> # Search for 'EURUSD' currency pair using 'polygon' as provider. - >>> obb.currency.search(provider='polygon', symbol='EURUSD') - >>> # Search for terms using 'polygon' as provider. - >>> obb.currency.search(provider='polygon', search='Euro zone') + >>> obb.currency.search(provider='intrinio') + >>> # Search for 'EURUSD' currency pair using 'intrinio' as provider. + >>> obb.currency.search(provider='intrinio', symbol='EURUSD') >>> # Search for actively traded currency pairs on the queried date using 'polygon' as provider. >>> obb.currency.search(provider='polygon', date='2024-01-02', active=True) + >>> # Search for terms using 'polygon' as provider. + >>> obb.currency.search(provider='polygon', search='Euro zone') """ # noqa: E501 return self._run( @@ -162,7 +169,12 @@ def snapshots( description="An optional list of counter currency symbols to filter for. None returns all." ), ] = None, - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Snapshots of currency exchange rates from an indirect or direct perspective of a base currency. @@ -229,12 +241,12 @@ def snapshots( last_rate_timestamp : Optional[datetime] The timestamp of the last rate. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.currency.snapshots( - >>> provider="fmp", base="USD,XAU", counter_currencies="EUR,JPY,GBP", quote_type="indirect" - >>> ) + >>> obb.currency.snapshots(provider='fmp') + >>> # Get exchange rates from USD and XAU to EUR, JPY, and GBP using 'fmp' as provider. + >>> obb.currency.snapshots(provider='fmp', base='USD,XAU', counter_currencies='EUR,JPY,GBP', quote_type='indirect') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/currency_price.py b/openbb_platform/openbb/package/currency_price.py index 2be0e311fe98..aa39e03e0911 100644 --- a/openbb_platform/openbb/package/currency_price.py +++ b/openbb_platform/openbb/package/currency_price.py @@ -41,7 +41,12 @@ def historical( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fmp", "polygon", "tiingo", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "polygon", "tiingo", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Currency Historical Price. Currency historical data. @@ -111,14 +116,14 @@ def historical( transactions : Optional[Annotated[int, Gt(gt=0)]] Number of transactions for the symbol in the time period. (provider: polygon) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.currency.price.historical(symbol="EURUSD") + >>> obb.currency.price.historical(symbol='EURUSD', provider='fmp') >>> # Filter historical data with specific start and end date. - >>> obb.currency.price.historical(symbol='EURUSD', start_date='2023-01-01', end_date='20213-12-31') + >>> obb.currency.price.historical(symbol='EURUSD', start_date='2023-01-01', end_date='2023-12-31', provider='fmp') >>> # Get data with different granularity. - >>> obb.currency.price.historical(symbol='EURUSD', interval='15m', provider='polygon') + >>> obb.currency.price.historical(symbol='EURUSD', provider='polygon', interval='15m') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/derivatives_options.py b/openbb_platform/openbb/package/derivatives_options.py index 492b6c872e41..c1e156d9a3de 100644 --- a/openbb_platform/openbb/package/derivatives_options.py +++ b/openbb_platform/openbb/package/derivatives_options.py @@ -26,7 +26,12 @@ def chains( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["intrinio"]] = None, + provider: Annotated[ + Optional[Literal["intrinio"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'intrinio' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the complete options chain for a ticker. @@ -147,12 +152,12 @@ def chains( exercise_style : Optional[str] The exercise style of the option, American or European. (provider: intrinio) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> chains = obb.derivatives.options.chains(symbol="AAPL", provider="intrinio").to_df() - >>> #### Use the "date" parameter to get the end-of-day-data for a specific date, where supported. #### - >>> eod_chains = obb.derivatives.options.chains(symbol="AAPL", date="2023-01-25", provider="intrinio").to_df() + >>> obb.derivatives.options.chains(symbol='AAPL', provider='intrinio') + >>> # Use the "date" parameter to get the end-of-day-data for a specific date, where supported. + >>> obb.derivatives.options.chains(symbol='AAPL', date='2023-01-25', provider='intrinio') """ # noqa: E501 return self._run( @@ -182,7 +187,12 @@ def unusual( description="Symbol to get data for. (the underlying symbol)" ), ] = None, - provider: Optional[Literal["intrinio"]] = None, + provider: Annotated[ + Optional[Literal["intrinio"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'intrinio' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the complete options chain for a ticker. @@ -237,12 +247,12 @@ def unusual( timestamp : Optional[datetime] The UTC timestamp of order placement. (provider: intrinio) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> options = obb.derivatives.options.unusual().to_df() - >>> #### Use the "symbol" parameter to get the most recent activity for a specific symbol. #### - >>> options = obb.derivatives.options.unusual(symbol="TSLA").to_df() + >>> obb.derivatives.options.unusual(provider='intrinio') + >>> # Use the 'symbol' parameter to get the most recent activity for a specific symbol. + >>> obb.derivatives.options.unusual(symbol='TSLA', provider='intrinio') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/economy.py b/openbb_platform/openbb/package/economy.py index 4b0149ad315e..3aa90603745e 100644 --- a/openbb_platform/openbb/package/economy.py +++ b/openbb_platform/openbb/package/economy.py @@ -49,7 +49,12 @@ def calendar( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fmp", "tradingeconomics"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "tradingeconomics"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the upcoming, or historical, economic calendar of global events. @@ -124,12 +129,12 @@ def calendar( created_at : Optional[datetime] Created at timestamp. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.calendar(provider="fmp", start_date="2020-03-01", end_date="2020-03-31") - >>> #### By default, the calendar will be forward-looking. #### - >>> obb.economy.calendar(provider="nasdaq") + >>> # By default, the calendar will be forward-looking. + >>> obb.economy.calendar(provider='fmp') + >>> obb.economy.calendar(provider='fmp', start_date='2020-03-01', end_date='2020-03-31') """ # noqa: E501 return self._run( @@ -166,7 +171,12 @@ def composite_leading_indicator( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["oecd"]] = None, + provider: Annotated[ + Optional[Literal["oecd"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'oecd' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """The composite leading indicator (CLI) is designed to provide early signals of turning points @@ -210,10 +220,11 @@ def composite_leading_indicator( country : Optional[str] Country for which CLI is given - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.composite_leading_indicator(country="all").to_df() + >>> obb.economy.composite_leading_indicator(provider='oecd') + >>> obb.economy.composite_leading_indicator(country='all', provider='oecd') """ # noqa: E501 return self._run( @@ -327,7 +338,12 @@ def cpi( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Consumer Price Index (CPI). Returns either the rescaled index value, or a rate of change (inflation). @@ -377,12 +393,12 @@ def cpi( date : date The date of the data. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.cpi(countries=["japan", "china", "turkey"]).to_df() - >>> #### Use the `units` parameter to define the reference period for the change in values. #### - >>> obb.economy.cpi(countries=["united_states", "united_kingdom"], units="growth_previous").to_df() + >>> obb.economy.cpi(country='japan,china,turkey', provider='fred') + >>> # Use the `units` parameter to define the reference period for the change in values. + >>> obb.economy.cpi(country='united_states,united_kingdom', units='growth_previous', provider='fred') """ # noqa: E501 return self._run( @@ -434,7 +450,12 @@ def fred_regional( Optional[int], OpenBBCustomParameter(description="The number of data entries to return."), ] = 100000, - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Query the Geo Fred API for regional economic data by series group. @@ -533,13 +554,12 @@ def fred_regional( series_id : Optional[str] The individual series ID for the region. (provider: fred) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> #### With no date, the most recent report is returned. #### - >>> obb.economy.fred_regional("NYICLAIMS") - >>> #### With a date, time series data is returned. #### - >>> obb.economy.fred_regional("NYICLAIMS", start_date="2021-01-01") + >>> obb.economy.fred_regional(symbol='NYICLAIMS', provider='fred') + >>> # With a date, time series data is returned. + >>> obb.economy.fred_regional(symbol='NYICLAIMS', start_date='2021-01-01', end_date='2021-12-31', limit=10, provider='fred') """ # noqa: E501 return self._run( @@ -570,7 +590,12 @@ def fred_search( query: Annotated[ Optional[str], OpenBBCustomParameter(description="The search word(s).") ] = None, - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Search for FRED series or economic releases by ID or string. @@ -662,10 +687,10 @@ def fred_search( series_group : Optional[Union[int, str]] The series group ID of the series. This value is used to query for regional data. (provider: fred) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.fred_search() + >>> obb.economy.fred_search(provider='fred') """ # noqa: E501 return self._run( @@ -711,7 +736,12 @@ def fred_series( Optional[int], OpenBBCustomParameter(description="The number of data entries to return."), ] = 100000, - provider: Optional[Literal["fred", "intrinio"]] = None, + provider: Annotated[ + Optional[Literal["fred", "intrinio"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get data by series ID from FRED. @@ -796,14 +826,14 @@ def fred_series( value : Optional[float] Value of the index. (provider: intrinio) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.fred_series("NFCI").to_df() - >>> #### Multiple series can be passed in as a list. #### - >>> obb.economy.fred_series(["NFCI","STLFSI4"]).to_df() - >>> #### Use the `transform` parameter to transform the data as change, log, or percent change. #### - >>> obb.economy.fred_series("CBBTCUSD", transform="pc1").to_df() + >>> obb.economy.fred_series(symbol='NFCI', provider='fred') + >>> # Multiple series can be passed in as a list. + >>> obb.economy.fred_series(symbol='NFCI,STLFSI4', provider='fred') + >>> # Use the `transform` parameter to transform the data as change, log, or percent change. + >>> obb.economy.fred_series(symbol='CBBTCUSD', transform='pc1', provider='fred') """ # noqa: E501 return self._run( @@ -850,7 +880,12 @@ def long_term_interest_rate( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["oecd"]] = None, + provider: Annotated[ + Optional[Literal["oecd"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'oecd' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Long-term interest rates refer to government bonds maturing in ten years. @@ -901,10 +936,11 @@ def long_term_interest_rate( country : Optional[str] Country for which interest rate is given - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.long_term_interest_rate(country="all", frequency="quarterly").to_df() + >>> obb.economy.long_term_interest_rate(provider='oecd') + >>> obb.economy.long_term_interest_rate(country='all', frequency='quarterly', provider='oecd') """ # noqa: E501 return self._run( @@ -947,7 +983,12 @@ def money_measures( description="Whether to return seasonally adjusted data." ), ] = True, - provider: Optional[Literal["federal_reserve"]] = None, + provider: Annotated[ + Optional[Literal["federal_reserve"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'federal_reserve' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Money Measures (M1/M2 and components). The Federal Reserve publishes as part of the H.6 Release. @@ -998,10 +1039,11 @@ def money_measures( small_denomination_time_deposits : Optional[float] Value of small denomination time deposits in billions. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.money_measures(adjusted=False).to_df() + >>> obb.economy.money_measures(provider='federal_reserve') + >>> obb.economy.money_measures(adjusted=False, provider='federal_reserve') """ # noqa: E501 return self._run( @@ -1026,7 +1068,14 @@ def money_measures( @exception_handler @validate def risk_premium( - self, provider: Optional[Literal["fmp"]] = None, **kwargs + self, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, + **kwargs ) -> OBBject: """Market Risk Premium by country. @@ -1062,10 +1111,10 @@ def risk_premium( country_risk_premium : Optional[Annotated[float, Ge(ge=0)]] Country-specific risk premium. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.risk_premium().to_df() + >>> obb.economy.risk_premium(provider='fmp') """ # noqa: E501 return self._run( @@ -1099,7 +1148,12 @@ def short_term_interest_rate( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["oecd"]] = None, + provider: Annotated[ + Optional[Literal["oecd"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'oecd' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Short-term interest rates are the rates at which short-term borrowings are effected between @@ -1147,10 +1201,11 @@ def short_term_interest_rate( country : Optional[str] Country for which interest rate is given - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.short_term_interest_rate(country="all", frequency="quarterly").to_df() + >>> obb.economy.short_term_interest_rate(provider='oecd') + >>> obb.economy.short_term_interest_rate(country='all', frequency='quarterly', provider='oecd') """ # noqa: E501 return self._run( @@ -1187,7 +1242,12 @@ def unemployment( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["oecd"]] = None, + provider: Annotated[ + Optional[Literal["oecd"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'oecd' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Global unemployment data. @@ -1236,14 +1296,13 @@ def unemployment( country : Optional[str] Country for which unemployment rate is given - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.unemployment(country="all", frequency="quarterly") - >>> #### Demographics for the statistics are selected with the `age` and `sex` parameters. #### - >>> obb.economy.unemployment( - >>> country="all", frequency="quarterly", age="25-54" - >>> ).to_df().pivot(columns="country", values="value") + >>> obb.economy.unemployment(provider='oecd') + >>> obb.economy.unemployment(country='all', frequency='quarterly', provider='oecd') + >>> # Demographics for the statistics are selected with the `age` and `sex` parameters. + >>> obb.economy.unemployment(country='all', frequency='quarterly', age='25-54', provider='oecd') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/economy_gdp.py b/openbb_platform/openbb/package/economy_gdp.py index 12d7fd201792..d4a4bb05a85f 100644 --- a/openbb_platform/openbb/package/economy_gdp.py +++ b/openbb_platform/openbb/package/economy_gdp.py @@ -49,7 +49,12 @@ def forecast( description="Type of GDP to get forecast of. Either nominal or real." ), ] = "real", - provider: Optional[Literal["oecd"]] = None, + provider: Annotated[ + Optional[Literal["oecd"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'oecd' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Forecasted GDP Data. @@ -92,10 +97,11 @@ def forecast( value : Optional[float] Nominal GDP value on the date. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.gdp.forecast(period="annual", type="real") + >>> obb.economy.gdp.forecast(provider='oecd') + >>> obb.economy.gdp.forecast(period='annual', type='real', provider='oecd') """ # noqa: E501 return self._run( @@ -140,7 +146,12 @@ def nominal( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["oecd"]] = None, + provider: Annotated[ + Optional[Literal["oecd"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'oecd' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Nominal GDP Data. @@ -181,10 +192,11 @@ def nominal( value : Optional[float] Nominal GDP value on the date. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.gdp.nominal(units="usd") + >>> obb.economy.gdp.nominal(provider='oecd') + >>> obb.economy.gdp.nominal(units='usd', provider='oecd') """ # noqa: E501 return self._run( @@ -228,7 +240,12 @@ def real( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["oecd"]] = None, + provider: Annotated[ + Optional[Literal["oecd"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'oecd' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Real GDP Data. @@ -269,10 +286,11 @@ def real( value : Optional[float] Nominal GDP value on the date. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.economy.gdp.real(units="yoy") + >>> obb.economy.gdp.real(provider='oecd') + >>> obb.economy.gdp.real(units='yoy', provider='oecd') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/equity.py b/openbb_platform/openbb/package/equity.py index 18b065d1c694..f36be502f66c 100644 --- a/openbb_platform/openbb/package/equity.py +++ b/openbb_platform/openbb/package/equity.py @@ -75,7 +75,14 @@ def fundamental(self): @exception_handler @validate def market_snapshots( - self, provider: Optional[Literal["fmp", "polygon"]] = None, **kwargs + self, + provider: Annotated[ + Optional[Literal["fmp", "polygon"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, + **kwargs ) -> OBBject: """Get an updated equity market snapshot. This includes price data for thousands of stocks. @@ -185,10 +192,10 @@ def market_snapshots( last_trade_timestamp : Optional[datetime] The last trade timestamp. (provider: polygon) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.market_snapshots() + >>> obb.equity.market_snapshots(provider='fmp') """ # noqa: E501 return self._run( @@ -232,7 +239,12 @@ def profile( description="Symbol to get data for. Multiple items allowed for provider(s): fmp, intrinio, yfinance." ), ], - provider: Optional[Literal["fmp", "intrinio", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get general information about a company. This includes company name, industry, sector and price data. @@ -384,10 +396,10 @@ def profile( dividend_yield : Optional[float] The dividend yield of the asset, as a normalized percent. (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.profile(symbol="AAPL") + >>> obb.equity.profile(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( @@ -414,7 +426,16 @@ def profile( @exception_handler @validate - def screener(self, provider: Optional[Literal["fmp"]] = None, **kwargs) -> OBBject: + def screener( + self, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, + **kwargs + ) -> OBBject: """Screen for companies meeting various criteria. These criteria include market cap, price, beta, volume, and dividend yield. @@ -504,10 +525,10 @@ def screener(self, provider: Optional[Literal["fmp"]] = None, **kwargs) -> OBBje actively_trading : Optional[Literal[True, False]] Whether the ETF is actively trading. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.screener() + >>> obb.equity.screener(provider='fmp') """ # noqa: E501 return self._run( @@ -538,7 +559,12 @@ def search( Optional[bool], OpenBBCustomParameter(description="Whether to use the cache or not."), ] = True, - provider: Optional[Literal["intrinio", "sec"]] = None, + provider: Annotated[ + Optional[Literal["intrinio", "sec"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'intrinio' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Search for stock symbol, CIK, LEI, or company name. @@ -590,10 +616,10 @@ def search( intrinio_id : Optional[str] The Intrinio ID of the company. (provider: intrinio) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.search(query="AAPL", is_symbol=False, use_cache=True) + >>> obb.equity.search(provider='intrinio') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/equity_calendar.py b/openbb_platform/openbb/package/equity_calendar.py index e15af99bdbf9..ccd675cb892a 100644 --- a/openbb_platform/openbb/package/equity_calendar.py +++ b/openbb_platform/openbb/package/equity_calendar.py @@ -38,7 +38,12 @@ def dividend( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get historical and upcoming dividend payments. Includes dividend amount, ex-dividend and payment dates. @@ -89,12 +94,10 @@ def dividend( label : Optional[str] Ex-dividend date formatted for display. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.calendar.dividend() - >>> # Get dividend calendar for specific dates. - >>> obb.equity.calendar.dividend(start_date='2024-02-01', end_date='2024-02-07') + >>> obb.equity.calendar.dividend(provider='fmp') """ # noqa: E501 return self._run( @@ -131,7 +134,12 @@ def earnings( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get historical and upcoming company earnings releases. Includes earnings per share (EPS) and revenue data. @@ -186,12 +194,12 @@ def earnings( updated_date : Optional[date] The date the data was updated last. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.calendar.earnings() + >>> obb.equity.calendar.earnings(provider='fmp') >>> # Get earnings calendar for specific dates. - >>> obb.equity.calendar.earnings(start_date='2024-02-01', end_date='2024-02-07') + >>> obb.equity.calendar.earnings(start_date='2024-02-01', end_date='2024-02-07', provider='fmp') """ # noqa: E501 return self._run( @@ -235,7 +243,12 @@ def ipo( Optional[int], OpenBBCustomParameter(description="The number of data entries to return."), ] = 100, - provider: Optional[Literal["intrinio"]] = None, + provider: Annotated[ + Optional[Literal["intrinio"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'intrinio' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get historical and upcoming initial public offerings (IPOs). @@ -357,14 +370,12 @@ def ipo( security : Optional[openbb_intrinio.utils.references.IntrinioSecurity] The primary Security for the Company that is going public via the IPO (provider: intrinio) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.calendar.ipo(limit=100) + >>> obb.equity.calendar.ipo(provider='intrinio') >>> # Get all IPOs available. - >>> obb.equity.calendar.ipo() - >>> # Get IPOs for specific dates. - >>> obb.equity.calendar.ipo(start_date='2024-02-01', end_date='2024-02-07') + >>> obb.equity.calendar.ipo(provider='intrinio') """ # noqa: E501 return self._run( @@ -403,7 +414,12 @@ def splits( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get historical and upcoming stock split operations. @@ -446,12 +462,12 @@ def splits( denominator : float Denominator of the stock splits. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.calendar.splits() + >>> obb.equity.calendar.splits(provider='fmp') >>> # Get stock splits calendar for specific dates. - >>> obb.equity.calendar.splits(start_date='2024-02-01', end_date='2024-02-07') + >>> obb.equity.calendar.splits(start_date='2024-02-01', end_date='2024-02-07', provider='fmp') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/equity_compare.py b/openbb_platform/openbb/package/equity_compare.py index f08472add9b4..704c2328a1e8 100644 --- a/openbb_platform/openbb/package/equity_compare.py +++ b/openbb_platform/openbb/package/equity_compare.py @@ -25,7 +25,12 @@ def peers( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the closest peers for a given company. @@ -61,10 +66,10 @@ def peers( peers_list : List[str] A list of equity peers based on sector, exchange and market cap. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.compare.peers(symbol="AAPL") + >>> obb.equity.compare.peers(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/equity_discovery.py b/openbb_platform/openbb/package/equity_discovery.py index c84cae036229..12df47ef9034 100644 --- a/openbb_platform/openbb/package/equity_discovery.py +++ b/openbb_platform/openbb/package/equity_discovery.py @@ -31,19 +31,24 @@ def __repr__(self) -> str: def active( self, sort: Annotated[ - str, + Literal["asc", "desc"], OpenBBCustomParameter( description="Sort order. Possible values: 'asc', 'desc'. Default: 'desc'." ), ] = "desc", - provider: Optional[Literal["yfinance"]] = None, + provider: Annotated[ + Optional[Literal["yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'yfinance' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the most actively traded stocks based on volume. Parameters ---------- - sort : str + sort : Literal['asc', 'desc'] Sort order. Possible values: 'asc', 'desc'. Default: 'desc'. provider : Optional[Literal['yfinance']] The provider to use for the query, by default None. @@ -85,10 +90,11 @@ def active( pe_ratio_ttm : Optional[float] PE Ratio (TTM). (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.discovery.active(sort="desc") + >>> obb.equity.discovery.active(provider='yfinance') + >>> obb.equity.discovery.active(sort='desc', provider='yfinance') """ # noqa: E501 return self._run( @@ -113,19 +119,24 @@ def active( def aggressive_small_caps( self, sort: Annotated[ - str, + Literal["asc", "desc"], OpenBBCustomParameter( description="Sort order. Possible values: 'asc', 'desc'. Default: 'desc'." ), ] = "desc", - provider: Optional[Literal["yfinance"]] = None, + provider: Annotated[ + Optional[Literal["yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'yfinance' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get top small cap stocks based on earnings growth. Parameters ---------- - sort : str + sort : Literal['asc', 'desc'] Sort order. Possible values: 'asc', 'desc'. Default: 'desc'. provider : Optional[Literal['yfinance']] The provider to use for the query, by default None. @@ -167,10 +178,11 @@ def aggressive_small_caps( pe_ratio_ttm : Optional[float] PE Ratio (TTM). (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.discovery.aggressive_small_caps(sort="desc") + >>> obb.equity.discovery.aggressive_small_caps(provider='yfinance') + >>> obb.equity.discovery.aggressive_small_caps(sort='desc', provider='yfinance') """ # noqa: E501 return self._run( @@ -216,7 +228,12 @@ def filings( int, OpenBBCustomParameter(description="The number of data entries to return."), ] = 100, - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the URLs to SEC filings reported to EDGAR database, such as 10-K, 10-Q, 8-K, and more. SEC @@ -272,12 +289,12 @@ def filings( link : str URL to the filing page on the SEC site. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.discovery.filings(limit=100) + >>> obb.equity.discovery.filings(provider='fmp') >>> # Get filings for the year 2023, limited to 100 results - >>> obb.equity.discovery.filings(start_date='2023-01-01', end_date='2023-12-31') + >>> obb.equity.discovery.filings(start_date='2023-01-01', end_date='2023-12-31', limit=100, provider='fmp') """ # noqa: E501 return self._run( @@ -305,19 +322,24 @@ def filings( def gainers( self, sort: Annotated[ - str, + Literal["asc", "desc"], OpenBBCustomParameter( description="Sort order. Possible values: 'asc', 'desc'. Default: 'desc'." ), ] = "desc", - provider: Optional[Literal["yfinance"]] = None, + provider: Annotated[ + Optional[Literal["yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'yfinance' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the top price gainers in the stock market. Parameters ---------- - sort : str + sort : Literal['asc', 'desc'] Sort order. Possible values: 'asc', 'desc'. Default: 'desc'. provider : Optional[Literal['yfinance']] The provider to use for the query, by default None. @@ -359,10 +381,11 @@ def gainers( pe_ratio_ttm : Optional[float] PE Ratio (TTM). (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.discovery.gainers(sort="desc") + >>> obb.equity.discovery.gainers(provider='yfinance') + >>> obb.equity.discovery.gainers(sort='desc', provider='yfinance') """ # noqa: E501 return self._run( @@ -387,19 +410,24 @@ def gainers( def growth_tech( self, sort: Annotated[ - str, + Literal["asc", "desc"], OpenBBCustomParameter( description="Sort order. Possible values: 'asc', 'desc'. Default: 'desc'." ), ] = "desc", - provider: Optional[Literal["yfinance"]] = None, + provider: Annotated[ + Optional[Literal["yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'yfinance' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get top tech stocks based on revenue and earnings growth. Parameters ---------- - sort : str + sort : Literal['asc', 'desc'] Sort order. Possible values: 'asc', 'desc'. Default: 'desc'. provider : Optional[Literal['yfinance']] The provider to use for the query, by default None. @@ -441,10 +469,11 @@ def growth_tech( pe_ratio_ttm : Optional[float] PE Ratio (TTM). (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.discovery.growth_tech(sort="desc") + >>> obb.equity.discovery.growth_tech(provider='yfinance') + >>> obb.equity.discovery.growth_tech(sort='desc', provider='yfinance') """ # noqa: E501 return self._run( @@ -469,19 +498,24 @@ def growth_tech( def losers( self, sort: Annotated[ - str, + Literal["asc", "desc"], OpenBBCustomParameter( description="Sort order. Possible values: 'asc', 'desc'. Default: 'desc'." ), ] = "desc", - provider: Optional[Literal["yfinance"]] = None, + provider: Annotated[ + Optional[Literal["yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'yfinance' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the top price losers in the stock market. Parameters ---------- - sort : str + sort : Literal['asc', 'desc'] Sort order. Possible values: 'asc', 'desc'. Default: 'desc'. provider : Optional[Literal['yfinance']] The provider to use for the query, by default None. @@ -523,10 +557,11 @@ def losers( pe_ratio_ttm : Optional[float] PE Ratio (TTM). (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.discovery.losers(sort="desc") + >>> obb.equity.discovery.losers(provider='yfinance') + >>> obb.equity.discovery.losers(sort='desc', provider='yfinance') """ # noqa: E501 return self._run( @@ -551,19 +586,24 @@ def losers( def undervalued_growth( self, sort: Annotated[ - str, + Literal["asc", "desc"], OpenBBCustomParameter( description="Sort order. Possible values: 'asc', 'desc'. Default: 'desc'." ), ] = "desc", - provider: Optional[Literal["yfinance"]] = None, + provider: Annotated[ + Optional[Literal["yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'yfinance' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get potentially undervalued growth stocks. Parameters ---------- - sort : str + sort : Literal['asc', 'desc'] Sort order. Possible values: 'asc', 'desc'. Default: 'desc'. provider : Optional[Literal['yfinance']] The provider to use for the query, by default None. @@ -605,10 +645,11 @@ def undervalued_growth( pe_ratio_ttm : Optional[float] PE Ratio (TTM). (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.discovery.undervalued_growth(sort="desc") + >>> obb.equity.discovery.undervalued_growth(provider='yfinance') + >>> obb.equity.discovery.undervalued_growth(sort='desc', provider='yfinance') """ # noqa: E501 return self._run( @@ -633,19 +674,24 @@ def undervalued_growth( def undervalued_large_caps( self, sort: Annotated[ - str, + Literal["asc", "desc"], OpenBBCustomParameter( description="Sort order. Possible values: 'asc', 'desc'. Default: 'desc'." ), ] = "desc", - provider: Optional[Literal["yfinance"]] = None, + provider: Annotated[ + Optional[Literal["yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'yfinance' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get potentially undervalued large cap stocks. Parameters ---------- - sort : str + sort : Literal['asc', 'desc'] Sort order. Possible values: 'asc', 'desc'. Default: 'desc'. provider : Optional[Literal['yfinance']] The provider to use for the query, by default None. @@ -687,10 +733,11 @@ def undervalued_large_caps( pe_ratio_ttm : Optional[float] PE Ratio (TTM). (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.discovery.undervalued_large_caps(sort="desc") + >>> obb.equity.discovery.undervalued_large_caps(provider='yfinance') + >>> obb.equity.discovery.undervalued_large_caps(sort='desc', provider='yfinance') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/equity_estimates.py b/openbb_platform/openbb/package/equity_estimates.py index a1d21d83b4da..4016105cc9d6 100644 --- a/openbb_platform/openbb/package/equity_estimates.py +++ b/openbb_platform/openbb/package/equity_estimates.py @@ -37,7 +37,12 @@ def analyst_search( description="A comma separated list of firm names to bring back. Omitting will bring back all available firms." ), ] = None, - provider: Optional[Literal["benzinga"]] = None, + provider: Annotated[ + Optional[Literal["benzinga"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'benzinga' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Search for specific analysts and get their forecast track record. @@ -168,10 +173,11 @@ def analyst_search( std_dev_3y : Optional[float] The standard deviation in percent (normalized) price difference in the analyst's ratings over the last 3 years (provider: benzinga) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.estimates.analyst_search(firm_name="Wedbush", provider="benzinga").to_df() + >>> obb.equity.estimates.analyst_search(provider='benzinga') + >>> obb.equity.estimates.analyst_search(firm_name='Wedbush', provider='benzinga') """ # noqa: E501 return self._run( @@ -202,7 +208,12 @@ def consensus( description="Symbol to get data for. Multiple items allowed for provider(s): yfinance." ), ], - provider: Optional[Literal["fmp", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get consensus price target and recommendation. @@ -253,10 +264,11 @@ def consensus( currency : Optional[str] Currency the stock is priced in. (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.estimates.consensus("AAPL,MSFT", provider="yfinance").to_df() + >>> obb.equity.estimates.consensus(symbol='AAPL', provider='fmp') + >>> obb.equity.estimates.consensus(symbol='AAPL,MSFT', provider='yfinance') """ # noqa: E501 return self._run( @@ -292,7 +304,12 @@ def historical( int, OpenBBCustomParameter(description="The number of data entries to return."), ] = 30, - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get historical analyst estimates for earnings and revenue. @@ -371,10 +388,10 @@ def historical( number_analysts_estimated_eps : int Number of analysts who estimated EPS. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.estimates.historical("AAPL", period="quarter", provider="fmp").to_df() + >>> obb.equity.estimates.historical(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( @@ -410,7 +427,12 @@ def price_target( int, OpenBBCustomParameter(description="The number of data entries to return."), ] = 200, - provider: Optional[Literal["benzinga", "fmp"]] = None, + provider: Annotated[ + Optional[Literal["benzinga", "fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'benzinga' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get analyst price targets by company. @@ -521,10 +543,12 @@ def price_target( news_base_url : Optional[str] News base URL of the price target. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.estimates.price_target(start_date="2020-01-01", end_date="2024-02-16",limit=10, symbol="msft", provider="benzinga",action="downgrades").to_df() + >>> obb.equity.estimates.price_target(provider='benzinga') + >>> # Get price targets for Microsoft using 'benzinga' as provider. + >>> obb.equity.estimates.price_target(start_date='2020-01-01', end_date='2024-02-16', limit=10, symbol='msft', provider='benzinga', action='downgrades') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/equity_fundamental.py b/openbb_platform/openbb/package/equity_fundamental.py index 9ad938292d93..c0c6f810ecb5 100644 --- a/openbb_platform/openbb/package/equity_fundamental.py +++ b/openbb_platform/openbb/package/equity_fundamental.py @@ -60,7 +60,12 @@ def balance( Optional[Annotated[int, Ge(ge=0)]], OpenBBCustomParameter(description="The number of data entries to return."), ] = 5, - provider: Optional[Literal["fmp", "intrinio", "polygon", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "polygon", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the balance sheet for a given company. @@ -377,10 +382,11 @@ def balance( total_equity : Optional[int] Total equity (provider: polygon) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.balance(symbol="AAPL", period="annual", limit=5) + >>> obb.equity.fundamental.balance(symbol='AAPL', provider='fmp') + >>> obb.equity.fundamental.balance(symbol='AAPL', period='annual', limit=5, provider='intrinio') """ # noqa: E501 return self._run( @@ -413,7 +419,12 @@ def balance_growth( int, OpenBBCustomParameter(description="The number of data entries to return."), ] = 10, - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the growth of a company's balance sheet items over time. @@ -530,10 +541,11 @@ def balance_growth( growth_net_debt : float Growth rate of net debt. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.balance_growth(symbol="AAPL", limit=10) + >>> obb.equity.fundamental.balance_growth(symbol='AAPL', provider='fmp') + >>> obb.equity.fundamental.balance_growth(symbol='AAPL', limit=10, provider='fmp') """ # noqa: E501 return self._run( @@ -568,7 +580,12 @@ def cash( Optional[Annotated[int, Ge(ge=0)]], OpenBBCustomParameter(description="The number of data entries to return."), ] = 5, - provider: Optional[Literal["fmp", "intrinio", "polygon", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "polygon", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the cash flow statement for a given company. @@ -793,10 +810,11 @@ def cash( net_cash_flow : Optional[int] Net cash flow. (provider: polygon) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.cash(symbol="AAPL", period="annual", limit=5) + >>> obb.equity.fundamental.cash(symbol='AAPL', provider='fmp') + >>> obb.equity.fundamental.cash(symbol='AAPL', period='annual', limit=5, provider='intrinio') """ # noqa: E501 return self._run( @@ -829,7 +847,12 @@ def cash_growth( int, OpenBBCustomParameter(description="The number of data entries to return."), ] = 10, - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the growth of a company's cash flow statement items over time. @@ -928,10 +951,11 @@ def cash_growth( growth_free_cash_flow : float Growth rate of free cash flow. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.cash_growth(symbol="AAPL", limit=10) + >>> obb.equity.fundamental.cash_growth(symbol='AAPL', provider='fmp') + >>> obb.equity.fundamental.cash_growth(symbol='AAPL', limit=10, provider='fmp') """ # noqa: E501 return self._run( @@ -971,7 +995,12 @@ def dividends( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fmp", "intrinio", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get historical dividend data for a given company. @@ -1028,10 +1057,10 @@ def dividends( split_ratio : Optional[float] The ratio of the stock split, if a stock split occurred. (provider: intrinio) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.dividends(symbol="AAPL") + >>> obb.equity.fundamental.dividends(symbol='AAPL', provider='intrinio') """ # noqa: E501 return self._run( @@ -1060,7 +1089,12 @@ def employee_count( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get historical employee count data for a given company. @@ -1109,10 +1143,10 @@ def employee_count( source : str Source URL which retrieves this data for the company. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.employee_count(symbol="AAPL") + >>> obb.equity.fundamental.employee_count(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( @@ -1149,7 +1183,12 @@ def filings( int, OpenBBCustomParameter(description="The number of data entries to return."), ] = 100, - provider: Optional[Literal["fmp", "intrinio", "sec"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "sec"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the URLs to SEC filings reported to EDGAR database, such as 10-K, 10-Q, 8-K, and more. SEC @@ -1253,10 +1292,11 @@ def filings( filing_detail_url : Optional[str] The URL to the filing details. (provider: sec) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.filings(limit=100) + >>> obb.equity.fundamental.filings(provider='fmp') + >>> obb.equity.fundamental.filings(limit=100, provider='fmp') """ # noqa: E501 return self._run( @@ -1322,7 +1362,12 @@ def historical_attributes( Optional[Literal["asc", "desc"]], OpenBBCustomParameter(description="Sort order."), ] = "desc", - provider: Optional[Literal["intrinio"]] = None, + provider: Annotated[ + Optional[Literal["intrinio"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'intrinio' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the historical values of a data tag from Intrinio. @@ -1375,10 +1420,10 @@ def historical_attributes( value : Optional[float] The value of the data. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.historical_attributes(tag='ebitda') + >>> obb.equity.fundamental.historical_attributes(symbol='AAPL', tag='ebitda', provider='intrinio') """ # noqa: E501 return self._run( @@ -1416,7 +1461,12 @@ def historical_eps( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get historical earnings per share data for a given company. @@ -1469,10 +1519,10 @@ def historical_eps( period_ending : Optional[date] The fiscal period end date. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.historical_eps(symbol="AAPL") + >>> obb.equity.fundamental.historical_eps(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( @@ -1499,7 +1549,12 @@ def historical_splits( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get historical stock splits for a given company. @@ -1538,10 +1593,10 @@ def historical_splits( denominator : float Denominator of the historical stock splits. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.historical_splits(symbol="AAPL") + >>> obb.equity.fundamental.historical_splits(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( @@ -1575,7 +1630,12 @@ def income( Optional[Annotated[int, Ge(ge=0)]], OpenBBCustomParameter(description="The number of data entries to return."), ] = 5, - provider: Optional[Literal["fmp", "intrinio", "polygon", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "polygon", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the income statement for a given company. @@ -1894,10 +1954,11 @@ def income( preferred_stock_dividends_and_other_adjustments : Optional[float] Preferred stock dividends and other adjustments (provider: polygon) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.income(symbol="AAPL", period="annual", limit=5) + >>> obb.equity.fundamental.income(symbol='AAPL', provider='fmp') + >>> obb.equity.fundamental.income(symbol='AAPL', period='annual', limit=5, provider='intrinio') """ # noqa: E501 return self._run( @@ -1934,7 +1995,12 @@ def income_growth( Literal["quarter", "annual"], OpenBBCustomParameter(description="Time period of the data to return."), ] = "annual", - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the growth of a company's income statement items over time. @@ -2027,10 +2093,11 @@ def income_growth( growth_weighted_average_shs_out_dil : float Growth rate of diluted weighted average shares outstanding. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.income_growth(symbol="AAPL", limit=10, period="annual") + >>> obb.equity.fundamental.income_growth(symbol='AAPL', provider='fmp') + >>> obb.equity.fundamental.income_growth(symbol='AAPL', limit=10, period='annual', provider='fmp') """ # noqa: E501 return self._run( @@ -2068,7 +2135,12 @@ def latest_attributes( description="Intrinio data tag ID or code. Multiple items allowed for provider(s): intrinio." ), ], - provider: Optional[Literal["intrinio"]] = None, + provider: Annotated[ + Optional[Literal["intrinio"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'intrinio' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the latest value of a data tag from Intrinio. @@ -2107,10 +2179,10 @@ def latest_attributes( value : Optional[Union[str, float]] The value of the data. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.latest_attributes(tag='ceo') + >>> obb.equity.fundamental.latest_attributes(symbol='AAPL', tag='ceo', provider='intrinio') """ # noqa: E501 return self._run( @@ -2142,7 +2214,12 @@ def management( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["fmp", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get executive management team data for a given company. @@ -2191,10 +2268,10 @@ def management( unexercised_value : Optional[int] Value of shares not exercised. (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.management(symbol="AAPL") + >>> obb.equity.fundamental.management(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( @@ -2236,7 +2313,12 @@ def management_compensation( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get executive management team compensation for a given company over time. @@ -2297,10 +2379,10 @@ def management_compensation( url : str URL of the filing data. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.management_compensation(symbol="AAPL") + >>> obb.equity.fundamental.management_compensation(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( @@ -2341,7 +2423,12 @@ def metrics( Optional[int], OpenBBCustomParameter(description="The number of data entries to return."), ] = 100, - provider: Optional[Literal["fmp", "intrinio", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get fundamental metrics for a given company. @@ -2563,10 +2650,11 @@ def metrics( currency : Optional[str] Currency in which the data is presented. (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.metrics(symbol="AAPL", period="annual", limit=100) + >>> obb.equity.fundamental.metrics(symbol='AAPL', provider='fmp') + >>> obb.equity.fundamental.metrics(symbol='AAPL', period='annual', limit=100, provider='intrinio') """ # noqa: E501 return self._run( @@ -2599,7 +2687,12 @@ def multiples( description="Symbol to get data for. Multiple items allowed for provider(s): fmp." ), ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get equity valuation multiples for a given company. @@ -2752,10 +2845,10 @@ def multiples( capex_per_share_ttm : Optional[float] Capital expenditures per share calculated as trailing twelve months. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.multiples(symbol="AAPL") + >>> obb.equity.fundamental.multiples(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( @@ -2787,7 +2880,12 @@ def overview( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get company general business and stock data for a given company. @@ -2890,10 +2988,10 @@ def overview( is_fund : bool If the company is a fund. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.overview(symbol="AAPL") + >>> obb.equity.fundamental.overview(symbol='AAPL', provider='fmp') """ # noqa: E501 simplefilter("always", DeprecationWarning) @@ -2934,7 +3032,12 @@ def ratios( int, OpenBBCustomParameter(description="The number of data entries to return."), ] = 12, - provider: Optional[Literal["fmp", "intrinio"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "intrinio"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get an extensive set of financial and accounting ratios for a given company over time. @@ -3089,10 +3192,11 @@ def ratios( price_fair_value : Optional[float] Price fair value. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.ratios(symbol="AAPL", period="annual", limit=12) + >>> obb.equity.fundamental.ratios(symbol='AAPL', provider='fmp') + >>> obb.equity.fundamental.ratios(symbol='AAPL', period='annual', limit=12, provider='intrinio') """ # noqa: E501 return self._run( @@ -3136,7 +3240,12 @@ def reported_financials( description="The number of data entries to return. Although the response object contains multiple results, because of the variance in the fields, year-to-year and quarter-to-quarter, it is recommended to view results in small chunks." ), ] = 100, - provider: Optional[Literal["intrinio"]] = None, + provider: Annotated[ + Optional[Literal["intrinio"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'intrinio' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get financial statements as reported by the company. @@ -3181,14 +3290,16 @@ def reported_financials( fiscal_year : Optional[int] The fiscal year of the fiscal period. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.reported_financials(symbol="AAPL", period="annual", statement_type="balance", limit=100) + >>> obb.equity.fundamental.reported_financials(symbol='AAPL', provider='intrinio') + >>> # Get AAPL balance sheet with a limit of 10 items. + >>> obb.equity.fundamental.reported_financials(symbol='AAPL', period='annual', statement_type='balance', limit=10, provider='intrinio') >>> # Get reported income statement - >>> obb.equity.fundamental.reported_financials(symbol='AAPL', statement_type='income) + >>> obb.equity.fundamental.reported_financials(symbol='AAPL', statement_type='income', provider='intrinio') >>> # Get reported cash flow statement - >>> obb.equity.fundamental.reported_financials(symbol='AAPL', statement_type='cash') + >>> obb.equity.fundamental.reported_financials(symbol='AAPL', statement_type='cash', provider='intrinio') """ # noqa: E501 return self._run( @@ -3226,7 +3337,12 @@ def revenue_per_geography( Literal["hierarchical", "flat"], OpenBBCustomParameter(description="Structure of the returned data."), ] = "flat", - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the revenue geographic breakdown for a given company over time. @@ -3271,10 +3387,11 @@ def revenue_per_geography( geographic_segment : int Dictionary of the revenue by geographic segment. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.revenue_per_geography(symbol="AAPL", period="annual", structure="flat") + >>> obb.equity.fundamental.revenue_per_geography(symbol='AAPL', provider='fmp') + >>> obb.equity.fundamental.revenue_per_geography(symbol='AAPL', period='annual', structure='flat', provider='fmp') """ # noqa: E501 return self._run( @@ -3311,7 +3428,12 @@ def revenue_per_segment( Literal["hierarchical", "flat"], OpenBBCustomParameter(description="Structure of the returned data."), ] = "flat", - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the revenue breakdown by business segment for a given company over time. @@ -3356,10 +3478,11 @@ def revenue_per_segment( business_line : int Dictionary containing the revenue of the business line. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.revenue_per_segment(symbol="AAPL", period="annual", structure="flat") + >>> obb.equity.fundamental.revenue_per_segment(symbol='AAPL', provider='fmp') + >>> obb.equity.fundamental.revenue_per_segment(symbol='AAPL', period='annual', structure='flat', provider='fmp') """ # noqa: E501 return self._run( @@ -3392,7 +3515,12 @@ def search_attributes( Optional[int], OpenBBCustomParameter(description="The number of data entries to return."), ] = 1000, - provider: Optional[Literal["intrinio"]] = None, + provider: Annotated[ + Optional[Literal["intrinio"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'intrinio' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Search Intrinio data tags to search in latest or historical attributes. @@ -3447,10 +3575,10 @@ def search_attributes( unit : Optional[str] Unit of the financial attribute. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.search_attributes(query='ebitda') + >>> obb.equity.fundamental.search_attributes(query='ebitda', provider='intrinio') """ # noqa: E501 return self._run( @@ -3476,22 +3604,27 @@ def search_attributes( def trailing_dividend_yield( self, symbol: Annotated[ - Optional[str], OpenBBCustomParameter(description="Symbol to get data for.") - ] = None, + str, OpenBBCustomParameter(description="Symbol to get data for.") + ], limit: Annotated[ Optional[int], OpenBBCustomParameter( description="The number of data entries to return. Default is 252, the number of trading days in a year." ), ] = 252, - provider: Optional[Literal["tiingo"]] = None, + provider: Annotated[ + Optional[Literal["tiingo"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'tiingo' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the 1 year trailing dividend yield for a given company over time. Parameters ---------- - symbol : Optional[str] + symbol : str Symbol to get data for. limit : Optional[int] The number of data entries to return. Default is 252, the number of trading days in a year. @@ -3521,10 +3654,11 @@ def trailing_dividend_yield( trailing_dividend_yield : float Trailing dividend yield. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.trailing_dividend_yield(limit=252) + >>> obb.equity.fundamental.trailing_dividend_yield(symbol='AAPL', provider='tiingo') + >>> obb.equity.fundamental.trailing_dividend_yield(symbol='AAPL', limit=252, provider='tiingo') """ # noqa: E501 return self._run( @@ -3556,7 +3690,12 @@ def transcript( int, OpenBBCustomParameter(description="Year of the earnings call transcript."), ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get earnings call transcripts for a given company. @@ -3599,10 +3738,10 @@ def transcript( content : str Content of the earnings call transcript. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.fundamental.transcript(symbol='AAPL', year=2020) + >>> obb.equity.fundamental.transcript(symbol='AAPL', year=2020, provider='fmp') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/equity_ownership.py b/openbb_platform/openbb/package/equity_ownership.py index 6597acbb9fd8..7942b4a1db99 100644 --- a/openbb_platform/openbb/package/equity_ownership.py +++ b/openbb_platform/openbb/package/equity_ownership.py @@ -45,7 +45,12 @@ def form_13f( description="The number of data entries to return. The number of previous filings to return. The date parameter takes priority over this parameter." ), ] = 1, - provider: Optional[Literal["sec"]] = None, + provider: Annotated[ + Optional[Literal["sec"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'sec' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """The Securities and Exchange Commission's (SEC) Form 13F is a quarterly report @@ -110,16 +115,15 @@ def form_13f( weight : Optional[float] The weight of the security relative to the market value of all securities in the filing , as a normalized percent. (provider: sec) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> ### Enter the symbol as either the stock ticker or the CIK number as a string. ### - >>> obb.equity.ownership.form_13f(symbol="NVDA").to_df() - >>> ### Enter a date (calendar quarter ending) for a specific report. ### - >>> obb.equity.ownership.form_13f(symbol="BRK-A", date="2016-09-30") - >>> ### Use the `limit` parameter to return N number of reports from the most recent. ### - >>> ### Example finding Michael Burry's filings. ### + >>> obb.equity.ownership.form_13f(symbol='NVDA', provider='sec') + >>> # Enter a date (calendar quarter ending) for a specific report. + >>> obb.equity.ownership.form_13f(symbol='BRK-A', date='2016-09-30', provider='sec') + >>> # Example finding Michael Burry's filings. >>> cik = obb.regulators.sec.institutions_search("Scion Asset Management").results[0].cik + >>> # Use the `limit` parameter to return N number of reports from the most recent. >>> obb.equity.ownership.form_13f(cik, limit=2).to_df() """ # noqa: E501 @@ -153,7 +157,12 @@ def insider_trading( int, OpenBBCustomParameter(description="The number of data entries to return."), ] = 500, - provider: Optional[Literal["fmp", "intrinio"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "intrinio"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get data about trading by a company's management team and board of directors. @@ -254,10 +263,11 @@ def insider_trading( report_line_number : Optional[int] Report line number of the insider trading. (provider: intrinio) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.ownership.insider_trading(symbol="AAPL", limit=500) + >>> obb.equity.ownership.insider_trading(symbol='AAPL', provider='fmp') + >>> obb.equity.ownership.insider_trading(symbol='AAPL', limit=500, provider='intrinio') """ # noqa: E501 return self._run( @@ -285,7 +295,12 @@ def institutional( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get data about institutional ownership for a given company over time. @@ -392,10 +407,10 @@ def institutional( put_call_ratio_change : Optional[float] Change in the put-call ratio between the current and previous reporting dates. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.ownership.institutional(symbol="AAPL") + >>> obb.equity.ownership.institutional(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( @@ -430,7 +445,12 @@ def major_holders( Optional[int], OpenBBCustomParameter(description="Page number of the data to fetch."), ] = 0, - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get data about major holders for a given company over time. @@ -543,10 +563,11 @@ def major_holders( is_counted_for_performance : bool Is the stock ownership counted for performance. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.ownership.major_holders(symbol="AAPL", page=0) + >>> obb.equity.ownership.major_holders(symbol='AAPL', provider='fmp') + >>> obb.equity.ownership.major_holders(symbol='AAPL', page=0, provider='fmp') """ # noqa: E501 return self._run( @@ -578,7 +599,12 @@ def share_statistics( description="Symbol to get data for. Multiple items allowed for provider(s): yfinance." ), ], - provider: Optional[Literal["fmp", "intrinio", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get data about share float for a given company. @@ -645,10 +671,10 @@ def share_statistics( institutions_count : Optional[int] Number of institutions holding shares. (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.ownership.share_statistics(symbol="AAPL") + >>> obb.equity.ownership.share_statistics(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/equity_price.py b/openbb_platform/openbb/package/equity_price.py index 3a525a4dcff1..5e83ca0c9cdf 100644 --- a/openbb_platform/openbb/package/equity_price.py +++ b/openbb_platform/openbb/package/equity_price.py @@ -48,8 +48,11 @@ def historical( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[ - Literal["fmp", "intrinio", "polygon", "tiingo", "yfinance"] + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "polygon", "tiingo", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), ] = None, **kwargs ) -> OBBject: @@ -87,6 +90,10 @@ def historical( The number of data entries to return. (provider: polygon) include_actions : bool Include dividends and stock splits in results. (provider: yfinance) + adjusted : bool + This field is deprecated (4.1.5) and will be removed in a future version. Use 'adjustment' set as 'splits_and_dividends' instead. (provider: yfinance) + prepost : bool + This field is deprecated (4.1.5) and will be removed in a future version. Use 'extended_hours' as True instead. (provider: yfinance) Returns ------- @@ -157,10 +164,11 @@ def historical( transactions : Optional[Annotated[int, Gt(gt=0)]] Number of transactions for the symbol in the time period. (provider: polygon) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.price.historical(symbol="AAPL", interval="1d") + >>> obb.equity.price.historical(symbol='AAPL', provider='fmp') + >>> obb.equity.price.historical(symbol='AAPL', interval='1d', provider='intrinio') """ # noqa: E501 return self._run( @@ -200,7 +208,12 @@ def nbbo( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["polygon"]] = None, + provider: Annotated[ + Optional[Literal["polygon"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'polygon' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the National Best Bid and Offer for a given stock. @@ -300,10 +313,10 @@ def nbbo( This is the timestamp of when the trade reporting facility received this quote. (provider: polygon) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.price.nbbo(symbol="AAPL") + >>> obb.equity.price.nbbo(symbol='AAPL', provider='polygon') """ # noqa: E501 return self._run( @@ -333,7 +346,12 @@ def performance( description="Symbol to get data for. Multiple items allowed for provider(s): fmp." ), ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get price performance data for a given stock. This includes price changes for different time periods. @@ -394,10 +412,10 @@ def performance( symbol : Optional[str] The ticker symbol. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.price.performance(symbol="AAPL") + >>> obb.equity.price.performance(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( @@ -428,7 +446,12 @@ def quote( description="Symbol to get data for. This endpoint will accept multiple symbols separated by commas. Multiple items allowed for provider(s): fmp, intrinio, yfinance." ), ], - provider: Optional[Literal["fmp", "intrinio", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the latest quote for a given stock. Quote includes price, volume, and other data. @@ -561,10 +584,10 @@ def quote( currency : Optional[str] Currency of the price. (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.price.quote(symbol="AAPL") + >>> obb.equity.price.quote(symbol='AAPL', provider='fmp') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/equity_shorts.py b/openbb_platform/openbb/package/equity_shorts.py index 3bf1f10b5d1d..115690a4fab0 100644 --- a/openbb_platform/openbb/package/equity_shorts.py +++ b/openbb_platform/openbb/package/equity_shorts.py @@ -25,7 +25,12 @@ def fails_to_deliver( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["sec"]] = None, + provider: Annotated[ + Optional[Literal["sec"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'sec' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get reported Fail-to-deliver (FTD) data. @@ -77,10 +82,10 @@ def fails_to_deliver( description : Optional[str] The description of the Security. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.equity.shorts.fails_to_deliver(symbol='AAPL') + >>> obb.equity.shorts.fails_to_deliver(symbol='AAPL', provider='sec') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/etf.py b/openbb_platform/openbb/package/etf.py index 62945ff43551..b34a947e0922 100644 --- a/openbb_platform/openbb/package/etf.py +++ b/openbb_platform/openbb/package/etf.py @@ -38,7 +38,12 @@ def countries( description="Symbol to get data for. (ETF) Multiple items allowed for provider(s): fmp." ), ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """ETF Country weighting. @@ -71,10 +76,10 @@ def countries( country : str The country of the exposure. Corresponding values are normalized percentage points. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.etf.countries("VT", provider="fmp") + >>> obb.etf.countries(symbol='VT', provider='fmp') """ # noqa: E501 return self._run( @@ -105,7 +110,12 @@ def equity_exposure( description="Symbol to get data for. (Stock) Multiple items allowed for provider(s): fmp." ), ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the exposure to ETFs for a specific stock. @@ -146,12 +156,12 @@ def equity_exposure( market_value : Optional[Union[float, int]] The market value of the equity position in the ETF. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.etf.equity_exposure("MSFT", provider="fmp") - >>> #### This function accepts multiple tickers. #### - >>> obb.etf.equity_exposure("MSFT,AAPL", provider="fmp") + >>> obb.etf.equity_exposure(symbol='MSFT', provider='fmp') + >>> # This function accepts multiple tickers. + >>> obb.etf.equity_exposure(symbol='MSFT,AAPL', provider='fmp') """ # noqa: E501 return self._run( @@ -198,8 +208,11 @@ def historical( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[ - Literal["fmp", "intrinio", "polygon", "tiingo", "yfinance"] + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "polygon", "tiingo", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), ] = None, **kwargs ) -> OBBject: @@ -237,6 +250,10 @@ def historical( The number of data entries to return. (provider: polygon) include_actions : bool Include dividends and stock splits in results. (provider: yfinance) + adjusted : bool + This field is deprecated (4.1.5) and will be removed in a future version. Use 'adjustment' set as 'splits_and_dividends' instead. (provider: yfinance) + prepost : bool + This field is deprecated (4.1.5) and will be removed in a future version. Use 'extended_hours' as True instead. (provider: yfinance) Returns ------- @@ -307,13 +324,13 @@ def historical( transactions : Optional[Annotated[int, Gt(gt=0)]] Number of transactions for the symbol in the time period. (provider: polygon) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.etf.historical(symbol="SPY", interval="1d") - >>> obb.etf.historical("SPY", provider="yfinance") - >>> #### This function accepts multiple tickers. #### - >>> obb.etf.historical("SPY,IWM,QQQ,DJIA", provider="yfinance") + >>> obb.etf.historical(symbol='SPY', provider='fmp') + >>> obb.etf.historical(symbol='SPY', provider='yfinance') + >>> # This function accepts multiple tickers. + >>> obb.etf.historical(symbol='SPY,IWM,QQQ,DJIA', provider='yfinance') """ # noqa: E501 return self._run( @@ -353,7 +370,12 @@ def holdings( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for. (ETF)") ], - provider: Optional[Literal["fmp", "sec"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "sec"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the holdings for an individual ETF. @@ -552,14 +574,14 @@ def holdings( unrealized_gain : Optional[float] The unrealized gain or loss on the derivative. (provider: sec) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.etf.holdings("XLK", provider="fmp").to_df() - >>> #### Including a date (FMP, SEC) will return the holdings as per NPORT-P filings. #### - >>> obb.etf.holdings("XLK", date="2022-03-31",provider="fmp").to_df() - >>> #### The same data can be returned from the SEC directly. #### - >>> obb.etf.holdings("XLK", date="2022-03-31",provider="sec").to_df() + >>> obb.etf.holdings(symbol='XLK', provider='fmp') + >>> # Including a date (FMP, SEC) will return the holdings as per NPORT-P filings. + >>> obb.etf.holdings(symbol='XLK', date='2022-03-31', provider='fmp') + >>> # The same data can be returned from the SEC directly. + >>> obb.etf.holdings(symbol='XLK', date='2022-03-31', provider='sec') """ # noqa: E501 return self._run( @@ -586,7 +608,12 @@ def holdings_date( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for. (ETF)") ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Use this function to get the holdings dates, if available. @@ -621,10 +648,10 @@ def holdings_date( date : date The date of the data. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.etf.holdings_date("XLK", provider="fmp").results + >>> obb.etf.holdings_date(symbol='XLK', provider='fmp') """ # noqa: E501 return self._run( @@ -654,7 +681,12 @@ def holdings_performance( description="Symbol to get data for. Multiple items allowed for provider(s): fmp." ), ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Get the recent price performance of each ticker held in the ETF. @@ -715,10 +747,10 @@ def holdings_performance( symbol : Optional[str] The ticker symbol. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.etf.holdings_performance("XLK", provider="fmp") + >>> obb.etf.holdings_performance(symbol='XLK', provider='fmp') """ # noqa: E501 return self._run( @@ -749,7 +781,12 @@ def info( description="Symbol to get data for. (ETF) Multiple items allowed for provider(s): fmp, yfinance." ), ], - provider: Optional[Literal["fmp", "yfinance"]] = None, + provider: Annotated[ + Optional[Literal["fmp", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """ETF Information Overview. @@ -874,12 +911,12 @@ def info( prev_close : Optional[float] The previous closing price. (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.etf.info("SPY", provider="fmp") - >>> #### This function accepts multiple tickers. #### - >>> obb.etf.info("SPY,IWM,QQQ,DJIA", provider="fmp") + >>> obb.etf.info(symbol='SPY', provider='fmp') + >>> # This function accepts multiple tickers. + >>> obb.etf.info(symbol='SPY,IWM,QQQ,DJIA', provider='fmp') """ # noqa: E501 return self._run( @@ -910,7 +947,12 @@ def price_performance( description="Symbol to get data for. Multiple items allowed for provider(s): fmp." ), ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Price performance as a return, over different periods. This is a proxy for `equity.price.performance`. @@ -971,10 +1013,11 @@ def price_performance( symbol : Optional[str] The ticker symbol. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.etf.price_performance("SPY,QQQ,IWM,DJIA", provider="fmp") + >>> obb.etf.price_performance(symbol='QQQ', provider='fmp') + >>> obb.etf.price_performance(symbol='SPY,QQQ,IWM,DJIA', provider='fmp') """ # noqa: E501 return self._run( @@ -1002,7 +1045,12 @@ def search( query: Annotated[ Optional[str], OpenBBCustomParameter(description="Search query.") ] = "", - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Search for ETFs. @@ -1066,12 +1114,13 @@ def search( actively_trading : Optional[Literal[True, False]] Whether the ETF is actively trading. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> ### An empty query returns the full list of ETFs from the provider. ### - >>> obb.etf.search("", provider="fmp") - >>> #### The query will return results from text-based fields containing the term. ####obb.etf.search("commercial real estate", provider="fmp") + >>> # An empty query returns the full list of ETFs from the provider. + >>> obb.etf.search(provider='fmp') + >>> # The query will return results from text-based fields containing the term. + >>> obb.etf.search(query='commercial real estate', provider='fmp') """ # noqa: E501 return self._run( @@ -1098,7 +1147,12 @@ def sectors( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for. (ETF)") ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """ETF Sector weighting. @@ -1133,10 +1187,10 @@ def sectors( weight : Optional[float] Exposure of the ETF to the sector in normalized percentage points. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.etf.sectors("SPY", provider="fmp") + >>> obb.etf.sectors(symbol='SPY', provider='fmp') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/fixedincome.py b/openbb_platform/openbb/package/fixedincome.py index 65ec3f7ae62e..30bfb1f52c83 100644 --- a/openbb_platform/openbb/package/fixedincome.py +++ b/openbb_platform/openbb/package/fixedincome.py @@ -66,7 +66,12 @@ def sofr( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Secured Overnight Financing Rate. @@ -109,10 +114,11 @@ def sofr( rate : Optional[float] SOFR rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.fixedincome.sofr(period="overnight") + >>> obb.fixedincome.sofr(provider='fred') + >>> obb.fixedincome.sofr(period='overnight', provider='fred') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/fixedincome_corporate.py b/openbb_platform/openbb/package/fixedincome_corporate.py index b651e91c1633..bd6d09f57271 100644 --- a/openbb_platform/openbb/package/fixedincome_corporate.py +++ b/openbb_platform/openbb/package/fixedincome_corporate.py @@ -3,7 +3,10 @@ import datetime from typing import List, Literal, Optional, Union -from openbb_core.app.model.custom_parameter import OpenBBCustomParameter +from openbb_core.app.model.custom_parameter import ( + OpenBBCustomChoices, + OpenBBCustomParameter, +) from openbb_core.app.model.obbject import OBBject from openbb_core.app.static.container import Container from openbb_core.app.static.utils.decorators import exception_handler, validate @@ -50,7 +53,12 @@ def commercial_paper( grade: Annotated[ Literal["aa", "a2_p2"], OpenBBCustomParameter(description="The grade.") ] = "aa", - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Commercial Paper. @@ -99,10 +107,11 @@ def commercial_paper( rate : Optional[float] Commercial Paper Rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.corporate.commercial_paper(maturity="15d") + >>> obb.fixedincome.corporate.commercial_paper(provider='fred') + >>> obb.fixedincome.corporate.commercial_paper(maturity='15d', provider='fred') """ # noqa: E501 return self._run( @@ -138,7 +147,12 @@ def hqm( Literal["spot", "par"], OpenBBCustomParameter(description="The yield curve type."), ] = "spot", - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """High Quality Market Corporate Bond. @@ -187,10 +201,11 @@ def hqm( series_id : Optional[str] FRED series id. (provider: fred) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.corporate.hqm(yield_curve="par") + >>> obb.fixedincome.corporate.hqm(provider='fred') + >>> obb.fixedincome.corporate.hqm(yield_curve='par', provider='fred') """ # noqa: E501 return self._run( @@ -231,7 +246,12 @@ def ice_bofa( Literal["yield", "yield_to_worst", "total_return", "spread"], OpenBBCustomParameter(description="The type of series."), ] = "yield", - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """ICE BofA US Corporate Bond Indices. @@ -285,10 +305,11 @@ def ice_bofa( rate : Optional[float] ICE BofA US Corporate Bond Indices Rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.corporate.ice_bofa(index_type="yield_to_worst") + >>> obb.fixedincome.corporate.ice_bofa(provider='fred') + >>> obb.fixedincome.corporate.ice_bofa(index_type='yield_to_worst', provider='fred') """ # noqa: E501 return self._run( @@ -330,7 +351,12 @@ def moody( Literal["aaa", "baa"], OpenBBCustomParameter(description="The type of series."), ] = "aaa", - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Moody Corporate Bond Index. @@ -377,10 +403,11 @@ def moody( rate : Optional[float] Moody Corporate Bond Index Rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.corporate.moody(index_type="baa") + >>> obb.fixedincome.corporate.moody(provider='fred') + >>> obb.fixedincome.corporate.moody(index_type='baa', provider='fred') """ # noqa: E501 return self._run( @@ -429,8 +456,14 @@ def spot_rates( OpenBBCustomParameter( description="Rate category. Options: spot_rate, par_yield. Multiple items allowed for provider(s): fred." ), + OpenBBCustomChoices(choices=["par_yield", "spot_rate"]), ] = "spot_rate", - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Spot Rates. @@ -477,10 +510,11 @@ def spot_rates( rate : Optional[float] Spot Rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.corporate.spot_rates(maturity=[10,20,30,50]) + >>> obb.fixedincome.corporate.spot_rates(provider='fred') + >>> obb.fixedincome.corporate.spot_rates(maturity='10,20,30,50', provider='fred') """ # noqa: E501 return self._run( @@ -502,10 +536,7 @@ def spot_rates( extra_params=kwargs, extra_info={ "maturity": {"multiple_items_allowed": ["fred"]}, - "category": { - "choices": ["par_yield", "spot_rate"], - "multiple_items_allowed": ["fred"], - }, + "category": {"multiple_items_allowed": ["fred"]}, }, ) ) diff --git a/openbb_platform/openbb/package/fixedincome_government.py b/openbb_platform/openbb/package/fixedincome_government.py index 68d7c9540513..5b0f6169e6cf 100644 --- a/openbb_platform/openbb/package/fixedincome_government.py +++ b/openbb_platform/openbb/package/fixedincome_government.py @@ -36,7 +36,12 @@ def treasury_rates( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["federal_reserve", "fmp"]] = None, + provider: Annotated[ + Optional[Literal["federal_reserve", "fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'federal_reserve' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Government Treasury Rates. @@ -97,10 +102,10 @@ def treasury_rates( year_30 : Optional[float] 30 year Treasury rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.government.treasury_rates(provider="federal_reserve") + >>> obb.fixedincome.government.treasury_rates(provider='fmp') """ # noqa: E501 return self._run( @@ -135,7 +140,12 @@ def us_yield_curve( Optional[bool], OpenBBCustomParameter(description="Get inflation adjusted rates."), ] = False, - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """US Yield Curve. Get United States yield curve. @@ -172,10 +182,11 @@ def us_yield_curve( rate : float Associated rate given in decimal form (0.05 is 5%) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.government.us_yield_curve(inflation_adjusted=True) + >>> obb.fixedincome.government.us_yield_curve(provider='fred') + >>> obb.fixedincome.government.us_yield_curve(inflation_adjusted=True, provider='fred') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/fixedincome_rate.py b/openbb_platform/openbb/package/fixedincome_rate.py index 3049e7766494..17cb78b99e6e 100644 --- a/openbb_platform/openbb/package/fixedincome_rate.py +++ b/openbb_platform/openbb/package/fixedincome_rate.py @@ -42,7 +42,12 @@ def ameribor( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Ameribor. @@ -86,10 +91,11 @@ def ameribor( rate : Optional[float] AMERIBOR rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.rate.ameribor(parameter="30_day_ma").to_df() + >>> obb.fixedincome.rate.ameribor(provider='fred') + >>> obb.fixedincome.rate.ameribor(parameter='30_day_ma', provider='fred') """ # noqa: E501 return self._run( @@ -126,7 +132,12 @@ def dpcredit( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Discount Window Primary Credit Rate. @@ -171,10 +182,11 @@ def dpcredit( rate : Optional[float] Discount Window Primary Credit Rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.rate.dpcredit(start_date="2023-02-01", end_date="2023-05-01").to_df() + >>> obb.fixedincome.rate.dpcredit(provider='fred') + >>> obb.fixedincome.rate.dpcredit(start_date='2023-02-01', end_date='2023-05-01', provider='fred') """ # noqa: E501 return self._run( @@ -215,7 +227,12 @@ def ecb( Literal["deposit", "lending", "refinancing"], OpenBBCustomParameter(description="The type of interest rate."), ] = "lending", - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """European Central Bank Interest Rates. @@ -262,10 +279,11 @@ def ecb( rate : Optional[float] European Central Bank Interest Rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.rate.ecb(interest_rate_type="refinancing") + >>> obb.fixedincome.rate.ecb(provider='fred') + >>> obb.fixedincome.rate.ecb(interest_rate_type='refinancing', provider='fred') """ # noqa: E501 return self._run( @@ -303,7 +321,12 @@ def effr( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["federal_reserve", "fred"]] = None, + provider: Annotated[ + Optional[Literal["federal_reserve", "fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'federal_reserve' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Fed Funds Rate. @@ -347,10 +370,11 @@ def effr( rate : Optional[float] FED rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.rate.effr(parameter="daily", provider="fred").to_df() + >>> obb.fixedincome.rate.effr(provider='fred') + >>> obb.fixedincome.rate.effr(parameter='daily', provider='fred') """ # noqa: E501 return self._run( @@ -374,7 +398,14 @@ def effr( @exception_handler @validate def effr_forecast( - self, provider: Optional[Literal["fred"]] = None, **kwargs + self, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, + **kwargs ) -> OBBject: """Fed Funds Rate Projections. @@ -426,10 +457,11 @@ def effr_forecast( central_tendency_low : Optional[float] Central tendency of low projection of rates. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.rate.effr_forecast(long_run=True) + >>> obb.fixedincome.rate.effr_forecast(provider='fred') + >>> obb.fixedincome.rate.effr_forecast(long_run=True, provider='fred') """ # noqa: E501 return self._run( @@ -463,7 +495,12 @@ def estr( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Euro Short-Term Rate. @@ -508,10 +545,11 @@ def estr( rate : Optional[float] ESTR rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.rate.estr(parameter="number_of_active_banks") + >>> obb.fixedincome.rate.estr(provider='fred') + >>> obb.fixedincome.rate.estr(parameter='number_of_active_banks', provider='fred') """ # noqa: E501 return self._run( @@ -548,7 +586,12 @@ def iorb( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Interest on Reserve Balances. @@ -590,10 +633,10 @@ def iorb( rate : Optional[float] IORB rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.rate.iorb() + >>> obb.fixedincome.rate.iorb(provider='fred') """ # noqa: E501 return self._run( @@ -630,7 +673,12 @@ def sonia( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Sterling Overnight Index Average. @@ -674,10 +722,11 @@ def sonia( rate : Optional[float] SONIA rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.rate.sonia(parameter="total_nominal_value") + >>> obb.fixedincome.rate.sonia(provider='fred') + >>> obb.fixedincome.rate.sonia(parameter='total_nominal_value', provider='fred') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/fixedincome_spreads.py b/openbb_platform/openbb/package/fixedincome_spreads.py index 9c420f701cd0..b70c58e9676f 100644 --- a/openbb_platform/openbb/package/fixedincome_spreads.py +++ b/openbb_platform/openbb/package/fixedincome_spreads.py @@ -41,7 +41,12 @@ def tcm( Optional[Literal["3m", "2y"]], OpenBBCustomParameter(description="The maturity"), ] = "3m", - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Treasury Constant Maturity. @@ -86,10 +91,11 @@ def tcm( rate : Optional[float] TreasuryConstantMaturity Rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.fixedincome.spreads.tcm(maturity="2y") + >>> obb.fixedincome.spreads.tcm(provider='fred') + >>> obb.fixedincome.spreads.tcm(maturity='2y', provider='fred') """ # noqa: E501 return self._run( @@ -131,7 +137,12 @@ def tcm_effr( Optional[Literal["10y", "5y", "1y", "6m", "3m"]], OpenBBCustomParameter(description="The maturity"), ] = "10y", - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Select Treasury Constant Maturity. @@ -176,10 +187,11 @@ def tcm_effr( rate : Optional[float] Selected Treasury Constant Maturity Rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.fixedincome.spreads.tcm_effr(maturity="10y") + >>> obb.fixedincome.spreads.tcm_effr(provider='fred') + >>> obb.fixedincome.spreads.tcm_effr(maturity='10y', provider='fred') """ # noqa: E501 return self._run( @@ -221,7 +233,12 @@ def treasury_effr( Optional[Literal["3m", "6m"]], OpenBBCustomParameter(description="The maturity"), ] = "3m", - provider: Optional[Literal["fred"]] = None, + provider: Annotated[ + Optional[Literal["fred"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fred' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Select Treasury Bill. @@ -267,10 +284,11 @@ def treasury_effr( rate : Optional[float] SelectedTreasuryBill Rate. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.fixedincome.fixedincome.spreads.treasury_effr(maturity="6m") + >>> obb.fixedincome.spreads.treasury_effr(provider='fred') + >>> obb.fixedincome.spreads.treasury_effr(maturity='6m', provider='fred') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/index.py b/openbb_platform/openbb/package/index.py index a65de36b82ab..0d945611d798 100644 --- a/openbb_platform/openbb/package/index.py +++ b/openbb_platform/openbb/package/index.py @@ -27,7 +27,14 @@ def __repr__(self) -> str: @exception_handler @validate def available( - self, provider: Optional[Literal["fmp", "yfinance"]] = None, **kwargs + self, + provider: Annotated[ + Optional[Literal["fmp", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, + **kwargs ) -> OBBject: """All indices available from a given provider. @@ -67,10 +74,11 @@ def available( symbol : Optional[str] Symbol for the index. (provider: yfinance) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.index.available(provider="yfinance").to_df() + >>> obb.index.available(provider='fmp') + >>> obb.index.available(provider='yfinance') """ # noqa: E501 return self._run( @@ -95,7 +103,12 @@ def constituents( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["fmp"]] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Index Constituents. @@ -142,12 +155,10 @@ def constituents( founded : Optional[Union[str, date]] Founding year of the constituent company in the index. (provider: fmp) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.index.constituents("dowjones", provider="fmp").to_df() - >>> #### Providers other than FMP will use the ticker symbol. #### - >>> obb.index.constituents("BEP50P", provider="cboe").to_df() + >>> obb.index.constituents(symbol='dowjones', provider='fmp') """ # noqa: E501 return self._run( @@ -178,7 +189,7 @@ def market( symbol: Annotated[ Union[str, List[str]], OpenBBCustomParameter( - description="Symbol to get data for. Multiple items allowed for provider(s): yfinance." + description="Symbol to get data for. Multiple items allowed for provider(s): fmp, intrinio, polygon, yfinance." ), ], start_date: Annotated[ @@ -193,7 +204,16 @@ def market( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["fmp", "intrinio", "polygon", "yfinance"]] = None, + interval: Annotated[ + Optional[str], + OpenBBCustomParameter(description="Time interval of the data to return."), + ] = "1d", + provider: Annotated[ + Optional[Literal["fmp", "intrinio", "polygon", "yfinance"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'fmp' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Historical Market Indices. @@ -201,41 +221,21 @@ def market( Parameters ---------- symbol : Union[str, List[str]] - Symbol to get data for. Multiple items allowed for provider(s): yfinance. + Symbol to get data for. Multiple items allowed for provider(s): fmp, intrinio, polygon, yfinance. start_date : Union[datetime.date, None, str] Start date of the data, in YYYY-MM-DD format. end_date : Union[datetime.date, None, str] End date of the data, in YYYY-MM-DD format. + interval : Optional[str] + Time interval of the data to return. provider : Optional[Literal['fmp', 'intrinio', 'polygon', 'yfinance']] The provider to use for the query, by default None. If None, the provider specified in defaults is selected or 'fmp' if there is no default. - timeseries : Optional[Annotated[int, Ge(ge=0)]] - Number of days to look back. (provider: fmp) - interval : Optional[Union[Literal['1min', '5min', '15min', '30min', '1hour', '4hour', '1day'], Literal['1m', '2m', '5m', '15m', '30m', '60m', '90m', '1h', '1d', '5d', '1W', '1M', '1Q']]] - Data granularity. (provider: fmp, yfinance) - sort : Literal['asc', 'desc'] - Sort the data in ascending or descending order. (provider: fmp); - Sort order. (provider: intrinio); - Sort order of the data. (provider: polygon) - tag : Optional[str] - Index tag. (provider: intrinio) - type : Optional[str] - Index type. (provider: intrinio) - limit : int + limit : Optional[int] The number of data entries to return. (provider: intrinio, polygon) - timespan : Literal['minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'] - Timespan of the data. (provider: polygon) - adjusted : bool - Whether the data is adjusted. (provider: polygon) - multiplier : int - Multiplier of the timespan. (provider: polygon) - period : Optional[Literal['1d', '5d', '1mo', '3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max']] - Time period of the data to return. (provider: yfinance) - prepost : bool - Include Pre and Post market data. (provider: yfinance) - rounding : bool - Round prices to two decimals? (provider: yfinance) + sort : Literal['asc', 'desc'] + Sort order of the data. This impacts the results in combination with the 'limit' parameter. The results are always returned in ascending order by date. (provider: polygon) Returns ------- @@ -253,7 +253,7 @@ def market( MarketIndices ------------- - date : datetime + date : Union[date, datetime] The date of the data. open : Optional[Annotated[float, Strict(strict=True)]] The open price. @@ -265,25 +265,19 @@ def market( The close price. volume : Optional[int] The trading volume. - adj_close : Optional[float] - The adjusted close price. (provider: fmp) - unadjusted_volume : Optional[float] - Unadjusted volume of the symbol. (provider: fmp) + vwap : Optional[float] + Volume Weighted Average Price over the period. (provider: fmp) change : Optional[float] - Change in the price of the symbol from the previous day. (provider: fmp) + Change in the price from the previous close. (provider: fmp) change_percent : Optional[float] - Change % in the price of the symbol. (provider: fmp) - label : Optional[str] - Human readable format of the date. (provider: fmp) - change_over_time : Optional[float] - Change % in the price of the symbol over a period of time. (provider: fmp) + Change in the price from the previous close, as a normalized percent. (provider: fmp) transactions : Optional[Annotated[int, Gt(gt=0)]] Number of transactions for the symbol in the time period. (provider: polygon) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.index.market(symbol="SPX") + >>> obb.index.market(symbol='^IBEX', provider='fmp') """ # noqa: E501 simplefilter("always", DeprecationWarning) @@ -307,9 +301,19 @@ def market( "symbol": symbol, "start_date": start_date, "end_date": end_date, + "interval": interval, }, extra_params=kwargs, - extra_info={"symbol": {"multiple_items_allowed": ["yfinance"]}}, + extra_info={ + "symbol": { + "multiple_items_allowed": [ + "fmp", + "intrinio", + "polygon", + "yfinance", + ] + } + }, ) ) diff --git a/openbb_platform/openbb/package/news.py b/openbb_platform/openbb/package/news.py index 0f1f140b580d..52601f5905fd 100644 --- a/openbb_platform/openbb/package/news.py +++ b/openbb_platform/openbb/package/news.py @@ -47,8 +47,13 @@ def company( Optional[Annotated[int, Ge(ge=0)]], OpenBBCustomParameter(description="The number of data entries to return."), ] = 2500, - provider: Optional[ - Literal["benzinga", "fmp", "intrinio", "polygon", "tiingo", "yfinance"] + provider: Annotated[ + Optional[ + Literal["benzinga", "fmp", "intrinio", "polygon", "tiingo", "yfinance"] + ], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'benzinga' if there is\n no default." + ), ] = None, **kwargs ) -> OBBject: @@ -156,18 +161,19 @@ def company( crawl_date : Optional[datetime] Date the news article was crawled. (provider: tiingo) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.news.company(limit=2500) + >>> obb.news.company(provider='benzinga') + >>> obb.news.company(limit=100, provider='benzinga') >>> # Get news on the specified dates. - >>> obb.news.company(symbol='AAPL', start_date='2024-02-01', end_date='2024-02-07') + >>> obb.news.company(symbol='AAPL', start_date='2024-02-01', end_date='2024-02-07', provider='intrinio') >>> # Display the headlines of the news. >>> obb.news.company(symbol='AAPL', display='headline', provider='benzinga') >>> # Get news for multiple symbols. - >>> obb.news.company(symbol='aapl,tsla') + >>> obb.news.company(symbol='aapl,tsla', provider='fmp') >>> # Get news company's ISIN. - >>> obb.news.company(symbol='NVDA', isin='US0378331005') + >>> obb.news.company(symbol='NVDA', isin='US0378331005', provider='benzinga') """ # noqa: E501 return self._run( @@ -231,7 +237,12 @@ def world( description="End date of the data, in YYYY-MM-DD format." ), ] = None, - provider: Optional[Literal["benzinga", "fmp", "intrinio", "tiingo"]] = None, + provider: Annotated[ + Optional[Literal["benzinga", "fmp", "intrinio", "tiingo"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'benzinga' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """World News. Global news data. @@ -328,20 +339,19 @@ def world( crawl_date : Optional[datetime] Date the news article was crawled. (provider: tiingo) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.news.world(limit=2500) + >>> obb.news.world(provider='fmp') + >>> obb.news.world(limit=100, provider='intrinio') >>> # Get news on the specified dates. - >>> obb.news.world(start_date='2024-02-01', end_date='2024-02-07') + >>> obb.news.world(start_date='2024-02-01', end_date='2024-02-07', provider='intrinio') >>> # Display the headlines of the news. >>> obb.news.world(display='headline', provider='benzinga') >>> # Get news by topics. >>> obb.news.world(topics='finance', provider='benzinga') >>> # Get news by source using 'tingo' as provider. >>> obb.news.world(provider='tiingo', source='bloomberg') - >>> # Filter aticles by term using 'biztoc' as provider. - >>> obb.news.world(provider='biztoc', term='apple') """ # noqa: E501 return self._run( diff --git a/openbb_platform/openbb/package/regulators_sec.py b/openbb_platform/openbb/package/regulators_sec.py index 91c050b1badf..4b0ebcf377c1 100644 --- a/openbb_platform/openbb/package/regulators_sec.py +++ b/openbb_platform/openbb/package/regulators_sec.py @@ -30,7 +30,12 @@ def cik_map( symbol: Annotated[ str, OpenBBCustomParameter(description="Symbol to get data for.") ], - provider: Optional[Literal["sec"]] = None, + provider: Annotated[ + Optional[Literal["sec"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'sec' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Map a ticker symbol to a CIK number. @@ -63,11 +68,10 @@ def cik_map( cik : Optional[Union[int, str]] Central Index Key (CIK) for the requested entity. - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.regulators.sec.cik_map(symbol="MSFT").results.cik - >>> 0000789019 + >>> obb.regulators.sec.cik_map(symbol='MSFT', provider='sec') """ # noqa: E501 return self._run( @@ -98,7 +102,12 @@ def institutions_search( description="Whether or not to use cache. If True, cache will store for seven days." ), ] = True, - provider: Optional[Literal["sec"]] = None, + provider: Annotated[ + Optional[Literal["sec"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'sec' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Search SEC-regulated institutions by name and return a list of results with CIK numbers. @@ -135,10 +144,11 @@ def institutions_search( cik : Optional[Union[int, str]] Central Index Key (CIK) (provider: sec) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.regulators.sec.institutions_search(query="blackstone real estate").to_df() + >>> obb.regulators.sec.institutions_search(provider='sec') + >>> obb.regulators.sec.institutions_search(query='blackstone real estate', provider='sec') """ # noqa: E501 return self._run( @@ -162,7 +172,14 @@ def institutions_search( @exception_handler @validate def rss_litigation( - self, provider: Optional[Literal["sec"]] = None, **kwargs + self, + provider: Annotated[ + Optional[Literal["sec"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'sec' if there is\n no default." + ), + ] = None, + **kwargs ) -> OBBject: """The RSS feed provides links to litigation releases concerning civil lawsuits brought by the Commission in federal court. @@ -200,10 +217,10 @@ def rss_litigation( link : Optional[str] URL to the release. (provider: sec) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.regulators.sec.rss_litigation().to_dict("records")[0] + >>> obb.regulators.sec.rss_litigation(provider='sec') """ # noqa: E501 return self._run( @@ -232,7 +249,12 @@ def schema_files( description="Whether or not to use cache. If True, cache will store for seven days." ), ] = True, - provider: Optional[Literal["sec"]] = None, + provider: Annotated[ + Optional[Literal["sec"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'sec' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """A tool for navigating the directory of SEC XML schema files by year. @@ -269,26 +291,28 @@ def schema_files( files : Optional[List[str]] Dictionary of URLs to SEC Schema Files (provider: sec) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> data = obb.regulators.sec.schema_files() + >>> obb.regulators.sec.schema_files(provider='sec') + >>> # Get a list of schema files. + >>> data = obb.regulators.sec.schema_files().results >>> data.files[0] - >>> https://xbrl.fasb.org/us-gaap/ - >>> #### The directory structure can be navigated by constructing a URL from the 'results' list. #### + >>> 'https://xbrl.fasb.org/us-gaap/' + >>> # The directory structure can be navigated by constructing a URL from the 'results' list. >>> url = data.files[0]+data.files[-1] - >>> #### The URL base will always be the 0 position in the list, feed the URL back in as a parameter. #### + >>> # The URL base will always be the 0 position in the list, feed the URL back in as a parameter. >>> obb.regulators.sec.schema_files(url=url).results.files - >>> ['https://xbrl.fasb.org/us-gaap/2024/' - >>> 'USGAAP2024FileList.xml' - >>> 'dis/' - >>> 'dqcrules/' - >>> 'ebp/' - >>> 'elts/' - >>> 'entire/' - >>> 'meta/' - >>> 'stm/' - >>> 'us-gaap-2024.zip'] + >>> ['https://xbrl.fasb.org/us-gaap/2024/' + >>> 'USGAAP2024FileList.xml' + >>> 'dis/' + >>> 'dqcrules/' + >>> 'ebp/' + >>> 'elts/' + >>> 'entire/' + >>> 'meta/' + >>> 'stm/' + >>> 'us-gaap-2024.zip'] """ # noqa: E501 return self._run( @@ -320,7 +344,12 @@ def sic_search( description="Whether or not to use cache. If True, cache will store for seven days." ), ] = True, - provider: Optional[Literal["sec"]] = None, + provider: Annotated[ + Optional[Literal["sec"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'sec' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Search for Industry Titles, Reporting Office, and SIC Codes. An empty query string returns all results. @@ -359,10 +388,11 @@ def sic_search( office : Optional[str] Reporting office within the Corporate Finance Office (provider: sec) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.regulators.sec.sic_search("real estate investment trusts").results + >>> obb.regulators.sec.sic_search(provider='sec') + >>> obb.regulators.sec.sic_search(query='real estate investment trusts', provider='sec') """ # noqa: E501 return self._run( @@ -387,14 +417,19 @@ def sic_search( @validate def symbol_map( self, - query: Annotated[str, OpenBBCustomParameter(description="Search query.")] = "", + query: Annotated[str, OpenBBCustomParameter(description="Search query.")], use_cache: Annotated[ Optional[bool], OpenBBCustomParameter( description="Whether or not to use cache. If True, cache will store for seven days." ), ] = True, - provider: Optional[Literal["sec"]] = None, + provider: Annotated[ + Optional[Literal["sec"]], + OpenBBCustomParameter( + description="The provider to use for the query, by default None.\n If None, the provider specified in defaults is selected or 'sec' if there is\n no default." + ), + ] = None, **kwargs ) -> OBBject: """Map a CIK number to a ticker symbol, leading 0s can be omitted or included. @@ -429,11 +464,10 @@ def symbol_map( symbol : Optional[str] Symbol representing the entity requested in the data. (provider: sec) - Example - ------- + Examples + -------- >>> from openbb import obb - >>> obb.regulators.sec.symbol_map("0000789019").results.symbol - >>> MSFT + >>> obb.regulators.sec.symbol_map(query='0000789019', provider='sec') """ # noqa: E501 return self._run( diff --git a/openbb_platform/providers/finra/openbb_finra/models/equity_short_interest.py b/openbb_platform/providers/finra/openbb_finra/models/equity_short_interest.py index d63e67540ea9..f55dc4210ebc 100644 --- a/openbb_platform/providers/finra/openbb_finra/models/equity_short_interest.py +++ b/openbb_platform/providers/finra/openbb_finra/models/equity_short_interest.py @@ -10,6 +10,8 @@ ) from openbb_finra.utils.data_storage import DB_PATH, prepare_data +# pylint: disable=unused-argument + class FinraShortInterestQueryParams(ShortInterestQueryParams): """FINRA Equity Short Interest Query.""" @@ -54,12 +56,11 @@ def extract_data( # Get the data from the cache cnx = sqlite3.connect(DB_PATH) cursor = cnx.cursor() - if query.symbol: - cursor.execute( - "SELECT * FROM short_interest where symbolCode = ?", (query.symbol,) - ) - else: - cursor.execute("SELECT * FROM short_interest") + cursor.execute( + "SELECT * FROM short_interest where symbolCode = ?", (query.symbol,) + ) + # TODO: Check if we should allow general queries, it's more than 500k rows + # cursor.execute("SELECT * FROM short_interest") result = cursor.fetchall() titles = [ @@ -74,10 +75,7 @@ def extract_data( "changePreviousNumber", "settlementDate", ] - return [ - {title: value for title, value in zip(titles, list(row)[1:])} - for row in result - ] + return [dict(zip(titles, list(row)[1:])) for row in result] @staticmethod def transform_data( diff --git a/openbb_platform/providers/government_us/openbb_government_us/models/treasury_prices.py b/openbb_platform/providers/government_us/openbb_government_us/models/treasury_prices.py index fceb35b327b9..15e7e1bb0d01 100644 --- a/openbb_platform/providers/government_us/openbb_government_us/models/treasury_prices.py +++ b/openbb_platform/providers/government_us/openbb_government_us/models/treasury_prices.py @@ -12,8 +12,9 @@ TreasuryPricesData, TreasuryPricesQueryParams, ) +from openbb_core.provider.utils.errors import EmptyDataError from openbb_government_us.utils.helpers import get_random_agent -from pandas import read_csv, to_datetime +from pandas import Index, read_csv, to_datetime from pydantic import Field @@ -111,18 +112,21 @@ def transform_data( """Transform the data.""" try: + if not data: + raise EmptyDataError("Data not found") results = read_csv(StringIO(data), header=0) - columns = [ - "cusip", - "security_type", - "rate", - "maturity_date", - "call_date", - "bid", - "offer", - "eod_price", - ] - results.columns = columns + results.columns = Index( + [ + "cusip", + "security_type", + "rate", + "maturity_date", + "call_date", + "bid", + "offer", + "eod_price", + ] + ) results["date"] = query.date.strftime("%Y-%m-%d") # type: ignore for col in ["maturity_date", "call_date"]: results[col] = ( diff --git a/openbb_platform/providers/polygon/openbb_polygon/models/currency_pairs.py b/openbb_platform/providers/polygon/openbb_polygon/models/currency_pairs.py index 2ea951781d2f..965878c06c3b 100644 --- a/openbb_platform/providers/polygon/openbb_polygon/models/currency_pairs.py +++ b/openbb_platform/providers/polygon/openbb_polygon/models/currency_pairs.py @@ -105,12 +105,12 @@ class PolygonCurrencyPairsFetcher( def transform_query(params: Dict[str, Any]) -> PolygonCurrencyPairsQueryParams: """Transform the query parameters. Ticker is set if symbol is provided.""" transform_params = params - now = datetime.now().date() + now = datetime.now().date().isoformat() transform_params["symbol"] = ( f"ticker=C:{params.get('symbol').upper()}" if params.get("symbol") else "" ) if params.get("date") is None: - transform_params["start_date"] = now + transform_params["date"] = now return PolygonCurrencyPairsQueryParams(**transform_params) diff --git a/openbb_platform/providers/sec/openbb_sec/models/symbol_map.py b/openbb_platform/providers/sec/openbb_sec/models/symbol_map.py index 7d977093a5b0..449d4202ee69 100644 --- a/openbb_platform/providers/sec/openbb_sec/models/symbol_map.py +++ b/openbb_platform/providers/sec/openbb_sec/models/symbol_map.py @@ -4,13 +4,15 @@ from openbb_core.provider.abstract.data import Data from openbb_core.provider.abstract.fetcher import Fetcher -from openbb_core.provider.standard_models.cot_search import CotSearchQueryParams +from openbb_core.provider.standard_models.symbol_map import SymbolMapQueryParams from openbb_core.provider.utils.descriptions import DATA_DESCRIPTIONS from openbb_sec.utils.helpers import cik_map from pydantic import Field +# pylint: disable=unused-argument -class SecSymbolMapQueryParams(CotSearchQueryParams): + +class SecSymbolMapQueryParams(SymbolMapQueryParams): """SEC Symbol Mapping Query. Source: https://sec.gov/ @@ -43,9 +45,13 @@ def extract_data( **kwargs: Any, ) -> Dict: """Return the raw data from the SEC endpoint.""" + if not query.query.isdigit(): + raise ValueError("Query is required and must be a valid CIK.") return {"symbol": cik_map(int(query.query))} @staticmethod - def transform_data(data: Dict, **kwargs: Any) -> SecSymbolMapData: + def transform_data( + query: SecSymbolMapQueryParams, data: Dict, **kwargs: Any + ) -> SecSymbolMapData: """Transform the data to the standard format.""" return SecSymbolMapData.model_validate(data) diff --git a/website/generate_excel_markdown.py b/website/generate_excel_markdown.py index e92585d9f5db..a44057862162 100644 --- a/website/generate_excel_markdown.py +++ b/website/generate_excel_markdown.py @@ -4,10 +4,9 @@ from functools import reduce from pathlib import Path from textwrap import shorten -from typing import Any, Dict, List, Literal +from typing import Any, Dict, List, Literal, Optional import requests -from requests_cache import Optional # Paths WEBSITE_PATH = Path(__file__).parent.absolute()