Skip to content

Commit

Permalink
feat: add payload validation, update Simple API Test fixture, run tes…
Browse files Browse the repository at this point in the history
…ts (#2664)
  • Loading branch information
ogabrielluiz authored Jul 12, 2024
1 parent cdb8c80 commit c47c358
Show file tree
Hide file tree
Showing 8 changed files with 668 additions and 31 deletions.
32 changes: 32 additions & 0 deletions src/backend/base/langflow/api/v1/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
)
from langflow.custom.custom_component.component import Component
from langflow.custom.utils import build_custom_component_template, get_instance_name
from langflow.exceptions.api import InvalidChatInputException
from langflow.graph.graph.base import Graph
from langflow.graph.schema import RunOutputs
from langflow.helpers.flow import get_flow_by_id_or_endpoint_name
Expand Down Expand Up @@ -75,12 +76,40 @@ async def get_all(
raise HTTPException(status_code=500, detail=str(exc)) from exc


def validate_input_and_tweaks(input_request: SimplifiedAPIRequest):
# If the input_value is not None and the input_type is "chat"
# then we need to check the tweaks if the ChatInput component is present
# and if its input_value is not None
# if so, we raise an error
if input_request.tweaks is None:
return
for key, value in input_request.tweaks.items():
if "ChatInput" in key or "Chat Input" in key:
if isinstance(value, dict):
has_input_value = value.get("input_value") is not None
input_value_is_chat = input_request.input_value is not None and input_request.input_type == "chat"
if has_input_value and input_value_is_chat:
raise InvalidChatInputException(
"If you pass an input_value to the chat input, you cannot pass a tweak with the same name."
)
elif "Text Input" in key or "TextInput" in key:
if isinstance(value, dict):
has_input_value = value.get("input_value") is not None
input_value_is_text = input_request.input_value is not None and input_request.input_type == "text"
if has_input_value and input_value_is_text:
raise InvalidChatInputException(
"If you pass an input_value to the text input, you cannot pass a tweak with the same name."
)


async def simple_run_flow(
flow: Flow,
input_request: SimplifiedAPIRequest,
stream: bool = False,
api_key_user: Optional[User] = None,
):
if input_request.input_value is not None and input_request.tweaks is not None:
validate_input_and_tweaks(input_request)
try:
task_result: List[RunOutputs] = []
user_id = api_key_user.id if api_key_user else None
Expand Down Expand Up @@ -232,6 +261,9 @@ async def simplified_run_flow(
else:
logger.exception(exc)
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc)) from exc
except InvalidChatInputException as exc:
logger.error(exc)
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
except Exception as exc:
logger.exception(exc)
background_tasks.add_task(
Expand Down
2 changes: 1 addition & 1 deletion src/backend/base/langflow/api/v1/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ class InputValueRequest(BaseModel):


class SimplifiedAPIRequest(BaseModel):
input_value: Optional[str] = Field(default="", description="The input value")
input_value: Optional[str] = Field(default=None, description="The input value")
input_type: Optional[InputType] = Field(default="chat", description="The input type")
output_type: Optional[OutputType] = Field(default="chat", description="The output type")
output_component: Optional[str] = Field(
Expand Down
1 change: 1 addition & 0 deletions src/backend/base/langflow/components/inputs/ChatInput.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class ChatInput(ChatComponent):
display_name="Store Messages",
info="Store the message in the history.",
value=True,
advanced=True,
),
DropdownInput(
name="sender",
Expand Down
1 change: 1 addition & 0 deletions src/backend/base/langflow/components/outputs/ChatOutput.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class ChatOutput(ChatComponent):
display_name="Store Messages",
info="Store the message in the history.",
value=True,
advanced=True,
),
DropdownInput(
name="sender",
Expand Down
2 changes: 2 additions & 0 deletions src/backend/base/langflow/exceptions/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class InvalidChatInputException(Exception):
pass
21 changes: 21 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def pytest_configure(config):
pytest.CHAT_INPUT = data_path / "ChatInputTest.json"
pytest.TWO_OUTPUTS = data_path / "TwoOutputsTest.json"
pytest.VECTOR_STORE_PATH = data_path / "Vector_store.json"
pytest.SIMPLE_API_TEST = data_path / "SimpleAPITest.json"
pytest.CODE_WITH_SYNTAX_ERROR = """
def get_text():
retun "Hello World"
Expand Down Expand Up @@ -211,6 +212,12 @@ def json_flow_with_prompt_and_history():
return f.read()


@pytest.fixture
def json_simple_api_test():
with open(pytest.SIMPLE_API_TEST, "r") as f:
return f.read()


@pytest.fixture
def json_vector_store():
with open(pytest.VECTOR_STORE_PATH, "r") as f:
Expand Down Expand Up @@ -419,6 +426,20 @@ def created_api_key(active_user):
return api_key


@pytest.fixture(name="simple_api_test")
def get_simple_api_test(client, logged_in_headers, json_simple_api_test):
# Once the client is created, we can get the starter project
# Just create a new flow with the simple api test
flow = orjson.loads(json_simple_api_test)
data = flow["data"]
flow = FlowCreate(name="Simple API Test", data=data, description="Simple API Test")
response = client.post("api/v1/flows/", json=flow.model_dump(), headers=logged_in_headers)
assert response.status_code == 201
assert response.json()["name"] == flow.name
assert response.json()["data"] == flow.data
return response.json()


@pytest.fixture(name="starter_project")
def get_starter_project(active_user):
# once the client is created, we can get the starter project
Expand Down
Loading

0 comments on commit c47c358

Please sign in to comment.