Add attribute validation functions and mapping

This commit is contained in:
Gabriel Luiz Freitas Almeida 2024-02-22 11:57:03 -03:00
commit cb4fe92e9b
3 changed files with 39 additions and 39 deletions

View file

@ -0,0 +1,31 @@
def validate_icon(value: str, *args, **kwargs):
# we are going to use the emoji library to validate the emoji
# emojis can be defined using the :emoji_name: syntax
if not value.startswith(":") or not value.endswith(":"):
warnings.warn("Invalid emoji. Please use the :emoji_name: syntax.")
return value
emoji_value = emoji.emojize(value, variant="emoji_type")
if value == emoji_value:
warnings.warn(f"Invalid emoji. {value} is not a valid emoji.")
return value
return emoji_value
def getattr_return_str(value):
return str(value) if value else ""
def getattr_return_bool(value):
if isinstance(value, bool):
return value
ATTR_FUNC_MAPPING = {
"display_name": getattr_return_str,
"description": getattr_return_str,
"beta": getattr_return_str,
"documentation": getattr_return_str,
"icon": validate_icon,
"pinned": getattr_return_bool,
}

View file

@ -2,9 +2,10 @@ import operator
import warnings import warnings
from typing import Any, ClassVar, Optional from typing import Any, ClassVar, Optional
import emoji
from cachetools import TTLCache, cachedmethod from cachetools import TTLCache, cachedmethod
from fastapi import HTTPException from fastapi import HTTPException
from langflow.interface.custom.attributes import ATTR_FUNC_MAPPING
from langflow.interface.custom.code_parser import CodeParser from langflow.interface.custom.code_parser import CodeParser
from langflow.interface.custom.eval import eval_custom_component_code from langflow.interface.custom.eval import eval_custom_component_code
from langflow.utils import validate from langflow.utils import validate
@ -65,14 +66,6 @@ class Component:
return validate.create_function(self.code, self._function_entrypoint_name) return validate.create_function(self.code, self._function_entrypoint_name)
def getattr_return_str(self, value):
return str(value) if value else ""
def getattr_return_bool(self, value):
if isinstance(value, bool):
return value
def build_template_config(self) -> dict: def build_template_config(self) -> dict:
if not self.code: if not self.code:
return {} return {}
@ -80,15 +73,8 @@ class Component:
cc_class = eval_custom_component_code(self.code) cc_class = eval_custom_component_code(self.code)
component_instance = cc_class() component_instance = cc_class()
template_config = {} template_config = {}
attributes_func_mapping = {
"display_name": self.getattr_return_str,
"description": self.getattr_return_str,
"beta": self.getattr_return_str,
"documentation": self.getattr_return_str,
"icon": self.validate_icon,
}
for attribute, func in attributes_func_mapping.items(): for attribute, func in ATTR_FUNC_MAPPING.items():
if hasattr(component_instance, attribute): if hasattr(component_instance, attribute):
value = getattr(component_instance, attribute) value = getattr(component_instance, attribute)
if value is not None: if value is not None:
@ -96,17 +82,5 @@ class Component:
return template_config return template_config
def validate_icon(self, value: str, *args, **kwargs):
# we are going to use the emoji library to validate the emoji
# emojis can be defined using the :emoji_name: syntax
if not value.startswith(":") or not value.endswith(":"):
warnings.warn("Invalid emoji. Please use the :emoji_name: syntax.")
return value
emoji_value = emoji.emojize(value, variant="emoji_type")
if value == emoji_value:
warnings.warn(f"Invalid emoji. {value} is not a valid emoji.")
return value
return emoji_value
def build(self, *args: Any, **kwargs: Any) -> Any: def build(self, *args: Any, **kwargs: Any) -> Any:
raise NotImplementedError raise NotImplementedError

View file

@ -7,7 +7,10 @@ from typing import Any, Dict, List, Optional, Union
from uuid import UUID from uuid import UUID
from fastapi import HTTPException from fastapi import HTTPException
from loguru import logger
from langflow.field_typing.range_spec import RangeSpec from langflow.field_typing.range_spec import RangeSpec
from langflow.interface.custom.attributes import ATTR_FUNC_MAPPING
from langflow.interface.custom.code_parser.utils import extract_inner_type from langflow.interface.custom.code_parser.utils import extract_inner_type
from langflow.interface.custom.custom_component import CustomComponent from langflow.interface.custom.custom_component import CustomComponent
from langflow.interface.custom.directory_reader.utils import ( from langflow.interface.custom.directory_reader.utils import (
@ -22,7 +25,6 @@ from langflow.template.frontend_node.custom_components import (
) )
from langflow.utils import validate from langflow.utils import validate
from langflow.utils.util import get_base_classes from langflow.utils.util import get_base_classes
from loguru import logger
def add_output_types( def add_output_types(
@ -263,16 +265,9 @@ def run_build_config(
def sanitize_template_config(template_config): def sanitize_template_config(template_config):
"""Sanitize the template config""" """Sanitize the template config"""
attributes = {
"display_name",
"description",
"beta",
"documentation",
"output_types",
"icon",
}
for key in template_config.copy(): for key in template_config.copy():
if key not in attributes: if key not in ATTR_FUNC_MAPPING.keys():
template_config.pop(key, None) template_config.pop(key, None)
return template_config return template_config