From 1bf6781dc42e20748887a0516963f13912919abd Mon Sep 17 00:00:00 2001 From: Jordan Frazier <122494242+jordanrfrazier@users.noreply.github.com> Date: Fri, 27 Sep 2024 05:06:15 -0700 Subject: [PATCH] fix: use init_subclass instead of metaclass to enforce decorator (#3942) * Use init_subclass instead of metaclass to enforce decorator * [autofix.ci] apply automated fixes * fix imports --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- .../base/langflow/base/vectorstores/model.py | 41 ++++++++---------- .../components/retrievers/CohereRerank.py | 3 +- .../components/retrievers/NvidiaRerank.py | 3 +- src/frontend/.dspy_cache/cache.db | Bin 0 -> 32768 bytes 4 files changed, 23 insertions(+), 24 deletions(-) create mode 100644 src/frontend/.dspy_cache/cache.db diff --git a/src/backend/base/langflow/base/vectorstores/model.py b/src/backend/base/langflow/base/vectorstores/model.py index ced43f88e..3603e553a 100644 --- a/src/backend/base/langflow/base/vectorstores/model.py +++ b/src/backend/base/langflow/base/vectorstores/model.py @@ -1,4 +1,4 @@ -from abc import ABC, ABCMeta, abstractmethod +from abc import abstractmethod from functools import wraps from typing import cast @@ -15,6 +15,11 @@ from langflow.schema import Data def check_cached_vector_store(f): """ Decorator to check for cached vector stores, and returns them if they exist. + + Note: caching only occurs during the execution of a component - they do not persist + across separate invocations of the component. This method exists so that components with + multiple output methods share the same vector store during the same invocation of the + component. """ @wraps(f) @@ -30,30 +35,22 @@ def check_cached_vector_store(f): return check_cached -class EnforceCacheDecoratorMeta(ABCMeta): - """ - Enforces that abstract methods marked with @check_cached_vector_store are implemented with the decorator. - """ - - def __init__(cls, name, bases, dct): - for name, value in dct.items(): - if hasattr(value, "__isabstractmethod__"): - cls._check_method_decorator(name, cls) - super().__init__(name, bases, dct) - - @staticmethod - def _check_method_decorator(name, cls): - method = getattr(cls, name) - - # Check if the method has been marked as decorated by `check_cached_vector_store` - if not getattr(method, "_is_cached_vector_store_checked", False): - raise TypeError(f"Concrete implementation of '{name}' must use '@check_cached_vector_store' decorator.") - - -class LCVectorStoreComponent(Component, ABC, metaclass=EnforceCacheDecoratorMeta): +class LCVectorStoreComponent(Component): # Used to ensure a single vector store is built for each run of the flow _cached_vector_store: VectorStore | None = None + def __init_subclass__(cls, **kwargs): + """ + Enforces the check cached decorator on all subclasses + """ + super().__init_subclass__(**kwargs) + if hasattr(cls, "build_vector_store"): + method = cls.build_vector_store + if not hasattr(method, "_is_cached_vector_store_checked"): + raise TypeError( + f"The method 'build_vector_store' in class {cls.__name__} must be decorated with @check_cached_vector_store" + ) + trace_type = "retriever" outputs = [ Output( diff --git a/src/backend/base/langflow/components/retrievers/CohereRerank.py b/src/backend/base/langflow/components/retrievers/CohereRerank.py index 5a50ac445..059229130 100644 --- a/src/backend/base/langflow/components/retrievers/CohereRerank.py +++ b/src/backend/base/langflow/components/retrievers/CohereRerank.py @@ -3,7 +3,7 @@ from typing import cast from langchain.retrievers import ContextualCompressionRetriever from langchain_cohere import CohereRerank -from langflow.base.vectorstores.model import LCVectorStoreComponent +from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store from langflow.field_typing import Retriever, VectorStore from langflow.io import ( DropdownInput, @@ -80,5 +80,6 @@ class CohereRerankComponent(LCVectorStoreComponent): self.status = data return data + @check_cached_vector_store def build_vector_store(self) -> VectorStore: raise NotImplementedError("Cohere Rerank does not support vector stores.") diff --git a/src/backend/base/langflow/components/retrievers/NvidiaRerank.py b/src/backend/base/langflow/components/retrievers/NvidiaRerank.py index c8befbc9a..04cd964d6 100644 --- a/src/backend/base/langflow/components/retrievers/NvidiaRerank.py +++ b/src/backend/base/langflow/components/retrievers/NvidiaRerank.py @@ -2,7 +2,7 @@ from typing import Any, cast from langchain.retrievers import ContextualCompressionRetriever -from langflow.base.vectorstores.model import LCVectorStoreComponent +from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store from langflow.field_typing import Retriever, VectorStore from langflow.io import DropdownInput, HandleInput, MultilineInput, SecretStrInput, StrInput from langflow.schema import Data @@ -77,5 +77,6 @@ class NvidiaRerankComponent(LCVectorStoreComponent): self.status = data return data + @check_cached_vector_store def build_vector_store(self) -> VectorStore: raise NotImplementedError("NVIDIA Rerank does not support vector stores.") diff --git a/src/frontend/.dspy_cache/cache.db b/src/frontend/.dspy_cache/cache.db new file mode 100644 index 0000000000000000000000000000000000000000..76b1b24257202fd8d4b18e0c85ad0ba03b269034 GIT binary patch literal 32768 zcmeI)&rjQC7zc2h7m@&tUn)ios#0EPDM64j1XU|llN!L#Xlc@hAlk!Zd5#MnPE2D5 z%A`qcciLaD^G-YMJc(m3J8j2Zs%eLvR_(IGrk$p}{zXg&EK)bAL*Gat&g<8Y-}m#r ze$o5duy(&_x(0h>H|v_q=7j;Ft4p}em>>v*zf=4jz54h@clgCi7o#1gd=lYW;~-7{ z5c+!$1p1hMBW+59>4S9b+*kd-_uuMk@npOp009U<00Izz00cS`cy_ZtdGWfOdOqtm z&CN}txn{Vo+1PYc$Nbn(YldaG#*(IQ8A}x4cm z8~c3cxR)}1iz%h$XG?uS(UoJ1-rA{YofJLD7ZyD%*P9i6nw6A|py(ac;%4t@4PZ7L zqv`&00|fcPS`^BR^Q;XdJc~I>C!u;f7R}%?2CyS2Rs2NZE4xu`(-859!tOr+UD!fDsrDf$oaP7si zw7WyLecaSWPePuR#l2WmSS5d-ZN`F zbXD;Ntb3Kh-F)RCdtZ4t;}0f_#qy#bH_9@@+AxfdcEuSMt5KMu>AK-KKKjuVzfVM= z_!zj7UoTeKyEDwyHd$~ke>98A6U$MzYsPU$J~Az%q16pmRUTAl!hz8XHB}W8awa2w z;yXm6X!J>rXhf+j>(|-~#Y$!VUN06|z#oR5n(a!+OBqq{+st`v@j1P!wOrf(u10~> zxoFFq$NO`8e-eMaJ-w)E(P0^?l3G95>fAbfe)~`#Jxih}yYJWHiMeWl;Tx z0n!;VmU3LpH67Q~ojy9s=l?GSnxx;+6`G^JNWV$1q(A8o^lSPB{fxTw1L-9_f9AUp zDhL4xKmY;|fB*y_009U<00RG40f|qc+Y{YP9~lvYWrBee84|r^0_tsevudfA$fCbY zkWQ0P@o=(yiPv3f*MIngC4}q+G8e2Z99cn_^pgL+d~o$0l8cfLmk%anG9M+zmkzEB zk=ZD{y>4(h7CE+RFz!{ky=pM#3mh&Qut72{zP4a6>fQh6fAo(R1Rwwb2tWV=5P$## zAOHafKmY<~Sit+IewhEC;RZ(4AOHafKmY;|fB*y_009U<00LY9^M7;$2tWV=5P$## qAOHafKmY;|fWX-o!2JL0w=rr60SG_<0uX=z1Rwwb2tWV=5cmtrINyr^ literal 0 HcmV?d00001