From 0178f6a5bd87433e21c73cf12ad035a3e56d3acc Mon Sep 17 00:00:00 2001 From: Danglewood <85772166+deeleeramone@users.noreply.github.com> Date: Thu, 20 Feb 2025 08:49:22 -0800 Subject: [PATCH] [Feature] Align Python Interface With API - Stop Requiring `OBBject` As Output Type In `PackageBuilder` As Default (#7031) * stop enforcing OBBject as output type in PackageBuilder * mypy --- .../core/openbb_core/app/command_runner.py | 9 +---- .../openbb_core/app/static/package_builder.py | 36 +++++++++++++++---- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/openbb_platform/core/openbb_core/app/command_runner.py b/openbb_platform/core/openbb_core/app/command_runner.py index ebeac7f863d..b098daf8d50 100644 --- a/openbb_platform/core/openbb_core/app/command_runner.py +++ b/openbb_platform/core/openbb_core/app/command_runner.py @@ -329,19 +329,12 @@ class StaticCommandRunner: for name, default in model_headers.items() or {} } or None - validate = not execution_context.api_route.openapi_extra.get("no_validate") try: obbject = await cls._command(func, kwargs) # The output might be from a router command with 'no_validate=True' # It might be of a different type than OBBject. # In this case, we avoid accessing those attributes. - if isinstance(obbject, OBBject) or validate: - if validate and not isinstance(obbject, OBBject): - raise OpenBBError( - TypeError( - f"Expected OBBject instance at function output, got {type(obbject)} instead." - ) - ) + if isinstance(obbject, OBBject): # This section prepares the obbject to pass to the charting service. obbject._route = route # pylint: disable=protected-access std_params = cls._extract_params(kwargs, "standard_params") or ( 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 9eae47982da..aa9c06677c7 100644 --- a/openbb_platform/core/openbb_core/app/static/package_builder.py +++ b/openbb_platform/core/openbb_core/app/static/package_builder.py @@ -334,11 +334,11 @@ class ImportDefinition: hint_type_list.append(parameter.annotation) if return_type: - if not no_validate and not issubclass(return_type, OBBject): - raise ValueError("Return type must be an OBBject.") hint_type = ( get_args(get_type_hints(return_type)["results"])[0] - if "OBBject" in return_type.__class__.__name__ + if hasattr(return_type, "__class__") + and hasattr(return_type.__class__, "__name__") + and "OBBject" in return_type.__class__.__name__ else return_type ) hint_type_list.append(hint_type) @@ -1690,7 +1690,7 @@ class ReferenceGenerator: # Adjust regex to correctly capture content inside brackets, including nested brackets content_inside_brackets = re.search( r"OBBject\[\s*((?:[^\[\]]|\[[^\[\]]*\])*)\s*\]", return_type - ) + ) or re.search(r"list\[\s*((?:[^\[\]]|\[[^\[\]]*\])*)\s*\]", return_type) return_type = ( # type: ignore content_inside_brackets.group(1) if content_inside_brackets is not None @@ -1833,6 +1833,10 @@ class ReferenceGenerator: # may not contain the "Parameters" and "Returns" sections. Hence, the # endpoint function docstring is used instead. docstring = getattr(route_func, "__doc__", "") + + if not docstring: + continue + description = docstring.split("Parameters")[0].strip() # Remove extra spaces in between the string reference[path]["description"] = re.sub(" +", " ", description) @@ -1847,9 +1851,27 @@ class ReferenceGenerator: "description": "Unvalidated results object.", } else: - reference[path]["returns"]["OBBject"] = ( - cls._get_post_method_returns_info(docstring) - ) + returns_info = cls._get_post_method_returns_info(docstring) + if returns_info and "OBBject" in returns_info[0]["type"]: + reference[path]["returns"]["OBBject"] = returns_info + else: + r_info = returns_info[0] if returns_info else {} + r_type = r_info.pop("type", "Any") + r_info["name"] = None # type: ignore + if len(returns_info) == 2: + r_info = returns_info[1] + elif len(returns_info) == 1: + r_info["type"] = "Any" + if r_type: + if "[" in r_type: + c_types = r_type.split("[")[1].split("]")[0] + r_type = r_type.split("[")[0] + r_info["type"] = ( + "[" + c_types + "]" if c_types else "Any" + ) + reference[path]["returns"][r_type] = r_info + else: + reference[path]["returns"] = returns_info return reference