Skip to content

Commit

Permalink
still preparing for polar in enterprise (#1583)
Browse files Browse the repository at this point in the history
Co-authored-by: Fred Lefévère-Laoide <[email protected]>
  • Loading branch information
FredLL-Avaiga and Fred Lefévère-Laoide authored Jul 25, 2024
1 parent ae0d1bb commit 6c8c854
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 202 deletions.
4 changes: 2 additions & 2 deletions taipy/gui/_renderers/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ def _get_dataframe_attributes(self) -> "_Builder":
+ "}"
)
self.__update_vars.append(f"comparedatas={','.join(cmp_datas_hash)}")
col_types = self.__gui._accessors._get_col_types(data_hash, _TaipyData(data, data_hash))
col_types = self.__gui._get_accessor().get_col_types(data_hash, _TaipyData(data, data_hash))
col_dict = _get_columns_dict(
data, self.__attributes.get("columns", {}), col_types, date_format, self.__attributes.get("number_format")
)
Expand Down Expand Up @@ -591,7 +591,7 @@ def _get_chart_config(self, default_type: str, default_mode: str):
# read column definitions
data = self.__attributes.get("data")
data_hash = self.__hashes.get("data", "")
col_types = self.__gui._accessors._get_col_types(data_hash, _TaipyData(data, data_hash))
col_types = self.__gui._get_accessor().get_col_types(data_hash, _TaipyData(data, data_hash))

config = _build_chart_config(self.__gui, self.__attributes, col_types)

Expand Down
29 changes: 18 additions & 11 deletions taipy/gui/data/array_dict_data_accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

import pandas as pd

from ..gui import Gui
from ..utils import _MapDict
from .data_format import _DataFormat
from .pandas_data_accessor import _PandasDataAccessor
Expand All @@ -26,8 +25,8 @@ class _ArrayDictDataAccessor(_PandasDataAccessor):
def get_supported_classes() -> t.List[str]:
return [t.__name__ for t in _ArrayDictDataAccessor.__types] # type: ignore

def _get_dataframe(self, value: t.Any) -> t.Union[t.List[pd.DataFrame], pd.DataFrame]:
if isinstance(value, list):
def to_pandas(self, value: t.Any) -> t.Union[t.List[pd.DataFrame], pd.DataFrame]:
if isinstance(value, (list, tuple)):
if not value or isinstance(value[0], (str, int, float, bool)):
return pd.DataFrame({"0": value})
types = {type(x) for x in value}
Expand All @@ -45,22 +44,30 @@ def _get_dataframe(self, value: t.Any) -> t.Union[t.List[pd.DataFrame], pd.DataF
elif type_elt is _MapDict:
return [pd.DataFrame(v._dict) for v in value]
elif type_elt is pd.DataFrame:
return value
return t.cast(t.List[pd.DataFrame], value)

elif len(types) == 2 and list in types and pd.DataFrame in types:
return [v if isinstance(v, pd.DataFrame) else pd.DataFrame({f"{i}/0": v}) for i, v in enumerate(value)]
elif isinstance(value, _MapDict):
return pd.DataFrame(value._dict)
return pd.DataFrame(value)

def _from_pandas(self, value: pd.DataFrame, type: t.Type):
if type is dict:
return value.to_dict()
if type is _MapDict:
return _MapDict(value.to_dict())
if len(value.columns) == 1:
if type is list:
return value.iloc[:, 0].to_list()
if type is tuple:
return tuple(value.iloc[:, 0].to_list())
return super()._from_pandas(value, type)

def get_col_types(self, var_name: str, value: t.Any) -> t.Union[None, t.Dict[str, str]]: # type: ignore
if isinstance(value, _ArrayDictDataAccessor.__types): # type: ignore
return super().get_col_types(var_name, self._get_dataframe(value))
return None
return super().get_col_types(var_name, self.to_pandas(value))

def get_data( # noqa: C901
self, guiApp: Gui, var_name: str, value: t.Any, payload: t.Dict[str, t.Any], data_format: _DataFormat
self, var_name: str, value: t.Any, payload: t.Dict[str, t.Any], data_format: _DataFormat
) -> t.Dict[str, t.Any]:
if isinstance(value, _ArrayDictDataAccessor.__types): # type: ignore
return super().get_data(guiApp, var_name, self._get_dataframe(value), payload, data_format)
return {}
return super().get_data(var_name, self.to_pandas(value), payload, data_format)
4 changes: 2 additions & 2 deletions taipy/gui/data/comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ def _compare_function(
return None
compare_fn = gui._get_user_function(compare_name) if compare_name else None
if callable(compare_fn):
return gui._accessors._get_dataframe(
return gui._get_accessor().to_pandas(
gui._call_function_with_state(compare_fn, [name, [gui._get_real_var_name(n) for n in names]])
)
elif compare_fn is not None:
_warn(f"{compare_name}(): compare function name is not valid.")
dfs = [gui._accessors._get_dataframe(_getscopeattr(gui, n)) for n in names]
dfs = [gui._get_accessor().to_pandas(_getscopeattr(gui, n)) for n in names]
return value.compare(dfs[0], keep_shape=True)
except Exception as e:
if not gui._call_on_exception(compare_name or "Gui._compare_function", e):
Expand Down
72 changes: 39 additions & 33 deletions taipy/gui/data/data_accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,24 @@
from ..utils import _TaipyData
from .data_format import _DataFormat

if t.TYPE_CHECKING:
from ..gui import Gui


class _DataAccessor(ABC):
_WS_DATE_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"

def __init__(self, gui: "Gui") -> None:
self._gui = gui

@staticmethod
@abstractmethod
def get_supported_classes() -> t.List[str]:
pass

@abstractmethod
def get_data(
self, guiApp: t.Any, var_name: str, value: t.Any, payload: t.Dict[str, t.Any], data_format: _DataFormat
self, var_name: str, value: t.Any, payload: t.Dict[str, t.Any], data_format: _DataFormat
) -> t.Dict[str, t.Any]:
pass

Expand All @@ -37,23 +43,23 @@ def get_col_types(self, var_name: str, value: t.Any) -> t.Dict[str, str]:
pass

@abstractmethod
def _get_dataframe(self, value: t.Any) -> t.Union[t.List[t.Any], t.Any]:
def to_pandas(self, value: t.Any) -> t.Union[t.List[t.Any], t.Any]:
pass

@abstractmethod
def _on_edit(self, value: t.Any, payload: t.Dict[str, t.Any]):
def on_edit(self, value: t.Any, payload: t.Dict[str, t.Any]):
pass

@abstractmethod
def _on_delete(self, value: t.Any, payload: t.Dict[str, t.Any]):
def on_delete(self, value: t.Any, payload: t.Dict[str, t.Any]):
pass

@abstractmethod
def _on_add(self, value: t.Any, payload: t.Dict[str, t.Any], new_row: t.Optional[t.List[t.Any]] = None):
def on_add(self, value: t.Any, payload: t.Dict[str, t.Any], new_row: t.Optional[t.List[t.Any]] = None):
pass

@abstractmethod
def _to_csv(self, guiApp: t.Any, var_name: str, value: t.Any):
def to_csv(self, var_name: str, value: t.Any):
pass


Expand All @@ -63,36 +69,35 @@ def get_supported_classes() -> t.List[str]:
return [type(None).__name__]

def get_data(
self, guiApp: t.Any, var_name: str, value: t.Any, payload: t.Dict[str, t.Any], data_format: _DataFormat
self, var_name: str, value: t.Any, payload: t.Dict[str, t.Any], data_format: _DataFormat
) -> t.Dict[str, t.Any]:
return {}

def get_col_types(self, var_name: str, value: t.Any) -> t.Dict[str, str]:
return {}

def _get_dataframe(self, value: t.Any) -> t.Union[t.List[t.Any], t.Any]:
def to_pandas(self, value: t.Any) -> t.Union[t.List[t.Any], t.Any]:
return None

def _on_edit(self, value: t.Any, payload: t.Dict[str, t.Any]):
def on_edit(self, value: t.Any, payload: t.Dict[str, t.Any]):
return None

def _on_delete(self, value: t.Any, payload: t.Dict[str, t.Any]):
def on_delete(self, value: t.Any, payload: t.Dict[str, t.Any]):
return None

def _on_add(self, value: t.Any, payload: t.Dict[str, t.Any], new_row: t.Optional[t.List[t.Any]] = None):
def on_add(self, value: t.Any, payload: t.Dict[str, t.Any], new_row: t.Optional[t.List[t.Any]] = None):
return None

def _to_csv(self, guiApp: t.Any, var_name: str, value: t.Any):
def to_csv(self, var_name: str, value: t.Any):
return None


class _DataAccessors(object):
def __init__(self) -> None:
def __init__(self, gui: "Gui") -> None:
self.__access_4_type: t.Dict[str, _DataAccessor] = {}

self.__invalid_data_accessor = _InvalidDataAccessor()

self.__invalid_data_accessor = _InvalidDataAccessor(gui)
self.__data_format = _DataFormat.JSON
self.__gui = gui

from .array_dict_data_accessor import _ArrayDictDataAccessor
from .numpy_data_accessor import _NumpyDataAccessor
Expand All @@ -118,7 +123,7 @@ def _register(self, cls: t.Type[_DataAccessor]) -> None:
break
if inst is None:
try:
inst = cls()
inst = cls(self.__gui)
except Exception as e:
raise TypeError(f"Class {cls.__name__} cannot be instantiated") from e
if inst:
Expand All @@ -134,28 +139,29 @@ def __get_instance(self, value: _TaipyData) -> _DataAccessor: # type: ignore
return self.__invalid_data_accessor
return access

def _get_data(
self, guiApp: t.Any, var_name: str, value: _TaipyData, payload: t.Dict[str, t.Any]
) -> t.Dict[str, t.Any]:
return self.__get_instance(value).get_data(guiApp, var_name, value.get(), payload, self.__data_format)
def get_data(self, var_name: str, value: _TaipyData, payload: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]:
return self.__get_instance(value).get_data(var_name, value.get(), payload, self.__data_format)

def _get_col_types(self, var_name: str, value: _TaipyData) -> t.Dict[str, str]:
def get_col_types(self, var_name: str, value: _TaipyData) -> t.Dict[str, str]:
return self.__get_instance(value).get_col_types(var_name, value.get())

def _set_data_format(self, data_format: _DataFormat):
def set_data_format(self, data_format: _DataFormat):
self.__data_format = data_format

def _get_dataframe(self, value: t.Any):
return self.__get_instance(value)._get_dataframe(value)
def get_dataframe(self, value: t.Any):
return self.__get_instance(value).to_pandas(value)

def on_edit(self, value: t.Any, payload: t.Dict[str, t.Any]):
return self.__get_instance(value).on_edit(value, payload)

def _on_edit(self, value: t.Any, payload: t.Dict[str, t.Any]):
return self.__get_instance(value)._on_edit(value, payload)
def on_delete(self, value: t.Any, payload: t.Dict[str, t.Any]):
return self.__get_instance(value).on_delete(value, payload)

def _on_delete(self, value: t.Any, payload: t.Dict[str, t.Any]):
return self.__get_instance(value)._on_delete(value, payload)
def on_add(self, value: t.Any, payload: t.Dict[str, t.Any], new_row: t.Optional[t.List[t.Any]] = None):
return self.__get_instance(value).on_add(value, payload, new_row)

def _on_add(self, value: t.Any, payload: t.Dict[str, t.Any], new_row: t.Optional[t.List[t.Any]] = None):
return self.__get_instance(value)._on_add(value, payload, new_row)
def to_csv(self, var_name: str, value: t.Any):
return self.__get_instance(value).to_csv(var_name, value.get())

def _to_csv(self, guiApp: t.Any, var_name: str, value: t.Any):
return self.__get_instance(value)._to_csv(guiApp, var_name, value.get())
def to_pandas(self, value: t.Any):
return self.__get_instance(value).to_pandas(value.get())
19 changes: 5 additions & 14 deletions taipy/gui/data/numpy_data_accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
import numpy
import pandas as pd

from ..gui import Gui
from .data_format import _DataFormat
from .pandas_data_accessor import _PandasDataAccessor


Expand All @@ -26,17 +24,10 @@ class _NumpyDataAccessor(_PandasDataAccessor):
def get_supported_classes() -> t.List[str]:
return [t.__name__ for t in _NumpyDataAccessor.__types] # type: ignore

def _get_dataframe(self, value: t.Any) -> pd.DataFrame:
def to_pandas(self, value: t.Any) -> pd.DataFrame:
return pd.DataFrame(value)

def get_col_types(self, var_name: str, value: t.Any) -> t.Union[None, t.Dict[str, str]]: # type: ignore
if isinstance(value, _NumpyDataAccessor.__types): # type: ignore
return super().get_col_types(var_name, self._get_dataframe(value))
return None

def get_data( # noqa: C901
self, guiApp: Gui, var_name: str, value: t.Any, payload: t.Dict[str, t.Any], data_format: _DataFormat
) -> t.Dict[str, t.Any]:
if isinstance(value, _NumpyDataAccessor.__types): # type: ignore
return super().get_data(guiApp, var_name, self._get_dataframe(value), payload, data_format)
return {}
def _from_pandas(self, value: pd.DataFrame, type: t.Type):
if type is numpy.ndarray:
return value.to_numpy()
return super()._from_pandas(value, type)
Loading

0 comments on commit 6c8c854

Please sign in to comment.