diff --git a/src/backend/langflow/api/v1/store.py b/src/backend/langflow/api/v1/store.py index 88f7f978f..5133b11f6 100644 --- a/src/backend/langflow/api/v1/store.py +++ b/src/backend/langflow/api/v1/store.py @@ -3,6 +3,7 @@ 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 @@ -86,20 +87,19 @@ def get_components( ): try: with user_data_context(api_key=store_api_Key, store_service=store_service): - filter_conditions: List[Dict[str, Any]] = [] + filter_conditions: List[Dict[str, Any]] = store_service.build_filter_conditions( + search=search, + status=status, + tags=tags, + is_component=is_component, + liked=liked, + api_key=store_api_Key, + ) result: List[ListComponentResponse] = [] authorized = False try: - result, filter_conditions = store_service.query_components( - api_key=store_api_Key, - page=page, - limit=limit, - liked=liked, - is_component=is_component, - search=search, - status=status, - tags=tags, - sort=sort, + result = store_service.query_components( + api_key=store_api_Key, page=page, limit=limit, sort=sort, filter_conditions=filter_conditions ) except HTTPStatusError as exc: if exc.response.status_code == 403: diff --git a/src/backend/langflow/services/store/service.py b/src/backend/langflow/services/store/service.py index 2c5608311..003c5ac2c 100644 --- a/src/backend/langflow/services/store/service.py +++ b/src/backend/langflow/services/store/service.py @@ -4,8 +4,6 @@ from uuid import UUID import httpx from httpx import HTTPError, HTTPStatusError -from loguru import logger - from langflow.services.base import Service from langflow.services.store.schema import ( ComponentResponse, @@ -14,6 +12,7 @@ from langflow.services.store.schema import ( StoreComponentCreate, ) from langflow.services.store.utils import process_tags_for_post +from loguru import logger if TYPE_CHECKING: from langflow.services.settings.service import SettingsService @@ -131,26 +130,15 @@ class StoreService(Service): conditions["_or"].append({"tags": {"tags_id": {"name": {"_icontains": query}}}}) return conditions - def query_components( + def build_filter_conditions( self, - api_key: Optional[str] = None, search: Optional[str] = None, status: Optional[str] = None, tags: Optional[List[str]] = None, - sort: Optional[List[str]] = None, - page: int = 1, - limit: int = 15, - fields: Optional[List[str]] = None, is_component: Optional[bool] = None, liked: bool = False, - ) -> Tuple[List[ListComponentResponse], List[Dict[str, Any]]]: - params = {"page": page, "limit": limit} - # ?aggregate[count]=likes - params["fields"] = ",".join(fields) if fields else ",".join(self.default_fields) - - if sort: - params["sort"] = ",".join(sort) - + api_key: Optional[str] = None, + ): filter_conditions = [] if search is not None: @@ -161,19 +149,18 @@ class StoreService(Service): filter_conditions.append({"status": {"_eq": status}}) 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 is_component is not None: filter_conditions.append({"is_component": {"_eq": is_component}}) - if is_component is not None: - filter_conditions.append({"is_component": {"_eq": is_component}}) + liked_filter = self.build_liked_filter(liked, api_key) + filter_conditions.append(liked_filter) - # Only public components or the ones created by the user - # check for "public" or "Public" + return filter_conditions + + def build_liked_filter(self, liked: bool, api_key: Optional[str] = None): if liked and not api_key: raise ValueError("No API key provided") @@ -182,9 +169,32 @@ class StoreService(Service): # params["filter"] = json.dumps({"user_created": {"_eq": user_data["id"]}}) if not user_data: raise ValueError("No user data") - filter_conditions.append({"liked_by": {"_eq": user_data["id"]}}) + return {"liked_by": {"_eq": user_data["id"]}} else: - filter_conditions.append({"status": {"_in": ["public", "Public"]}}) + return {"status": {"_in": ["public", "Public"]}} + + def query_components( + self, + api_key: Optional[str] = None, + sort: Optional[List[str]] = None, + page: int = 1, + limit: int = 15, + fields: Optional[List[str]] = None, + is_component: Optional[bool] = None, + filter_conditions: Optional[List[Dict[str, Any]]] = None, + ) -> Tuple[List[ListComponentResponse], List[Dict[str, Any]]]: + params = {"page": page, "limit": limit} + # ?aggregate[count]=likes + params["fields"] = ",".join(fields) if fields else ",".join(self.default_fields) + + if sort: + params["sort"] = ",".join(sort) + + if is_component is not None: + filter_conditions.append({"is_component": {"_eq": is_component}}) + + # Only public components or the ones created by the user + # check for "public" or "Public" if filter_conditions: params["filter"] = json.dumps({"_and": filter_conditions}) @@ -195,7 +205,7 @@ class StoreService(Service): # for component in results_objects: # if component.tags: # component.tags = [tags_id.tags_id for tags_id in component.tags] - return results_objects, filter_conditions + return results_objects def get_liked_by_user_components(self, component_ids: List[UUID], api_key: str) -> List[UUID]: # Get fields id diff --git a/src/backend/langflow/services/utils.py b/src/backend/langflow/services/utils.py index f0fd91f1f..72807ee0c 100644 --- a/src/backend/langflow/services/utils.py +++ b/src/backend/langflow/services/utils.py @@ -2,24 +2,22 @@ from langflow.services.auth.utils import create_super_user, verify_password from langflow.services.database.utils import initialize_database from langflow.services.manager import service_manager from langflow.services.schema import ServiceType -from langflow.services.settings.constants import ( - DEFAULT_SUPERUSER, - DEFAULT_SUPERUSER_PASSWORD, -) -from sqlmodel import Session -from .deps import get_db_service, get_session, get_settings_service +from langflow.services.settings.constants import DEFAULT_SUPERUSER, DEFAULT_SUPERUSER_PASSWORD from loguru import logger +from sqlmodel import Session + +from .deps import get_db_service, get_session, get_settings_service def get_factories_and_deps(): - from langflow.services.database import factory as database_factory + from langflow.services.auth import factory as auth_factory from langflow.services.cache import factory as cache_factory from langflow.services.chat import factory as chat_factory - from langflow.services.settings import factory as settings_factory - from langflow.services.auth import factory as auth_factory - from langflow.services.task import factory as task_factory + from langflow.services.database import factory as database_factory from langflow.services.session import factory as session_service_factory # type: ignore + from langflow.services.settings import factory as settings_factory from langflow.services.store import factory as store_factory + from langflow.services.task import factory as task_factory return [ (settings_factory.SettingsServiceFactory(), []), @@ -170,8 +168,8 @@ def initialize_session_service(): """ Initialize the session manager. """ - from langflow.services.session import factory as session_service_factory # type: ignore from langflow.services.cache import factory as cache_factory + from langflow.services.session import factory as session_service_factory # type: ignore initialize_settings_service()