diff --git a/openbb_sdk/sdk/core/openbb_core/app/model/obbject.py b/openbb_sdk/sdk/core/openbb_core/app/model/obbject.py index c5de65a8e5b..69f44838e11 100644 --- a/openbb_sdk/sdk/core/openbb_core/app/model/obbject.py +++ b/openbb_sdk/sdk/core/openbb_core/app/model/obbject.py @@ -1,7 +1,8 @@ +"""The OBBject.""" from typing import Dict, Generic, List, Literal, Optional, TypeVar, Union import pandas as pd -from pydantic import Field +from pydantic import BaseModel, Field from pydantic.generics import GenericModel from openbb_core.app.charting_manager import ChartingManager @@ -42,45 +43,60 @@ class OBBject(GenericModel, Generic[T], Tagged): ) def __repr__(self) -> str: - return f"{self.__class__.__name__}\n\n" + "\n".join( - f"{k}: {v}" for k, v in self.dict().items() + """Human readable representation of the object.""" + return ( + self.__class__.__name__ + + "\n\n" + + "\n".join( + [ + f"{k}: {v}"[:83] + + ("..." if len(f"{k}: {v}") > len(f"{k}: {v}"[:83]) else "") + for k, v in self.dict().items() + ] + ) ) - def to_dataframe( - self, concat: bool = True - ) -> Union[pd.DataFrame, Dict[str, pd.DataFrame]]: - """Converts results field to pandas dataframe. + def to_dataframe(self) -> Union[pd.DataFrame, Dict[str, pd.DataFrame]]: + """Convert results field to pandas dataframe. - Parameters - ---------- - concat : bool, optional - If True, it concatenates the dataframes, by default True. + Supports converting creating pandas DataFrames from the following + serializable data formats: + + - List[Basemodel] + - List[Dict] + - List[List] + - List[str] + - List[int] + - List[float] + - Dict[str, Dict] + - Dict[str, List] Returns ------- Union[pd.DataFrame, Dict[str, pd.DataFrame]] Pandas dataframe or dictionary of dataframes. """ - if not self.results: + if self.results is None or self.results == []: raise OpenBBError("Results not found.") try: res = self.results - if isinstance(res, list): - if isinstance(res[0], dict): - for r in res: - dict_of_df = { - k: basemodel_to_df(v, "date") for k, v in r.items() - } - df = pd.concat(dict_of_df, axis=1) if concat else dict_of_df - else: - df = basemodel_to_df(res, "date") # type: ignore + df = None + + if isinstance(res, list) and all( + isinstance(item, BaseModel) for item in res + ): + df = basemodel_to_df(res, "date") else: - df = basemodel_to_df(res, "date") # type: ignore + df = pd.DataFrame(res) + + if df is None: + raise OpenBBError("Unsupported data format.") # Improve output so that all columns that are None are not returned df = df.dropna(axis=1, how="all") + df.sort_index(axis=1, inplace=True) except Exception as e: raise OpenBBError("Failed to convert results to DataFrame.") from e @@ -88,7 +104,7 @@ class OBBject(GenericModel, Generic[T], Tagged): return df def to_dict(self) -> Dict[str, List]: - """Converts results field to list of values. + """Convert results field to list of values. Returns ------- @@ -103,8 +119,8 @@ class OBBject(GenericModel, Generic[T], Tagged): return results def to_chart(self, **kwargs): - """ - Create or update the `Chart`. + """Create or update the `Chart`. + Note that the `chart` attribute is composed by: `content`, `format` and `fig`. Parameters @@ -126,8 +142,7 @@ class OBBject(GenericModel, Generic[T], Tagged): return self.chart.fig def show(self): - """Displays chart.""" - + """Display chart.""" if not self.chart or not self.chart.fig: raise OpenBBError("Chart not found.") self.chart.fig.show()