feat: add batch run beta component (#5489)
* feat: add batch run beta component * [autofix.ci] apply automated fixes * Update batch_run to run async using Runnable * [autofix.ci] apply automated fixes * refactor: streamline BatchRunComponent by removing unused synchronous model invocation and enhancing async processing - Consolidated imports and improved type checking for LanguageModel. - Simplified the run_batch method by directly using the model's asynchronous capabilities. - Enhanced error handling for missing DataFrame columns. - Cleaned up comments and improved code readability. * refactor: update BatchRunComponent to use Runnable for improved async processing - Added future annotations for better type hinting. - Replaced LanguageModel with Runnable in type checking and method implementation. - Enhanced code clarity and maintainability by consolidating imports. * test: add unit tests for BatchRunComponent functionality - Introduced a new test suite for BatchRunComponent to validate its behavior. - Added tests for successful batch runs with and without system messages. - Implemented tests for handling invalid column names and empty DataFrames. - Included a test to ensure non-string columns are converted to strings during processing. * refactor: rename useful.py to mock_language_model.py and update imports --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
parent
3df81309bf
commit
75c3c1ce97
5 changed files with 191 additions and 1 deletions
|
|
@ -0,0 +1,88 @@
|
|||
import re
|
||||
|
||||
import pytest
|
||||
from langflow.components.helpers.batch_run import BatchRunComponent
|
||||
from langflow.schema import DataFrame
|
||||
|
||||
from tests.base import ComponentTestBaseWithoutClient
|
||||
from tests.unit.mock_language_model import MockLanguageModel
|
||||
|
||||
|
||||
class TestBatchRunComponent(ComponentTestBaseWithoutClient):
|
||||
@pytest.fixture
|
||||
def component_class(self):
|
||||
"""Return the component class to test."""
|
||||
return BatchRunComponent
|
||||
|
||||
@pytest.fixture
|
||||
def default_kwargs(self):
|
||||
"""Return the default kwargs for the component."""
|
||||
return {
|
||||
"model": MockLanguageModel(),
|
||||
"df": DataFrame({"text": ["Hello"]}),
|
||||
"column_name": "text",
|
||||
}
|
||||
|
||||
@pytest.fixture
|
||||
def file_names_mapping(self):
|
||||
"""Return an empty list since this component doesn't have version-specific files."""
|
||||
return []
|
||||
|
||||
async def test_successful_batch_run_with_system_message(self):
|
||||
# Create test data
|
||||
test_df = DataFrame({"text": ["Hello", "World", "Test"]})
|
||||
|
||||
component = BatchRunComponent(
|
||||
model=MockLanguageModel(), system_message="You are a helpful assistant", df=test_df, column_name="text"
|
||||
)
|
||||
|
||||
# Run the batch process
|
||||
result = await component.run_batch()
|
||||
|
||||
# Verify the results
|
||||
assert isinstance(result, DataFrame)
|
||||
assert "text_input" in result.columns
|
||||
assert "model_response" in result.columns
|
||||
assert len(result) == 3
|
||||
assert all(isinstance(resp, str) for resp in result["model_response"])
|
||||
|
||||
async def test_batch_run_without_system_message(self):
|
||||
test_df = DataFrame({"text": ["Hello", "World"]})
|
||||
|
||||
component = BatchRunComponent(model=MockLanguageModel(), df=test_df, column_name="text")
|
||||
|
||||
result = await component.run_batch()
|
||||
|
||||
assert isinstance(result, DataFrame)
|
||||
assert len(result) == 2
|
||||
assert all(isinstance(resp, str) for resp in result["model_response"])
|
||||
|
||||
async def test_invalid_column_name(self):
|
||||
component = BatchRunComponent(
|
||||
model=MockLanguageModel(), df=DataFrame({"text": ["Hello"]}), column_name="nonexistent_column"
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError, match=re.escape("Column 'nonexistent_column' not found in the DataFrame.")):
|
||||
await component.run_batch()
|
||||
|
||||
async def test_empty_dataframe(self):
|
||||
component = BatchRunComponent(model=MockLanguageModel(), df=DataFrame({"text": []}), column_name="text")
|
||||
|
||||
result = await component.run_batch()
|
||||
assert isinstance(result, DataFrame)
|
||||
assert len(result) == 0
|
||||
|
||||
async def test_non_string_column_conversion(self):
|
||||
test_df = DataFrame(
|
||||
{
|
||||
"text": [123, 456, 789] # Numeric values
|
||||
}
|
||||
)
|
||||
|
||||
component = BatchRunComponent(model=MockLanguageModel(), df=test_df, column_name="text")
|
||||
|
||||
result = await component.run_batch()
|
||||
|
||||
assert isinstance(result, DataFrame)
|
||||
assert all(isinstance(text, str) for text in result["text_input"])
|
||||
assert all(str(num) in text for num, text in zip(test_df["text"], result["text_input"], strict=False))
|
||||
|
|
@ -8,7 +8,7 @@ from langflow.inputs.inputs import TableInput
|
|||
from langflow.schema.data import Data
|
||||
from pydantic import BaseModel
|
||||
|
||||
from tests.unit.useful import MockLanguageModel
|
||||
from tests.unit.mock_language_model import MockLanguageModel
|
||||
|
||||
|
||||
class TestStructuredOutputComponent:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue