Fix bug in login functionality

This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-11-21 14:13:51 -03:00
commit 777686dd65

View file

@ -1,43 +1,39 @@
import ast
import contextlib
from typing import Any, List, Union, Optional
import re
import traceback
import warnings
from typing import Any, Dict, List, Optional, Union
from uuid import UUID
from fastapi import HTTPException
from langflow.api.utils import get_new_key
from langflow.field_typing.constants import CUSTOM_COMPONENT_SUPPORTED_TYPES
from langflow.interface.agents.base import agent_creator
from langflow.interface.chains.base import chain_creator
from langflow.field_typing.constants import CUSTOM_COMPONENT_SUPPORTED_TYPES
from langflow.interface.custom.base import custom_component_creator
from langflow.interface.custom.custom_component import CustomComponent
from langflow.interface.custom.directory_reader import DirectoryReader
from langflow.interface.custom.utils import extract_inner_type
from langflow.interface.document_loaders.base import documentloader_creator
from langflow.interface.embeddings.base import embedding_creator
from langflow.interface.importing.utils import get_function_custom
from langflow.interface.llms.base import llm_creator
from langflow.interface.memories.base import memory_creator
from langflow.interface.output_parsers.base import output_parser_creator
from langflow.interface.prompts.base import prompt_creator
from langflow.interface.retrievers.base import retriever_creator
from langflow.interface.text_splitters.base import textsplitter_creator
from langflow.interface.toolkits.base import toolkits_creator
from langflow.interface.tools.base import tool_creator
from langflow.interface.utilities.base import utility_creator
from langflow.interface.vector_store.base import vectorstore_creator
from langflow.interface.wrappers.base import wrapper_creator
from langflow.interface.output_parsers.base import output_parser_creator
from langflow.interface.custom.base import custom_component_creator
from langflow.interface.custom.custom_component import CustomComponent
from langflow.template.field.base import TemplateField
from langflow.template.frontend_node.constants import CLASSES_TO_REMOVE
from langflow.template.frontend_node.custom_components import (
CustomComponentFrontendNode,
)
from langflow.interface.retrievers.base import retriever_creator
from langflow.interface.custom.directory_reader import DirectoryReader
from loguru import logger
from langflow.template.frontend_node.custom_components import CustomComponentFrontendNode
from langflow.utils.util import get_base_classes
import re
import warnings
import traceback
from fastapi import HTTPException
from loguru import logger
# Used to get the base_classes list
@ -115,14 +111,10 @@ def add_new_custom_field(
# If options is a list, then it's a dropdown
# If options is None, then it's a list of strings
is_list = isinstance(field_config.get("options"), list)
field_config["is_list"] = (
is_list or field_config.get("is_list", False) or field_contains_list
)
field_config["is_list"] = is_list or field_config.get("is_list", False) or field_contains_list
if "name" in field_config:
warnings.warn(
"The 'name' key in field_config is used to build the object and can't be changed."
)
warnings.warn("The 'name' key in field_config is used to build the object and can't be changed.")
field_config.pop("name", None)
required = field_config.pop("required", field_required)
@ -186,9 +178,7 @@ def extract_type_from_optional(field_type):
def build_frontend_node(custom_component: CustomComponent):
"""Build a frontend node for a custom component"""
try:
return (
CustomComponentFrontendNode().to_dict().get(type(custom_component).__name__)
)
return CustomComponentFrontendNode().to_dict().get(type(custom_component).__name__)
except Exception as exc:
logger.error(f"Error while building base frontend node: {exc}")
@ -210,7 +200,7 @@ def update_attributes(frontend_node, template_config):
def build_field_config(
custom_component: CustomComponent, user_id: Optional[Union[str, UUID]] = None
custom_component: CustomComponent, user_id: Optional[Union[str, UUID]] = None, update_field=None
):
"""Build the field configuration for a custom component"""
@ -221,7 +211,37 @@ def build_field_config(
return {}
try:
return custom_class(user_id=user_id).build_config()
build_config: Dict = custom_class(user_id=user_id).build_config()
if update_field is not None:
try:
field_dict = build_config[update_field]
# If "options" in field_dict, and it is a callable
# then call it to get the options
if "options" in field_dict and callable(field_dict["options"]):
field_dict["options"] = field_dict["options"]()
elif "value" in field_dict and callable(field_dict["value"]):
field_dict["value"] = field_dict["value"]()
# Now we need to update the build_config
# with the new field_dict
build_config[update_field] = field_dict
except Exception as exc:
logger.error(f"Error while getting build_config: {str(exc)}")
else:
# Update all the fields
for field_name, field_dict in build_config.items():
# If "options" in field_dict, and it is a callable
# then call it to get the options
if "options" in field_dict and callable(field_dict["options"]):
field_dict["options"] = field_dict["options"]()
elif "value" in field_dict and callable(field_dict["value"]):
field_dict["value"] = field_dict["value"]()
# Now we need to update the build_config
# with the new field_dict
build_config[field_name] = field_dict
return build_config
except Exception as exc:
logger.error(f"Error while building field config: {str(exc)}")
return {}
@ -239,9 +259,7 @@ def add_extra_fields(frontend_node, field_config, function_args):
if "name" not in extra_field or extra_field["name"] == "self":
continue
field_name, field_type, field_value, field_required = get_field_properties(
extra_field
)
field_name, field_type, field_value, field_required = get_field_properties(extra_field)
config = field_config.get(field_name, {})
frontend_node = add_new_custom_field(
frontend_node,
@ -276,8 +294,7 @@ def add_base_classes(frontend_node, return_types: List[str]):
status_code=400,
detail={
"error": (
"Invalid return type should be one of: "
f"{list(CUSTOM_COMPONENT_SUPPORTED_TYPES.keys())}"
"Invalid return type should be one of: " f"{list(CUSTOM_COMPONENT_SUPPORTED_TYPES.keys())}"
),
"traceback": traceback.format_exc(),
},
@ -299,8 +316,7 @@ def add_output_types(frontend_node, return_types: List[str]):
status_code=400,
detail={
"error": (
"Invalid return type should be one of: "
f"{list(CUSTOM_COMPONENT_SUPPORTED_TYPES.keys())}"
"Invalid return type should be one of: " f"{list(CUSTOM_COMPONENT_SUPPORTED_TYPES.keys())}"
),
"traceback": traceback.format_exc(),
},
@ -310,7 +326,9 @@ def add_output_types(frontend_node, return_types: List[str]):
def build_langchain_template_custom_component(
custom_component: CustomComponent, user_id: Optional[Union[str, UUID]] = None
custom_component: CustomComponent,
user_id: Optional[Union[str, UUID]] = None,
update_field: Optional[str] = None,
):
"""Build a custom component template for the langchain"""
try:
@ -330,16 +348,10 @@ def build_langchain_template_custom_component(
add_extra_fields(frontend_node, field_config, entrypoint_args)
logger.debug("Added extra fields")
frontend_node = add_code_field(
frontend_node, custom_component.code, field_config.get("code", {})
)
frontend_node = add_code_field(frontend_node, custom_component.code, field_config.get("code", {}))
logger.debug("Added code field")
add_base_classes(
frontend_node, custom_component.get_function_entrypoint_return_type
)
add_output_types(
frontend_node, custom_component.get_function_entrypoint_return_type
)
add_base_classes(frontend_node, custom_component.get_function_entrypoint_return_type)
add_output_types(frontend_node, custom_component.get_function_entrypoint_return_type)
logger.debug("Added base classes")
return frontend_node
except Exception as exc:
@ -348,9 +360,7 @@ def build_langchain_template_custom_component(
raise HTTPException(
status_code=400,
detail={
"error": (
"Invalid type convertion. Please check your code and try again."
),
"error": ("Invalid type convertion. Please check your code and try again."),
"traceback": traceback.format_exc(),
},
) from exc
@ -382,9 +392,7 @@ def build_valid_menu(valid_components):
valid_menu[menu_name] = {}
for component in menu_item["components"]:
logger.debug(
f"Building component: {component.get('name'), component.get('output_types')}"
)
logger.debug(f"Building component: {component.get('name'), component.get('output_types')}")
try:
component_name = component["name"]
component_code = component["code"]
@ -393,9 +401,7 @@ def build_valid_menu(valid_components):
component_extractor = CustomComponent(code=component_code)
component_extractor.is_check_valid()
component_template = build_langchain_template_custom_component(
component_extractor
)
component_template = build_langchain_template_custom_component(component_extractor)
component_template["output_types"] = component_output_types
if len(component_output_types) == 1:
component_name = component_output_types[0]
@ -403,9 +409,7 @@ def build_valid_menu(valid_components):
file_name = component.get("file").split(".")[0]
if "_" in file_name:
# turn .py file into camelcase
component_name = "".join(
[word.capitalize() for word in file_name.split("_")]
)
component_name = "".join([word.capitalize() for word in file_name.split("_")])
else:
component_name = file_name
@ -414,9 +418,7 @@ def build_valid_menu(valid_components):
except Exception as exc:
logger.error(f"Error loading Component: {component['output_types']}")
logger.exception(
f"Error while building custom component {component_output_types}: {exc}"
)
logger.exception(f"Error while building custom component {component_output_types}: {exc}")
return valid_menu
@ -454,20 +456,14 @@ def build_invalid_menu(invalid_components):
logger.debug(f"Added {component_name} to invalid menu to {menu_name}")
except Exception as exc:
logger.exception(
f"Error while creating custom component [{component_name}]: {str(exc)}"
)
logger.exception(f"Error while creating custom component [{component_name}]: {str(exc)}")
return invalid_menu
def merge_nested_dicts_with_renaming(dict1, dict2):
for key, value in dict2.items():
if (
key in dict1
and isinstance(value, dict)
and isinstance(dict1.get(key), dict)
):
if key in dict1 and isinstance(value, dict) and isinstance(dict1.get(key), dict):
for sub_key, sub_value in value.items():
if sub_key in dict1[key]:
new_key = get_new_key(dict1[key], sub_key)
@ -484,9 +480,7 @@ def build_langchain_custom_component_list_from_path(path: str):
file_list = load_files_from_path(path)
reader = DirectoryReader(path, False)
valid_components, invalid_components = build_and_validate_all_files(
reader, file_list
)
valid_components, invalid_components = build_and_validate_all_files(reader, file_list)
valid_menu = build_valid_menu(valid_components)
invalid_menu = build_invalid_menu(invalid_components)
@ -500,18 +494,14 @@ def get_all_types_dict(settings_service):
# need to merge all the keys into one dict
custom_components_from_file: dict[str, Any] = {}
if settings_service.settings.COMPONENTS_PATH:
logger.info(
f"Building custom components from {settings_service.settings.COMPONENTS_PATH}"
)
logger.info(f"Building custom components from {settings_service.settings.COMPONENTS_PATH}")
custom_component_dicts = []
processed_paths = []
for path in settings_service.settings.COMPONENTS_PATH:
if str(path) in processed_paths:
continue
custom_component_dict = build_langchain_custom_component_list_from_path(
str(path)
)
custom_component_dict = build_langchain_custom_component_list_from_path(str(path))
custom_component_dicts.append(custom_component_dict)
processed_paths.append(str(path))
@ -521,16 +511,12 @@ def get_all_types_dict(settings_service):
if not custom_component_dict:
continue
category = list(custom_component_dict.keys())[0]
logger.info(
f"Loading {len(custom_component_dict[category])} component(s) from category {category}"
)
logger.info(f"Loading {len(custom_component_dict[category])} component(s) from category {category}")
custom_components_from_file = merge_nested_dicts_with_renaming(
custom_components_from_file, custom_component_dict
)
return merge_nested_dicts_with_renaming(
native_components, custom_components_from_file
)
return merge_nested_dicts_with_renaming(native_components, custom_components_from_file)
def merge_nested_dicts(dict1, dict2):