Fix import statements and formatting issues
This commit is contained in:
parent
47397153f4
commit
a6a69a0f3a
24 changed files with 924 additions and 527 deletions
|
|
@ -1,13 +1,19 @@
|
|||
import ast
|
||||
import pytest
|
||||
import types
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from langflow.interface.custom.base import CustomComponent
|
||||
from langflow.interface.custom.code_parser.code_parser import CodeParser, CodeSyntaxError
|
||||
from langflow.interface.custom.custom_component.component import Component, ComponentCodeNullError
|
||||
from langflow.interface.custom.utils import build_custom_component_template
|
||||
|
||||
from fastapi import HTTPException
|
||||
from langflow.services.database.models.flow import Flow, FlowCreate
|
||||
from langflow.interface.custom.base import CustomComponent
|
||||
from langflow.interface.custom.component import (
|
||||
Component,
|
||||
ComponentCodeNullError,
|
||||
ComponentFunctionEntrypointNameNullError,
|
||||
)
|
||||
from langflow.interface.custom.code_parser import CodeParser, CodeSyntaxError
|
||||
|
||||
|
||||
code_default = """
|
||||
from langflow import Prompt
|
||||
|
|
@ -47,7 +53,7 @@ def test_code_parser_get_tree():
|
|||
Test the __get_tree method of the CodeParser class.
|
||||
"""
|
||||
parser = CodeParser(code_default)
|
||||
tree = parser.get_tree()
|
||||
tree = parser._CodeParser__get_tree()
|
||||
assert isinstance(tree, ast.AST)
|
||||
|
||||
|
||||
|
|
@ -60,23 +66,23 @@ def test_code_parser_syntax_error():
|
|||
|
||||
parser = CodeParser(code_syntax_error)
|
||||
with pytest.raises(CodeSyntaxError):
|
||||
parser.get_tree()
|
||||
parser._CodeParser__get_tree()
|
||||
|
||||
|
||||
def test_component_init():
|
||||
"""
|
||||
Test the initialization of the Component class.
|
||||
"""
|
||||
component = Component(code=code_default, _function_entrypoint_name="build")
|
||||
component = Component(code=code_default, function_entrypoint_name="build")
|
||||
assert component.code == code_default
|
||||
assert component._function_entrypoint_name == "build"
|
||||
assert component.function_entrypoint_name == "build"
|
||||
|
||||
|
||||
def test_component_get_code_tree():
|
||||
"""
|
||||
Test the get_code_tree method of the Component class.
|
||||
"""
|
||||
component = Component(code=code_default, _function_entrypoint_name="build")
|
||||
component = Component(code=code_default, function_entrypoint_name="build")
|
||||
tree = component.get_code_tree(component.code)
|
||||
assert "imports" in tree
|
||||
|
||||
|
|
@ -86,20 +92,19 @@ def test_component_code_null_error():
|
|||
Test the get_function method raises the
|
||||
ComponentCodeNullError when the code is empty.
|
||||
"""
|
||||
component = Component(code="", _function_entrypoint_name="")
|
||||
component = Component(code="", function_entrypoint_name="")
|
||||
with pytest.raises(ComponentCodeNullError):
|
||||
component.get_function()
|
||||
|
||||
|
||||
# TODO: Validate if we should remove this
|
||||
# def test_component_function_entrypoint_name_null_error():
|
||||
# """
|
||||
# Test the get_function method raises the ComponentFunctionEntrypointNameNullError
|
||||
# when the function_entrypoint_name is empty.
|
||||
# """
|
||||
# component = Component(code=code_default, _function_entrypoint_name="")
|
||||
# with pytest.raises(ComponentFunctionEntrypointNameNullError):
|
||||
# component.get_function()
|
||||
def test_component_function_entrypoint_name_null_error():
|
||||
"""
|
||||
Test the get_function method raises the ComponentFunctionEntrypointNameNullError
|
||||
when the function_entrypoint_name is empty.
|
||||
"""
|
||||
component = Component(code=code_default, function_entrypoint_name="")
|
||||
with pytest.raises(ComponentFunctionEntrypointNameNullError):
|
||||
component.get_function()
|
||||
|
||||
|
||||
def test_custom_component_init():
|
||||
|
|
@ -108,7 +113,9 @@ def test_custom_component_init():
|
|||
"""
|
||||
function_entrypoint_name = "build"
|
||||
|
||||
custom_component = CustomComponent(code=code_default, function_entrypoint_name=function_entrypoint_name)
|
||||
custom_component = CustomComponent(
|
||||
code=code_default, function_entrypoint_name=function_entrypoint_name
|
||||
)
|
||||
assert custom_component.code == code_default
|
||||
assert custom_component.function_entrypoint_name == function_entrypoint_name
|
||||
|
||||
|
|
@ -117,8 +124,10 @@ def test_custom_component_build_template_config():
|
|||
"""
|
||||
Test the build_template_config property of the CustomComponent class.
|
||||
"""
|
||||
custom_component = CustomComponent(code=code_default, function_entrypoint_name="build")
|
||||
config = custom_component.template_config
|
||||
custom_component = CustomComponent(
|
||||
code=code_default, function_entrypoint_name="build"
|
||||
)
|
||||
config = custom_component.build_template_config
|
||||
assert isinstance(config, dict)
|
||||
|
||||
|
||||
|
|
@ -126,7 +135,9 @@ def test_custom_component_get_function():
|
|||
"""
|
||||
Test the get_function property of the CustomComponent class.
|
||||
"""
|
||||
custom_component = CustomComponent(code="def build(): pass", function_entrypoint_name="build")
|
||||
custom_component = CustomComponent(
|
||||
code="def build(): pass", function_entrypoint_name="build"
|
||||
)
|
||||
my_function = custom_component.get_function
|
||||
assert isinstance(my_function, types.FunctionType)
|
||||
|
||||
|
|
@ -137,7 +148,7 @@ def test_code_parser_parse_imports_import():
|
|||
class with an import statement.
|
||||
"""
|
||||
parser = CodeParser(code_default)
|
||||
tree = parser.get_tree()
|
||||
tree = parser._CodeParser__get_tree()
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.Import):
|
||||
parser.parse_imports(node)
|
||||
|
|
@ -150,7 +161,7 @@ def test_code_parser_parse_imports_importfrom():
|
|||
class with an import from statement.
|
||||
"""
|
||||
parser = CodeParser("from os import path")
|
||||
tree = parser.get_tree()
|
||||
tree = parser._CodeParser__get_tree()
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.ImportFrom):
|
||||
parser.parse_imports(node)
|
||||
|
|
@ -162,7 +173,7 @@ def test_code_parser_parse_functions():
|
|||
Test the parse_functions method of the CodeParser class.
|
||||
"""
|
||||
parser = CodeParser("def test(): pass")
|
||||
tree = parser.get_tree()
|
||||
tree = parser._CodeParser__get_tree()
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.FunctionDef):
|
||||
parser.parse_functions(node)
|
||||
|
|
@ -175,7 +186,7 @@ def test_code_parser_parse_classes():
|
|||
Test the parse_classes method of the CodeParser class.
|
||||
"""
|
||||
parser = CodeParser("class Test: pass")
|
||||
tree = parser.get_tree()
|
||||
tree = parser._CodeParser__get_tree()
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.ClassDef):
|
||||
parser.parse_classes(node)
|
||||
|
|
@ -188,7 +199,7 @@ def test_code_parser_parse_global_vars():
|
|||
Test the parse_global_vars method of the CodeParser class.
|
||||
"""
|
||||
parser = CodeParser("x = 1")
|
||||
tree = parser.get_tree()
|
||||
tree = parser._CodeParser__get_tree()
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.Assign):
|
||||
parser.parse_global_vars(node)
|
||||
|
|
@ -201,7 +212,7 @@ def test_component_get_function_valid():
|
|||
Test the get_function method of the Component
|
||||
class with valid code and function_entrypoint_name.
|
||||
"""
|
||||
component = Component(code="def build(): pass", _function_entrypoint_name="build")
|
||||
component = Component(code="def build(): pass", function_entrypoint_name="build")
|
||||
my_function = component.get_function()
|
||||
assert callable(my_function)
|
||||
|
||||
|
|
@ -211,7 +222,9 @@ def test_custom_component_get_function_entrypoint_args():
|
|||
Test the get_function_entrypoint_args
|
||||
property of the CustomComponent class.
|
||||
"""
|
||||
custom_component = CustomComponent(code=code_default, function_entrypoint_name="build")
|
||||
custom_component = CustomComponent(
|
||||
code=code_default, function_entrypoint_name="build"
|
||||
)
|
||||
args = custom_component.get_function_entrypoint_args
|
||||
assert len(args) == 4
|
||||
assert args[0]["name"] == "self"
|
||||
|
|
@ -224,18 +237,20 @@ def test_custom_component_get_function_entrypoint_return_type():
|
|||
Test the get_function_entrypoint_return_type
|
||||
property of the CustomComponent class.
|
||||
"""
|
||||
from langchain.schema import Document
|
||||
|
||||
custom_component = CustomComponent(code=code_default, function_entrypoint_name="build")
|
||||
custom_component = CustomComponent(
|
||||
code=code_default, function_entrypoint_name="build"
|
||||
)
|
||||
return_type = custom_component.get_function_entrypoint_return_type
|
||||
assert return_type == [Document]
|
||||
assert return_type == ["Document"]
|
||||
|
||||
|
||||
def test_custom_component_get_main_class_name():
|
||||
"""
|
||||
Test the get_main_class_name property of the CustomComponent class.
|
||||
"""
|
||||
custom_component = CustomComponent(code=code_default, function_entrypoint_name="build")
|
||||
custom_component = CustomComponent(
|
||||
code=code_default, function_entrypoint_name="build"
|
||||
)
|
||||
class_name = custom_component.get_main_class_name
|
||||
assert class_name == "YourComponent"
|
||||
|
||||
|
|
@ -245,7 +260,9 @@ def test_custom_component_get_function_valid():
|
|||
Test the get_function property of the CustomComponent
|
||||
class with valid code and function_entrypoint_name.
|
||||
"""
|
||||
custom_component = CustomComponent(code="def build(): pass", function_entrypoint_name="build")
|
||||
custom_component = CustomComponent(
|
||||
code="def build(): pass", function_entrypoint_name="build"
|
||||
)
|
||||
my_function = custom_component.get_function
|
||||
assert callable(my_function)
|
||||
|
||||
|
|
@ -280,7 +297,9 @@ def test_code_parser_parse_callable_details_no_args():
|
|||
parser = CodeParser("")
|
||||
node = ast.FunctionDef(
|
||||
name="test",
|
||||
args=ast.arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]),
|
||||
args=ast.arguments(
|
||||
args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]
|
||||
),
|
||||
body=[],
|
||||
decorator_list=[],
|
||||
returns=None,
|
||||
|
|
@ -309,7 +328,7 @@ def test_code_parser_parse_ann_assign():
|
|||
stmt = ast.AnnAssign(
|
||||
target=ast.Name(id="x", ctx=ast.Store()),
|
||||
annotation=ast.Name(id="int", ctx=ast.Load()),
|
||||
value=ast.Constant(n=1),
|
||||
value=ast.Num(n=1),
|
||||
simple=1,
|
||||
)
|
||||
result = parser.parse_ann_assign(stmt)
|
||||
|
|
@ -326,7 +345,9 @@ def test_code_parser_parse_function_def_not_init():
|
|||
parser = CodeParser("")
|
||||
stmt = ast.FunctionDef(
|
||||
name="test",
|
||||
args=ast.arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]),
|
||||
args=ast.arguments(
|
||||
args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]
|
||||
),
|
||||
body=[],
|
||||
decorator_list=[],
|
||||
returns=None,
|
||||
|
|
@ -344,7 +365,9 @@ def test_code_parser_parse_function_def_init():
|
|||
parser = CodeParser("")
|
||||
stmt = ast.FunctionDef(
|
||||
name="__init__",
|
||||
args=ast.arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]),
|
||||
args=ast.arguments(
|
||||
args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]
|
||||
),
|
||||
body=[],
|
||||
decorator_list=[],
|
||||
returns=None,
|
||||
|
|
@ -359,17 +382,29 @@ def test_component_get_code_tree_syntax_error():
|
|||
Test the get_code_tree method of the Component class
|
||||
raises the CodeSyntaxError when given incorrect syntax.
|
||||
"""
|
||||
component = Component(code="import os as", _function_entrypoint_name="build")
|
||||
component = Component(code="import os as", function_entrypoint_name="build")
|
||||
with pytest.raises(CodeSyntaxError):
|
||||
component.get_code_tree(component.code)
|
||||
|
||||
|
||||
def test_custom_component_class_template_validation_no_code():
|
||||
"""
|
||||
Test the _class_template_validation method of the CustomComponent class
|
||||
raises the HTTPException when the code is None.
|
||||
"""
|
||||
custom_component = CustomComponent(code=None, function_entrypoint_name="build")
|
||||
with pytest.raises(HTTPException):
|
||||
custom_component._class_template_validation(custom_component.code)
|
||||
|
||||
|
||||
def test_custom_component_get_code_tree_syntax_error():
|
||||
"""
|
||||
Test the get_code_tree method of the CustomComponent class
|
||||
raises the CodeSyntaxError when given incorrect syntax.
|
||||
"""
|
||||
custom_component = CustomComponent(code="import os as", function_entrypoint_name="build")
|
||||
custom_component = CustomComponent(
|
||||
code="import os as", function_entrypoint_name="build"
|
||||
)
|
||||
with pytest.raises(CodeSyntaxError):
|
||||
custom_component.get_code_tree(custom_component.code)
|
||||
|
||||
|
|
@ -423,7 +458,9 @@ def test_custom_component_build_not_implemented():
|
|||
Test the build method of the CustomComponent
|
||||
class raises the NotImplementedError.
|
||||
"""
|
||||
custom_component = CustomComponent(code="def build(): pass", function_entrypoint_name="build")
|
||||
custom_component = CustomComponent(
|
||||
code="def build(): pass", function_entrypoint_name="build"
|
||||
)
|
||||
with pytest.raises(NotImplementedError):
|
||||
custom_component.build()
|
||||
|
||||
|
|
@ -431,7 +468,7 @@ def test_custom_component_build_not_implemented():
|
|||
def test_build_config_no_code():
|
||||
component = CustomComponent(code=None)
|
||||
|
||||
assert component.get_function_entrypoint_args == []
|
||||
assert component.get_function_entrypoint_args == ""
|
||||
assert component.get_function_entrypoint_return_type == []
|
||||
|
||||
|
||||
|
|
@ -457,7 +494,9 @@ def test_flow(db):
|
|||
}
|
||||
|
||||
# Create flow
|
||||
flow = FlowCreate(id=uuid4(), name="Test Flow", description="Fixture flow", data=flow_data)
|
||||
flow = FlowCreate(
|
||||
id=uuid4(), name="Test Flow", description="Fixture flow", data=flow_data
|
||||
)
|
||||
|
||||
# Add to database
|
||||
db.add(flow)
|
||||
|
|
@ -518,36 +557,3 @@ def test_build_config_field_value_keys(component):
|
|||
config = component.build_config()
|
||||
field_values = config["fields"].values()
|
||||
assert all("type" in value for value in field_values)
|
||||
|
||||
|
||||
def test_create_and_validate_component_valid_code(test_component_code):
|
||||
component = CustomComponent(code=test_component_code)
|
||||
assert isinstance(component, CustomComponent)
|
||||
|
||||
|
||||
def test_build_langchain_template_custom_component_valid_code(test_component_code):
|
||||
component = CustomComponent(code=test_component_code)
|
||||
frontend_node = build_custom_component_template(component)
|
||||
assert isinstance(frontend_node, dict)
|
||||
template = frontend_node["template"]
|
||||
assert isinstance(template, dict)
|
||||
assert "param" in template
|
||||
param_options = template["param"]["options"]
|
||||
# Now run it again with an update field
|
||||
frontend_node = build_custom_component_template(component, update_field="param")
|
||||
new_param_options = frontend_node["template"]["param"]["options"]
|
||||
assert param_options != new_param_options
|
||||
|
||||
|
||||
def test_build_langchain_template_custom_component_templatefield(test_component_with_templatefield_code):
|
||||
component = CustomComponent(code=test_component_with_templatefield_code)
|
||||
frontend_node = build_custom_component_template(component)
|
||||
assert isinstance(frontend_node, dict)
|
||||
template = frontend_node["template"]
|
||||
assert isinstance(template, dict)
|
||||
assert "param" in template
|
||||
param_options = template["param"]["options"]
|
||||
# Now run it again with an update field
|
||||
frontend_node = build_custom_component_template(component, update_field="param")
|
||||
new_param_options = frontend_node["template"]["param"]["options"]
|
||||
assert param_options != new_param_options
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue