refactor: Update TextOperatorComponent to use langflow.template and langflow.schema
The TextOperatorComponent in TextOperator.py has been refactored to use the langflow.template.Input, langflow.template.Output, and langflow.schema.Record classes for improved code structure and maintainability. Note: The commit message has been generated based on the provided code changes and recent commits.
This commit is contained in:
parent
6e7421998d
commit
dd4b617b48
2 changed files with 62 additions and 47 deletions
|
|
@ -1,50 +1,64 @@
|
||||||
from typing import Optional, Union
|
from typing import Union
|
||||||
|
|
||||||
from langflow.custom import CustomComponent
|
from langflow.custom import Component
|
||||||
from langflow.field_typing import Text
|
from langflow.field_typing import Text
|
||||||
from langflow.schema import Record
|
from langflow.schema import Record
|
||||||
|
from langflow.template import Input, Output
|
||||||
|
|
||||||
|
|
||||||
class TextOperatorComponent(CustomComponent):
|
class TextOperatorComponent(Component):
|
||||||
display_name = "Text Operator"
|
display_name = "Text Operator"
|
||||||
description = "Compares two text inputs based on a specified condition such as equality or inequality, with optional case sensitivity."
|
description = "Compares two text inputs based on a specified condition such as equality or inequality, with optional case sensitivity."
|
||||||
|
|
||||||
def build_config(self) -> dict:
|
inputs = [
|
||||||
return {
|
Input(name="input_text", type=str, display_name="Input Text", info="The primary text input for the operation."),
|
||||||
"input_text": {
|
Input(name="match_text", type=str, display_name="Match Text", info="The text input to compare against."),
|
||||||
"display_name": "Input Text",
|
Input(
|
||||||
"info": "The primary text input for the operation.",
|
name="operator",
|
||||||
},
|
type=str,
|
||||||
"match_text": {
|
display_name="Operator",
|
||||||
"display_name": "Match Text",
|
info="The operator to apply for comparing the texts.",
|
||||||
"info": "The text input to compare against.",
|
options=["equals", "not equals", "contains", "starts with", "ends with", "exists"],
|
||||||
},
|
),
|
||||||
"operator": {
|
Input(
|
||||||
"display_name": "Operator",
|
name="case_sensitive",
|
||||||
"info": "The operator to apply for comparing the texts.",
|
type=bool,
|
||||||
"options": ["equals", "not equals", "contains", "starts with", "ends with", "exists"],
|
display_name="Case Sensitive",
|
||||||
},
|
info="If true, the comparison will be case sensitive.",
|
||||||
"case_sensitive": {
|
default=False,
|
||||||
"display_name": "Case Sensitive",
|
),
|
||||||
"info": "If true, the comparison will be case sensitive.",
|
Input(
|
||||||
"field_type": "bool",
|
name="true_output",
|
||||||
"default": False,
|
type=Union[str, Record],
|
||||||
},
|
display_name="True Output",
|
||||||
"true_output": {
|
info="The output to return or display when the comparison is true.",
|
||||||
"display_name": "Output",
|
input_types=["Text", "Record"],
|
||||||
"info": "The output to return or display when the comparison is true.",
|
),
|
||||||
"input_types": ["Text", "Record"], # Allow both text and record types
|
Input(
|
||||||
},
|
name="false_output",
|
||||||
}
|
type=Union[str, Record],
|
||||||
|
display_name="False Output",
|
||||||
|
info="The output to return or display when the comparison is false.",
|
||||||
|
input_types=["Text", "Record"],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
outputs = [
|
||||||
|
Output(name="True Result", method="result_response"),
|
||||||
|
Output(name="False Result", method="result_response"),
|
||||||
|
]
|
||||||
|
|
||||||
|
def true_response(self) -> Union[Text, Record]:
|
||||||
|
return self.true_output if self.true_output else self.input_text
|
||||||
|
|
||||||
|
def false_response(self) -> Union[Text, Record]:
|
||||||
|
return self.false_output if self.false_output else self.input_text
|
||||||
|
|
||||||
|
def result_response(self) -> Union[Text, Record]:
|
||||||
|
input_text = self.input_text
|
||||||
|
match_text = self.match_text
|
||||||
|
operator = self.operator
|
||||||
|
case_sensitive = self.case_sensitive
|
||||||
|
|
||||||
def build(
|
|
||||||
self,
|
|
||||||
input_text: Text,
|
|
||||||
match_text: Text,
|
|
||||||
operator: Text,
|
|
||||||
case_sensitive: bool = False,
|
|
||||||
true_output: Optional[Text] = "",
|
|
||||||
) -> Union[Text, Record]:
|
|
||||||
if not input_text or not match_text:
|
if not input_text or not match_text:
|
||||||
raise ValueError("Both 'input_text' and 'match_text' must be provided and non-empty.")
|
raise ValueError("Both 'input_text' and 'match_text' must be provided and non-empty.")
|
||||||
|
|
||||||
|
|
@ -64,13 +78,9 @@ class TextOperatorComponent(CustomComponent):
|
||||||
elif operator == "ends with":
|
elif operator == "ends with":
|
||||||
result = input_text.endswith(match_text)
|
result = input_text.endswith(match_text)
|
||||||
|
|
||||||
output_record = true_output if true_output else input_text
|
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
self.status = output_record
|
self.status = self.true_response()
|
||||||
return output_record
|
return self.true_response()
|
||||||
else:
|
else:
|
||||||
self.status = "Comparison failed, stopping execution."
|
self.status = self.false_response()
|
||||||
self.stop()
|
return self.false_response()
|
||||||
|
|
||||||
return output_record
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from uuid import UUID, uuid4
|
||||||
import pytest
|
import pytest
|
||||||
from fastapi import status
|
from fastapi import status
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
from langflow.custom.directory_reader.directory_reader import DirectoryReader
|
from langflow.custom.directory_reader.directory_reader import DirectoryReader
|
||||||
from langflow.services.deps import get_settings_service
|
from langflow.services.deps import get_settings_service
|
||||||
|
|
||||||
|
|
@ -638,6 +637,7 @@ def test_successful_run_with_input_type_any(client, starter_project, created_api
|
||||||
), any_input_outputs
|
), any_input_outputs
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_with_inputs_and_outputs(client, starter_project, created_api_key):
|
def test_run_with_inputs_and_outputs(client, starter_project, created_api_key):
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
flow_id = starter_project["id"]
|
flow_id = starter_project["id"]
|
||||||
|
|
@ -665,6 +665,7 @@ def test_invalid_flow_id(client, created_api_key):
|
||||||
# Check if the error detail is as expected
|
# Check if the error detail is as expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_flow_with_caching_success(client: TestClient, starter_project, created_api_key):
|
def test_run_flow_with_caching_success(client: TestClient, starter_project, created_api_key):
|
||||||
flow_id = starter_project["id"]
|
flow_id = starter_project["id"]
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
|
|
@ -682,6 +683,7 @@ def test_run_flow_with_caching_success(client: TestClient, starter_project, crea
|
||||||
assert "session_id" in data
|
assert "session_id" in data
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_flow_with_caching_invalid_flow_id(client: TestClient, created_api_key):
|
def test_run_flow_with_caching_invalid_flow_id(client: TestClient, created_api_key):
|
||||||
invalid_flow_id = uuid4()
|
invalid_flow_id = uuid4()
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
|
|
@ -693,6 +695,7 @@ def test_run_flow_with_caching_invalid_flow_id(client: TestClient, created_api_k
|
||||||
assert f"Flow identifier {invalid_flow_id} not found" in data["detail"]
|
assert f"Flow identifier {invalid_flow_id} not found" in data["detail"]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_flow_with_caching_invalid_input_format(client: TestClient, starter_project, created_api_key):
|
def test_run_flow_with_caching_invalid_input_format(client: TestClient, starter_project, created_api_key):
|
||||||
flow_id = starter_project["id"]
|
flow_id = starter_project["id"]
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
|
|
@ -701,6 +704,7 @@ def test_run_flow_with_caching_invalid_input_format(client: TestClient, starter_
|
||||||
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
|
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_flow_with_session_id(client, starter_project, created_api_key):
|
def test_run_flow_with_session_id(client, starter_project, created_api_key):
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
flow_id = starter_project["id"]
|
flow_id = starter_project["id"]
|
||||||
|
|
@ -732,6 +736,7 @@ def test_run_flow_with_invalid_session_id(client, starter_project, created_api_k
|
||||||
assert f"Session {payload['session_id']} not found" in data["detail"]
|
assert f"Session {payload['session_id']} not found" in data["detail"]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_flow_with_invalid_tweaks(client, starter_project, created_api_key):
|
def test_run_flow_with_invalid_tweaks(client, starter_project, created_api_key):
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
flow_id = starter_project["id"]
|
flow_id = starter_project["id"]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue