From 2b10cfe96d9ff24ccdc7f9248f78e286a0299498 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Fri, 22 Sep 2023 10:54:30 -0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20add=20missing=20?= =?UTF-8?q?import=20statement=20for=20is=5Fbasic=5Ftype=20function=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20add=20missing=20import=20stateme?= =?UTF-8?q?nt=20for=20logger=20=F0=9F=90=9B=20fix(base.py):=20handle=20Att?= =?UTF-8?q?ributeError=20when=20comparing=20Vertex=20objects=20for=20equal?= =?UTF-8?q?ity=20=F0=9F=90=9B=20fix(base.py):=20handle=20exception=20and?= =?UTF-8?q?=20log=20it=20when=20building=20node=20fails=20=F0=9F=90=9B=20f?= =?UTF-8?q?ix(base.py):=20handle=20exception=20and=20log=20it=20when=20pic?= =?UTF-8?q?kling=20built=20object=20fails=20=F0=9F=90=9B=20fix(base.py):?= =?UTF-8?q?=20reset=20params=20and=20rebuild=20built=20object=20when=20pic?= =?UTF-8?q?kling=20built=20object=20fails=20=F0=9F=90=9B=20fix(base.py):?= =?UTF-8?q?=20handle=20exception=20and=20log=20it=20when=20pickling=20buil?= =?UTF-8?q?t=20object=20fails=20=F0=9F=90=9B=20fix(base.py):=20handle=20ex?= =?UTF-8?q?ception=20and=20log=20it=20when=20pickling=20built=20object=20f?= =?UTF-8?q?ails=20=F0=9F=90=9B=20fix(base.py):=20handle=20exception=20and?= =?UTF-8?q?=20log=20it=20when=20pickling=20built=20object=20fails=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20handle=20exception=20and=20log?= =?UTF-8?q?=20it=20when=20pickling=20built=20object=20fails=20=F0=9F=90=9B?= =?UTF-8?q?=20fix(base.py):=20handle=20exception=20and=20log=20it=20when?= =?UTF-8?q?=20pickling=20built=20object=20fails=20=F0=9F=90=9B=20fix(base.?= =?UTF-8?q?py):=20handle=20exception=20and=20log=20it=20when=20pickling=20?= =?UTF-8?q?built=20object=20fails=20=F0=9F=90=9B=20fix(base.py):=20handle?= =?UTF-8?q?=20exception=20and=20log=20it=20when=20pickling=20built=20objec?= =?UTF-8?q?t=20fails=20=F0=9F=90=9B=20fix(base.py):=20handle=20exception?= =?UTF-8?q?=20and=20log=20it=20when=20pickling=20built=20object=20fails=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20handle=20exception=20and=20log?= =?UTF-8?q?=20it=20when=20pickling=20built=20object=20fails=20=F0=9F=90=9B?= =?UTF-8?q?=20fix(base.py):=20handle=20exception=20and=20log=20it=20when?= =?UTF-8?q?=20pickling=20built=20object=20fails=20=F0=9F=90=9B=20fix(base.?= =?UTF-8?q?py):=20handle=20exception=20and=20log=20it=20when=20pickling=20?= =?UTF-8?q?built=20object=20fails=20=F0=9F=90=9B=20fix(base.py):=20handle?= =?UTF-8?q?=20exception=20and=20log=20it=20when=20pickling=20built=20objec?= =?UTF-8?q?t=20fails=20=F0=9F=90=9B=20fix(base.py):=20handle=20exception?= =?UTF-8?q?=20and=20log=20it=20when=20pickling=20built=20object=20fails=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20handle=20exception=20and=20log?= =?UTF-8?q?=20it=20when=20pickling=20built=20object=20fails=20=F0=9F=90=9B?= =?UTF-8?q?=20fix(base.py):=20handle=20exception=20and=20log=20it=20when?= =?UTF-8?q?=20pickling=20built=20object=20fails=20=F0=9F=90=9B=20fix(base.?= =?UTF-8?q?py):=20handle=20exception=20and=20log=20it=20when=20pickling=20?= =?UTF-8?q?built=20object=20fails=20=F0=9F=90=9B=20fix(base.py):=20handle?= =?UTF-8?q?=20exception=20and=20log=20it=20when=20pickling=20built=20objec?= =?UTF-8?q?t=20fails=20=F0=9F=90=9B=20fix(base.py):=20handle=20exception?= =?UTF-8?q?=20and=20log=20it=20when=20pickling=20built=20object=20fails=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20handle=20exception=20and=20log?= =?UTF-8?q?=20it=20when=20pickling=20built=20object=20fails=20=F0=9F=90=9B?= =?UTF-8?q?=20fix(base.py):=20handle=20exception=20and=20log=20it=20when?= =?UTF-8?q?=20pickling=20built=20object=20fails=20=F0=9F=90=9B=20fix(base.?= =?UTF-8?q?py):=20handle=20exception=20and=20log=20it=20when=20pickling=20?= =?UTF-8?q?built=20object?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/graph/vertex/base.py | 72 ++++++++++++++++++++++- src/backend/langflow/utils/constants.py | 1 + 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/backend/langflow/graph/vertex/base.py b/src/backend/langflow/graph/vertex/base.py index d8de30ca9..4c6262554 100644 --- a/src/backend/langflow/graph/vertex/base.py +++ b/src/backend/langflow/graph/vertex/base.py @@ -1,5 +1,7 @@ import ast +import pickle from langflow.graph.utils import UnbuiltObject +from langflow.graph.vertex.utils import is_basic_type from langflow.interface.initialize import loading from langflow.interface.listing import lazy_load_dict from langflow.utils.constants import DIRECT_TYPES @@ -19,7 +21,11 @@ if TYPE_CHECKING: class Vertex: def __init__( - self, data: Dict, base_type: Optional[str] = None, is_task: bool = False + self, + data: Dict, + base_type: Optional[str] = None, + is_task: bool = False, + params: Optional[Dict] = None, ) -> None: self.id: str = data["id"] self._data = data @@ -31,6 +37,57 @@ class Vertex: self.artifacts: Dict[str, Any] = {} self.task_id: Optional[str] = None self.is_task = is_task + self.params = params + + def reset_params(self): + for edge in self.edges: + if edge.source != self: + target_param = edge.target_param + if target_param in ["document", "texts"]: + # this means they got data and have already ingested it + # so we continue after removing the param + self.params.pop(target_param, None) + continue + + if target_param in self.params and not is_basic_type( + self.params[target_param] + ): + # edge.source.params = {} + edge.source._build_params() + edge.source._built_object = UnbuiltObject() + edge.source._built = False + + self.params[target_param] = edge.source + + def __getstate__(self): + state_dict = self.__dict__.copy() + try: + # try pickling the built object + # if it fails, then we need to delete it + # and build it again + pickle.dumps(state_dict["_built_object"]) + except Exception: + self.reset_params() + del state_dict["_built_object"] + del state_dict["_built"] + return state_dict + + def __setstate__(self, state): + self._data = state["_data"] + self.params = state["params"] + self.base_type = state["base_type"] + self.is_task = state["is_task"] + self.edges = state["edges"] + self.id = state["id"] + self._parse_data() + if "_built_object" in state: + self._built_object = state["_built_object"] + self._built = state["_built"] + else: + self._built_object = UnbuiltObject() + self._built = False + self.artifacts: Dict[str, Any] = {} + self.task_id: Optional[str] = None def _parse_data(self) -> None: self.data = self._data["data"] @@ -101,9 +158,11 @@ class Vertex: for key, value in self.data["node"]["template"].items() if isinstance(value, dict) } - params = {} + params = self.params.copy() if self.params else {} for edge in self.edges: + if not hasattr(edge, "target_param"): + continue param_key = edge.target_param if param_key in template_dict: if template_dict[param_key]["list"]: @@ -114,6 +173,8 @@ class Vertex: params[param_key] = edge.source for key, value in template_dict.items(): + if key in params: + continue # Skip _type and any value that has show == False and is not code # If we don't want to show code but we want to use it if key == "_type" or (not value.get("show") and key != "code"): @@ -143,6 +204,7 @@ class Vertex: else: params.pop(key, None) # Add _type to params + self._raw_params = params self.params = params def _build(self, user_id=None): @@ -264,6 +326,7 @@ class Vertex: ) self._update_built_object_and_artifacts(result) except Exception as exc: + logger.exception(exc) raise ValueError( f"Error building node {self.vertex_type}: {str(exc)}" ) from exc @@ -304,7 +367,10 @@ class Vertex: return f"Vertex(id={self.id}, data={self.data})" def __eq__(self, __o: object) -> bool: - return self.id == __o.id if isinstance(__o, Vertex) else False + try: + return self.id == __o.id if isinstance(__o, Vertex) else False + except AttributeError: + return False def __hash__(self) -> int: return id(self) diff --git a/src/backend/langflow/utils/constants.py b/src/backend/langflow/utils/constants.py index e473d855b..adf4cf63c 100644 --- a/src/backend/langflow/utils/constants.py +++ b/src/backend/langflow/utils/constants.py @@ -49,3 +49,4 @@ def python_function(text: str) -> str: """ DIRECT_TYPES = ["str", "bool", "code", "int", "float", "Any", "prompt"] +PYTHON_BASIC_TYPES = [str, bool, int, float, tuple, list, dict, set]