🐛 fix(store.py): fix build_filter_conditions method to correctly build filter conditions for querying components

✨ feat(store.py): add build_liked_filter method to build filter conditions for querying liked components
✨ feat(store.py): add build_tags_filter method to build filter conditions for querying components with specific tags
✨ feat(store.py): add build_filter_conditions method to build filter conditions for querying components with various filters
✨ feat(store.py): modify query_components method to accept filter_conditions parameter for querying components with filters
🔧 chore(utils.py): reorder imports in get_factories_and_deps function
🔧 chore(utils.py): reorder imports in initialize_session_service function
This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-11-14 15:22:12 -03:00
commit a7c86f1d1e
3 changed files with 56 additions and 48 deletions

View file

@ -3,6 +3,7 @@ from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Query from fastapi import APIRouter, Depends, HTTPException, Query
from httpx import HTTPStatusError from httpx import HTTPStatusError
from langflow.services.auth import utils as auth_utils from langflow.services.auth import utils as auth_utils
from langflow.services.database.models.user.user import User from langflow.services.database.models.user.user import User
from langflow.services.deps import get_settings_service, get_store_service from langflow.services.deps import get_settings_service, get_store_service
@ -86,20 +87,19 @@ def get_components(
): ):
try: try:
with user_data_context(api_key=store_api_Key, store_service=store_service): 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] = [] result: List[ListComponentResponse] = []
authorized = False authorized = False
try: try:
result, filter_conditions = store_service.query_components( result = store_service.query_components(
api_key=store_api_Key, api_key=store_api_Key, page=page, limit=limit, sort=sort, filter_conditions=filter_conditions
page=page,
limit=limit,
liked=liked,
is_component=is_component,
search=search,
status=status,
tags=tags,
sort=sort,
) )
except HTTPStatusError as exc: except HTTPStatusError as exc:
if exc.response.status_code == 403: if exc.response.status_code == 403:

View file

@ -4,8 +4,6 @@ from uuid import UUID
import httpx import httpx
from httpx import HTTPError, HTTPStatusError from httpx import HTTPError, HTTPStatusError
from loguru import logger
from langflow.services.base import Service from langflow.services.base import Service
from langflow.services.store.schema import ( from langflow.services.store.schema import (
ComponentResponse, ComponentResponse,
@ -14,6 +12,7 @@ from langflow.services.store.schema import (
StoreComponentCreate, StoreComponentCreate,
) )
from langflow.services.store.utils import process_tags_for_post from langflow.services.store.utils import process_tags_for_post
from loguru import logger
if TYPE_CHECKING: if TYPE_CHECKING:
from langflow.services.settings.service import SettingsService from langflow.services.settings.service import SettingsService
@ -131,26 +130,15 @@ class StoreService(Service):
conditions["_or"].append({"tags": {"tags_id": {"name": {"_icontains": query}}}}) conditions["_or"].append({"tags": {"tags_id": {"name": {"_icontains": query}}}})
return conditions return conditions
def query_components( def build_filter_conditions(
self, self,
api_key: Optional[str] = None,
search: Optional[str] = None, search: Optional[str] = None,
status: Optional[str] = None, status: Optional[str] = None,
tags: Optional[List[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, is_component: Optional[bool] = None,
liked: bool = False, liked: bool = False,
) -> Tuple[List[ListComponentResponse], List[Dict[str, Any]]]: api_key: Optional[str] = None,
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)
filter_conditions = [] filter_conditions = []
if search is not None: if search is not None:
@ -161,19 +149,18 @@ class StoreService(Service):
filter_conditions.append({"status": {"_eq": status}}) filter_conditions.append({"status": {"_eq": status}})
if tags: if tags:
tags_filter = {"tags": {"_and": []}} tags_filter = self.build_tags_filter(tags)
for tag in tags:
tags_filter["tags"]["_and"].append({"_some": {"tags_id": {"name": {"_eq": tag}}}})
filter_conditions.append(tags_filter) filter_conditions.append(tags_filter)
if is_component is not None: if is_component is not None:
filter_conditions.append({"is_component": {"_eq": is_component}}) filter_conditions.append({"is_component": {"_eq": is_component}})
if is_component is not None: liked_filter = self.build_liked_filter(liked, api_key)
filter_conditions.append({"is_component": {"_eq": is_component}}) filter_conditions.append(liked_filter)
# Only public components or the ones created by the user return filter_conditions
# check for "public" or "Public"
def build_liked_filter(self, liked: bool, api_key: Optional[str] = None):
if liked and not api_key: if liked and not api_key:
raise ValueError("No API key provided") raise ValueError("No API key provided")
@ -182,9 +169,32 @@ class StoreService(Service):
# params["filter"] = json.dumps({"user_created": {"_eq": user_data["id"]}}) # params["filter"] = json.dumps({"user_created": {"_eq": user_data["id"]}})
if not user_data: if not user_data:
raise ValueError("No user data") raise ValueError("No user data")
filter_conditions.append({"liked_by": {"_eq": user_data["id"]}}) return {"liked_by": {"_eq": user_data["id"]}}
else: 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: if filter_conditions:
params["filter"] = json.dumps({"_and": filter_conditions}) params["filter"] = json.dumps({"_and": filter_conditions})
@ -195,7 +205,7 @@ class StoreService(Service):
# for component in results_objects: # for component in results_objects:
# if component.tags: # if component.tags:
# component.tags = [tags_id.tags_id for tags_id in 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]: def get_liked_by_user_components(self, component_ids: List[UUID], api_key: str) -> List[UUID]:
# Get fields id # Get fields id

View file

@ -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.database.utils import initialize_database
from langflow.services.manager import service_manager from langflow.services.manager import service_manager
from langflow.services.schema import ServiceType from langflow.services.schema import ServiceType
from langflow.services.settings.constants import ( from langflow.services.settings.constants import DEFAULT_SUPERUSER, DEFAULT_SUPERUSER_PASSWORD
DEFAULT_SUPERUSER,
DEFAULT_SUPERUSER_PASSWORD,
)
from sqlmodel import Session
from .deps import get_db_service, get_session, get_settings_service
from loguru import logger from loguru import logger
from sqlmodel import Session
from .deps import get_db_service, get_session, get_settings_service
def get_factories_and_deps(): 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.cache import factory as cache_factory
from langflow.services.chat import factory as chat_factory from langflow.services.chat import factory as chat_factory
from langflow.services.settings import factory as settings_factory from langflow.services.database import factory as database_factory
from langflow.services.auth import factory as auth_factory
from langflow.services.task import factory as task_factory
from langflow.services.session import factory as session_service_factory # type: ignore 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.store import factory as store_factory
from langflow.services.task import factory as task_factory
return [ return [
(settings_factory.SettingsServiceFactory(), []), (settings_factory.SettingsServiceFactory(), []),
@ -170,8 +168,8 @@ def initialize_session_service():
""" """
Initialize the session manager. 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.cache import factory as cache_factory
from langflow.services.session import factory as session_service_factory # type: ignore
initialize_settings_service() initialize_settings_service()