diff --git a/.gitignore b/.gitignore index 9d71e19b2..3b6cfebbf 100644 --- a/.gitignore +++ b/.gitignore @@ -251,3 +251,5 @@ langflow.db # docusaurus .docusaurus/ + +/tmp/* diff --git a/src/backend/langflow/api/v1/endpoints.py b/src/backend/langflow/api/v1/endpoints.py index 14a29bd44..26877e485 100644 --- a/src/backend/langflow/api/v1/endpoints.py +++ b/src/backend/langflow/api/v1/endpoints.py @@ -1,5 +1,6 @@ from http import HTTPStatus from typing import Optional + from langflow.cache.utils import save_uploaded_file from langflow.database.models.flow import Flow from langflow.processing.process import process_graph_cached, process_tweaks @@ -16,10 +17,11 @@ from langflow.api.v1.schemas import ( ) from langflow.interface.types import ( + build_langchain_types_dict, build_langchain_template_custom_component, + build_langchain_custom_component_list_from_path, ) -from langflow.interface.types import build_langchain_types_dict from langflow.database.base import get_session from sqlmodel import Session @@ -32,7 +34,26 @@ def get_all(): return build_langchain_types_dict() +@router.get("/load_custom_component_from_path") +def get_load_custom_component_from_path(path: str): + return build_langchain_custom_component_list_from_path(path) + + +@router.get("/load_custom_component_from_path_TEST") +def get_load_custom_component_from_path_test(path: str): + from langflow.interface.custom.load_custom_component_from_path import ( + DirectoryReader, + ) + + reader = DirectoryReader(path, False) + file_list = reader.get_files() + + return reader.build_component_menu_list(file_list) + + # For backwards compatibility we will keep the old endpoint + + @router.post("/predict/{flow_id}", response_model=ProcessResponse) @router.post("/process/{flow_id}", response_model=ProcessResponse) async def process_flow( diff --git a/src/backend/langflow/interface/custom/load_custom_component_from_file.py b/src/backend/langflow/interface/custom/load_custom_component_from_path.py similarity index 96% rename from src/backend/langflow/interface/custom/load_custom_component_from_file.py rename to src/backend/langflow/interface/custom/load_custom_component_from_path.py index 6dfdaa3c3..8c072c7a1 100644 --- a/src/backend/langflow/interface/custom/load_custom_component_from_file.py +++ b/src/backend/langflow/interface/custom/load_custom_component_from_path.py @@ -30,13 +30,13 @@ class StringCompressor: class DirectoryReader: - def __init__(self, directory_path, compress_code=False): + def __init__(self, directory_path, compress_code_field=False): """ Initialize DirectoryReader with a directory path and a flag indicating whether to compress the code. """ self.directory_path = directory_path - self.compress_code = compress_code + self.compress_code_field = compress_code_field def is_empty_file(self, file_content): """ @@ -115,7 +115,7 @@ class DirectoryReader: elif not self.validate_build(file_content): return False, "Missing build function" else: - if self.compress_code: + if self.compress_code_field: file_content = str(self.compress_string(file_content)) return True, file_content diff --git a/src/backend/langflow/interface/types.py b/src/backend/langflow/interface/types.py index 494c931e5..b33e2a397 100644 --- a/src/backend/langflow/interface/types.py +++ b/src/backend/langflow/interface/types.py @@ -20,6 +20,8 @@ from langflow.template.field.base import TemplateField from langflow.template.frontend_node.tools import CustomComponentNode from langflow.interface.retrievers.base import retriever_creator +from langflow.interface.custom.load_custom_component_from_path import DirectoryReader + import re import warnings import traceback @@ -233,3 +235,19 @@ def build_langchain_template_custom_component(custom_component: CustomComponent) frontend_node.get("base_classes").append(base_class) return frontend_node + + +def build_langchain_custom_component_list_from_path(path: str): + # Load all files from Path + reader = DirectoryReader(path, False) + file_list = reader.get_files() + + # Build and validate all files + data = reader.build_component_menu_list(file_list) + + raw_code = data.get("menu")[0].get("components")[0].get("code") + + extractor = CustomComponent(code=raw_code) + extractor.is_check_valid() + + return build_langchain_template_custom_component(extractor)