From bd4e88273befb13e0e0a783d10069916007f732b Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 14 Nov 2023 14:47:02 -0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(store.py):=20change=20filter?= =?UTF-8?q?=5Fby=5Fuser=20parameter=20name=20to=20liked=20to=20improve=20s?= =?UTF-8?q?emantics=20and=20clarity=20=E2=9C=A8=20feat(store.py):=20add=20?= =?UTF-8?q?support=20for=20filtering=20components=20by=20liked=20status=20?= =?UTF-8?q?to=20get=5Fcomponents=20function=20=F0=9F=90=9B=20fix(store.py)?= =?UTF-8?q?:=20remove=20in=5Fuser=5Fcollection=20attribute=20from=20ListCo?= =?UTF-8?q?mponentResponse=20schema=20as=20it=20is=20not=20used=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(service.py):=20change=20=5Fget=20method=20si?= =?UTF-8?q?gnature=20to=20accept=20Optional=20parameters=20and=20add=20typ?= =?UTF-8?q?e=20hints=20=E2=9C=A8=20feat(service.py):=20add=20build=5Ftags?= =?UTF-8?q?=5Ffilter=20method=20to=20build=20the=20tags=20filter=20for=20g?= =?UTF-8?q?et=5Fcomponents=20function=20=F0=9F=90=9B=20fix(service.py):=20?= =?UTF-8?q?remove=20filter=5Fby=5Fuser=20parameter=20from=20count=5Fcompon?= =?UTF-8?q?ents=20function=20and=20adjust=20logic=20accordingly=20?= =?UTF-8?q?=E2=9C=A8=20feat(service.py):=20add=20liked=20parameter=20to=20?= =?UTF-8?q?get=5Fcomponents=20function=20to=20filter=20components=20by=20l?= =?UTF-8?q?iked=20status=20=F0=9F=90=9B=20fix(service.py):=20change=20get?= =?UTF-8?q?=5Fcomponents=5Fin=5Fusers=5Fcollection=20method=20parameter=20?= =?UTF-8?q?type=20from=20List[UUID]=20to=20List[str]=20=F0=9F=90=9B=20fix(?= =?UTF-8?q?service.py):=20change=20download=20method=20parameter=20type=20?= =?UTF-8?q?from=20str=20to=20UUID=20=F0=9F=90=9B=20fix(utils.py):=20change?= =?UTF-8?q?=20update=5Fcomponents=5Fwith=5Fuser=5Fdata=20function=20parame?= =?UTF-8?q?ter=20type=20from=20List["ListComponentResponse"]=20to=20List[L?= =?UTF-8?q?istComponentResponse]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/store.py | 6 +-- src/backend/langflow/services/store/schema.py | 1 - .../langflow/services/store/service.py | 38 +++++++++---------- src/backend/langflow/services/store/utils.py | 21 +++++----- 4 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/backend/langflow/api/v1/store.py b/src/backend/langflow/api/v1/store.py index abdb1eaf1..ae1c953ca 100644 --- a/src/backend/langflow/api/v1/store.py +++ b/src/backend/langflow/api/v1/store.py @@ -4,7 +4,6 @@ from uuid import UUID from fastapi import APIRouter, Depends, HTTPException, Query from httpx import HTTPStatusError - from langflow.services.auth import utils as auth_utils from langflow.services.database.models.user.user import User from langflow.services.deps import get_settings_service, get_store_service @@ -80,7 +79,7 @@ def get_components( is_component: Annotated[Optional[bool], Query()] = None, tags: Annotated[Optional[list[str]], Query()] = None, sort: Annotated[Union[list[str], None], Query()] = None, - filter_by_user: Annotated[bool, Query()] = False, + liked: Annotated[bool, Query()] = False, page: int = 1, limit: int = 10, store_service: StoreService = Depends(get_store_service), @@ -96,7 +95,7 @@ def get_components( api_key=store_api_Key, page=page, limit=limit, - filter_by_user=filter_by_user, + liked=liked, is_component=is_component, search=search, status=status, @@ -111,7 +110,6 @@ def get_components( if len(result) >= limit: comp_count = store_service.count_components( api_key=store_api_Key, - filter_by_user=filter_by_user, filter_conditions=filter_conditions, ) else: diff --git a/src/backend/langflow/services/store/schema.py b/src/backend/langflow/services/store/schema.py index 9788a28ce..518355f96 100644 --- a/src/backend/langflow/services/store/schema.py +++ b/src/backend/langflow/services/store/schema.py @@ -45,7 +45,6 @@ class ListComponentResponse(BaseModel): description: Optional[str] liked_by_count: Optional[int] liked_by_user: Optional[bool] - in_user_collection: Optional[bool] is_component: Optional[bool] metadata: Optional[dict] user_created: Optional[dict] diff --git a/src/backend/langflow/services/store/service.py b/src/backend/langflow/services/store/service.py index 02075a804..88b47979a 100644 --- a/src/backend/langflow/services/store/service.py +++ b/src/backend/langflow/services/store/service.py @@ -5,7 +5,6 @@ from uuid import UUID import httpx from httpx import HTTPError, HTTPStatusError - from langflow.services.base import Service from langflow.services.store.schema import ( ComponentResponse, @@ -73,7 +72,9 @@ class StoreService(Service): # will make a property return that data # Without making the request multiple times - def _get(self, url: str, api_key: str, params: Dict[str, Any] = None) -> List[Dict[str, Any]]: + def _get( + self, url: str, api_key: Optional[str] = None, params: Optional[Dict[str, Any]] = None + ) -> List[Dict[str, Any]]: """Utility method to perform GET requests.""" if api_key: headers = {"Authorization": f"Bearer {api_key}"} @@ -127,7 +128,7 @@ class StoreService(Service): "limit": limit, } - filter_conditions = [] + filter_conditions: List[Dict[str, Any]] = [] if status: filter_conditions.append({"status": {"_eq": status}}) @@ -136,9 +137,7 @@ class StoreService(Service): filter_conditions.append({"is_component": {"_eq": is_component}}) if tags: - tags_filter = {"tags": {"_and": []}} - for tag in tags: - tags_filter["tags"]["_and"].append({"_some": {"tags_id": {"name": {"_eq": tag}}}}) + tags_filter = self.build_tags_filter(tags) filter_conditions.append(tags_filter) if date_from: @@ -167,19 +166,18 @@ class StoreService(Service): results = self._get(self.components_url, api_key, params) return [ComponentResponse(**component) for component in results] + def build_tags_filter(self, tags: List[str]): + tags_filter = {"tags": {"_and": []}} + for tag in tags: + tags_filter["tags"]["_and"].append({"_some": {"tags_id": {"name": {"_eq": tag}}}}) + return tags_filter + def count_components( self, + filter_conditions: List[Dict[str, Any]], api_key: Optional[str] = None, - filter_by_user: bool = False, - filter_conditions: Optional[List[Dict[str, Any]]] = None, ) -> int: params = {"aggregate": json.dumps({"count": "*"})} - filter_conditions = [] if filter_conditions is None else filter_conditions - if filter_by_user: - params["deep"] = json.dumps({"components": {"_filter": {"user_created": {"token": {"_eq": api_key}}}}}) - else: - filter_conditions.append({"status": {"_in": ["public", "Public"]}}) - if filter_conditions: params["filter"] = json.dumps({"_and": filter_conditions}) @@ -207,7 +205,7 @@ class StoreService(Service): limit: int = 15, fields: Optional[List[str]] = None, is_component: Optional[bool] = None, - filter_by_user: bool = False, + liked: bool = False, ) -> Tuple[List[ListComponentResponse], List[Dict[str, Any]]]: params = {"page": page, "limit": limit} # ?aggregate[count]=likes @@ -239,15 +237,15 @@ class StoreService(Service): # Only public components or the ones created by the user # check for "public" or "Public" - if filter_by_user and not api_key: + if liked and not api_key: raise ValueError("No API key provided") - if filter_by_user and api_key: + if liked and api_key: user_data = user_data_var.get() # params["filter"] = json.dumps({"user_created": {"_eq": user_data["id"]}}) if not user_data: raise ValueError("No user data") - filter_conditions.append({"user_created": {"_eq": user_data["id"]}}) + filter_conditions.append({"liked_by": {"_eq": user_data["id"]}}) else: filter_conditions.append({"status": {"_in": ["public", "Public"]}}) @@ -284,7 +282,7 @@ class StoreService(Service): return [result["id"] for result in results] # Which of the components is parent of the user's components - def get_components_in_users_collection(self, component_ids: List[UUID], api_key: str): + def get_components_in_users_collection(self, component_ids: List[str], api_key: str): user_data = user_data_var.get() if not user_data: raise ValueError("No user data") @@ -302,7 +300,7 @@ class StoreService(Service): results = self._get(self.components_url, api_key, params) return [result["id"] for result in results] - def download(self, api_key: str, component_id: str) -> DownloadComponentResponse: + def download(self, api_key: str, component_id: UUID) -> DownloadComponentResponse: url = f"{self.components_url}/{component_id}" params = {"fields": ",".join(["id", "name", "description", "data", "is_component"])} diff --git a/src/backend/langflow/services/store/utils.py b/src/backend/langflow/services/store/utils.py index 85262a4ed..ec0fbc8a6 100644 --- a/src/backend/langflow/services/store/utils.py +++ b/src/backend/langflow/services/store/utils.py @@ -16,20 +16,23 @@ def update_components_with_user_data( components: List["ListComponentResponse"], store_service: "StoreService", store_api_Key: str, + liked: bool, ): """ Updates the components with the user data (liked_by_user and in_users_collection) """ - liked_by_user_ids = store_service.get_liked_by_user_components( - component_ids=[str(component.id) for component in components], - api_key=store_api_Key, - ) - in_users_collection_ids = store_service.get_components_in_users_collection( - component_ids=[str(component.id) for component in components], - api_key=store_api_Key, - ) + component_ids = [str(component.id) for component in components] + if liked: + # If liked is True, this means all we got were liked_by_user components + # So we can set liked_by_user to True for all components + liked_by_user_ids = component_ids + else: + liked_by_user_ids = store_service.get_liked_by_user_components( + component_ids=component_ids, + api_key=store_api_Key, + ) # Now we need to set the liked_by_user attribute for component in components: component.liked_by_user = str(component.id) in liked_by_user_ids - component.in_user_collection = str(component.id) in in_users_collection_ids + return components