Fix various issues and refactor code (#1647)

* Add options field to FIELD_FORMAT_ATTRIBUTES constant and import pathlib in test_initial_setup.py

* Update TEXT_FILE_TYPES in utils.py and handle missing file path error in Vertex class

* Fix tweak value assignment in process.py and clear session cache in test_process.py

* New lock

* Update repository URLs and fix file paths in code blocks

* Fix data retrieval in test_pickle_graph and test_pickle_each_vertex in test_graph.py

* Refactor load_starter_projects function to include type hinting in setup.py

* Update name of Basic Prompting (Hello, world!) project to Basic Prompting (Hello, World)

* Refactor Graph.process() method to accept start_component_id parameter

* Refactor test_endpoints.py to use "Chat Output" instead of "Prompt Output" and "ChatOutput" instead of "TextOutput"
This commit is contained in:
Gabriel Luiz Freitas Almeida 2024-04-09 01:02:56 -03:00 • committed by GitHub
commit 254f11485e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 3452 additions and 3430 deletions

View file

@ -6,10 +6,9 @@ import httpx
import pytest
import respx
from httpx import Response
from langflow.components import (
data,
) # Adjust the import according to your project structure
)
@pytest.fixture
@ -135,7 +134,7 @@ def test_directory_without_mocks():
from langflow.initial_setup import setup
from langflow.initial_setup.setup import load_starter_projects
projects = load_starter_projects()
_, projects = zip(*load_starter_projects())
# the setup module has a folder where the projects are stored
# the contents of that folder are in the projects variable
# the directory component can be used to load the projects

View file

@ -472,11 +472,11 @@ def test_successful_run_with_output_type_text(client, starter_project, created_a
assert isinstance(outputs_dict.get("outputs"), list)
assert len(outputs_dict.get("outputs")) == 1
ids = [output.get("component_id") for output in outputs_dict.get("outputs")]
assert all(["TextOutput" in _id for _id in ids]), ids
assert all(["ChatOutput" in _id for _id in ids]), ids
display_names = [output.get("component_display_name") for output in outputs_dict.get("outputs")]
assert all([name in display_names for name in ["Prompt Output"]]), display_names
assert all([name in display_names for name in ["Chat Output"]]), display_names
inner_results = [output.get("results").get("result") for output in outputs_dict.get("outputs")]
expected_result = "Langflow"
expected_result = ""
assert all([expected_result in result for result in inner_results]), inner_results
@ -501,13 +501,13 @@ def test_successful_run_with_output_type_any(client, starter_project, created_ap
assert "outputs" in outputs_dict
assert outputs_dict.get("inputs") == {"input_value": ""}
assert isinstance(outputs_dict.get("outputs"), list)
assert len(outputs_dict.get("outputs")) == 2
assert len(outputs_dict.get("outputs")) == 1
ids = [output.get("component_id") for output in outputs_dict.get("outputs")]
assert all(["ChatOutput" in _id or "TextOutput" in _id for _id in ids]), ids
display_names = [output.get("component_display_name") for output in outputs_dict.get("outputs")]
assert all([name in display_names for name in ["Chat Output", "Prompt Output"]]), display_names
assert all([name in display_names for name in ["Chat Output"]]), display_names
inner_results = [output.get("results").get("result") for output in outputs_dict.get("outputs")]
expected_result = "Langflow"
expected_result = ""
assert all([expected_result in result for result in inner_results]), inner_results
@ -533,7 +533,7 @@ def test_successful_run_with_output_type_debug(client, starter_project, created_
assert "outputs" in outputs_dict
assert outputs_dict.get("inputs") == {"input_value": ""}
assert isinstance(outputs_dict.get("outputs"), list)
assert len(outputs_dict.get("outputs")) == 7
assert len(outputs_dict.get("outputs")) == 4
# To test input_type wel'l just set it with output_type debug and check if the value is correct
@ -559,10 +559,10 @@ def test_successful_run_with_input_type_text(client, starter_project, created_ap
assert "outputs" in outputs_dict
assert outputs_dict.get("inputs") == {"input_value": "value1"}
assert isinstance(outputs_dict.get("outputs"), list)
assert len(outputs_dict.get("outputs")) == 7
assert len(outputs_dict.get("outputs")) == 4
# Now we get all components that contain TextInput in the component_id
text_input_outputs = [output for output in outputs_dict.get("outputs") if "TextInput" in output.get("component_id")]
assert len(text_input_outputs) == 2
assert len(text_input_outputs) == 0
# Now we check if the input_value is correct
assert all([output.get("results").get("result") == "value1" for output in text_input_outputs]), text_input_outputs
@ -590,7 +590,7 @@ def test_successful_run_with_input_type_chat(client, starter_project, created_ap
assert "outputs" in outputs_dict
assert outputs_dict.get("inputs") == {"input_value": "value1"}
assert isinstance(outputs_dict.get("outputs"), list)
assert len(outputs_dict.get("outputs")) == 7
assert len(outputs_dict.get("outputs")) == 4
# Now we get all components that contain TextInput in the component_id
chat_input_outputs = [output for output in outputs_dict.get("outputs") if "ChatInput" in output.get("component_id")]
assert len(chat_input_outputs) == 1
@ -620,14 +620,14 @@ def test_successful_run_with_input_type_any(client, starter_project, created_api
assert "outputs" in outputs_dict
assert outputs_dict.get("inputs") == {"input_value": "value1"}
assert isinstance(outputs_dict.get("outputs"), list)
assert len(outputs_dict.get("outputs")) == 7
assert len(outputs_dict.get("outputs")) == 4
# Now we get all components that contain TextInput or ChatInput in the component_id
any_input_outputs = [
output
for output in outputs_dict.get("outputs")
if "TextInput" in output.get("component_id") or "ChatInput" in output.get("component_id")
]
assert len(any_input_outputs) == 3
assert len(any_input_outputs) == 1
# Now we check if the input_value is correct
assert all([output.get("results").get("result") == "value1" for output in any_input_outputs]), any_input_outputs

View file

@ -409,7 +409,7 @@ def test_update_source_handle():
@pytest.mark.asyncio
async def test_pickle_graph(json_vector_store):
starter_projects = load_starter_projects()
data = starter_projects[0]["data"]
data = starter_projects[0][1]["data"]
graph = Graph.from_payload(data)
assert isinstance(graph, Graph)
pickled = pickle.dumps(graph)
@ -421,7 +421,7 @@ async def test_pickle_graph(json_vector_store):
@pytest.mark.asyncio
async def test_pickle_each_vertex(json_vector_store):
starter_projects = load_starter_projects()
data = starter_projects[0]["data"]
data = starter_projects[0][1]["data"]
graph = Graph.from_payload(data)
assert isinstance(graph, Graph)
for vertex in graph.vertices:
@ -430,15 +430,3 @@ async def test_pickle_each_vertex(json_vector_store):
assert pickled is not None
unpickled = pickle.loads(pickled)
assert unpickled is not None
@pytest.mark.asyncio
async def test_build_ordering(complex_graph_with_groups):
sorted_vertices = complex_graph_with_groups.sort_vertices(stop_component_id="ChatInput-Ay8QQ")
assert sorted_vertices == [
"ChatInput-Ay8QQ",
"RecordsAsText-vkx2A",
"FileLoader-Vo1Cq",
]
sorted_vertices = complex_graph_with_groups.sort_vertices()

View file

@ -1,4 +1,5 @@
from datetime import datetime
from pathlib import Path
import pytest
from langflow.graph.graph.base import Graph
@ -10,6 +11,7 @@ from langflow.initial_setup.setup import (
load_starter_projects,
)
from langflow.memory import delete_messages
from langflow.processing.process import process_tweaks
from langflow.services.database.models.flow.model import Flow
from langflow.services.deps import session_scope
from sqlalchemy import func
@ -19,7 +21,8 @@ from sqlmodel import select
def test_load_starter_projects():
projects = load_starter_projects()
assert isinstance(projects, list)
assert all(isinstance(project, dict) for project in projects)
assert all(isinstance(project[1], dict) for project in projects)
assert all(isinstance(project[0], Path) for project in projects)
def test_get_project_data():
@ -59,7 +62,7 @@ def test_create_or_update_starter_projects(client):
@pytest.mark.asyncio
async def test_starter_project_can_run_successfully(client):
async def test_starter_projects_can_run_successfully(client):
with session_scope() as session:
# Run the function to create or update projects
create_or_update_starter_projects()
@ -75,12 +78,13 @@ async def test_starter_project_can_run_successfully(client):
# Get all the starter projects
projects = session.exec(select(Flow).where(Flow.folder == STARTER_FOLDER_NAME)).all()
graphs: list[tuple[str, Graph]] = [
(project.name, Graph.from_payload(project.data, flow_id=project.id))
for project in projects
if "Document" not in project.name or "RAG" not in project.name
]
graphs: list[tuple[str, Graph]] = []
for project in projects:
# Add tweaks to make file_path work
tweaks = {"path": __file__}
graph_data = process_tweaks(project.data, tweaks)
graph_object = Graph.from_payload(graph_data, flow_id=project.id)
graphs.append((project.name, graph_object))
assert len(graphs) == len(projects)
for name, graph in graphs:
outputs = await graph.arun(

View file

@ -1,5 +1,4 @@
import pytest
from langflow.processing.process import process_tweaks
from langflow.services.deps import get_session_service
@ -284,12 +283,12 @@ async def test_load_langchain_object_with_no_cached_session(client, basic_graph_
session_id = session_service.build_key(session_id1, basic_graph_data)
graph1, artifacts1 = await session_service.load_session(session_id, data_graph=basic_graph_data, flow_id="flow_id")
# Clear the cache
session_service.clear_session(session_id)
# Use the new session_id to get the langchain_object again
await session_service.clear_session(session_id)
# Use the new session_id to get the graph again
graph2, artifacts2 = await session_service.load_session(session_id, data_graph=basic_graph_data, flow_id="flow_id")
assert id(graph1) != id(graph2)
# Since the cache was cleared, objects should be different
assert id(graph1) != id(graph2)
@pytest.mark.asyncio