🐛 fix(store.py): change filter_by_user parameter name to liked to improve semantics and clarity

 feat(store.py): add support for filtering components by liked status to get_components function
🐛 fix(store.py): remove in_user_collection attribute from ListComponentResponse schema as it is not used
🐛 fix(service.py): change _get method signature to accept Optional parameters and add type hints
 feat(service.py): add build_tags_filter method to build the tags filter for get_components function
🐛 fix(service.py): remove filter_by_user parameter from count_components function and adjust logic accordingly
 feat(service.py): add liked parameter to get_components function to filter components by liked status
🐛 fix(service.py): change get_components_in_users_collection method parameter type from List[UUID] to List[str]
🐛 fix(service.py): change download method parameter type from str to UUID
🐛 fix(utils.py): change update_components_with_user_data function parameter type from List["ListComponentResponse"] to List[ListComponentResponse]
This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-11-14 14:47:02 -03:00
commit bd4e88273b
4 changed files with 32 additions and 34 deletions

View file

@ -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:

View file

@ -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]

View file

@ -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"])}

View file

@ -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