mirror of
https://github.com/langgenius/dify.git
synced 2024-11-16 19:59:50 +08:00
fix(validation): allow to use 0 in the inputs form (#10255)
This commit is contained in:
parent
c2b4845719
commit
84c35aef6c
|
@ -22,7 +22,10 @@ class BaseAppGenerator:
|
||||||
user_inputs = user_inputs or {}
|
user_inputs = user_inputs or {}
|
||||||
# Filter input variables from form configuration, handle required fields, default values, and option values
|
# Filter input variables from form configuration, handle required fields, default values, and option values
|
||||||
variables = app_config.variables
|
variables = app_config.variables
|
||||||
user_inputs = {var.variable: self._validate_input(inputs=user_inputs, var=var) for var in variables}
|
user_inputs = {
|
||||||
|
var.variable: self._validate_inputs(value=user_inputs.get(var.variable), variable_entity=var)
|
||||||
|
for var in variables
|
||||||
|
}
|
||||||
user_inputs = {k: self._sanitize_value(v) for k, v in user_inputs.items()}
|
user_inputs = {k: self._sanitize_value(v) for k, v in user_inputs.items()}
|
||||||
# Convert files in inputs to File
|
# Convert files in inputs to File
|
||||||
entity_dictionary = {item.variable: item for item in app_config.variables}
|
entity_dictionary = {item.variable: item for item in app_config.variables}
|
||||||
|
@ -74,57 +77,66 @@ class BaseAppGenerator:
|
||||||
|
|
||||||
return user_inputs
|
return user_inputs
|
||||||
|
|
||||||
def _validate_input(self, *, inputs: Mapping[str, Any], var: "VariableEntity"):
|
def _validate_inputs(
|
||||||
user_input_value = inputs.get(var.variable)
|
self,
|
||||||
|
*,
|
||||||
|
variable_entity: "VariableEntity",
|
||||||
|
value: Any,
|
||||||
|
):
|
||||||
|
if value is None:
|
||||||
|
if variable_entity.required:
|
||||||
|
raise ValueError(f"{variable_entity.variable} is required in input form")
|
||||||
|
return value
|
||||||
|
|
||||||
if not user_input_value:
|
if variable_entity.type in {
|
||||||
if var.required:
|
|
||||||
raise ValueError(f"{var.variable} is required in input form")
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if var.type in {
|
|
||||||
VariableEntityType.TEXT_INPUT,
|
VariableEntityType.TEXT_INPUT,
|
||||||
VariableEntityType.SELECT,
|
VariableEntityType.SELECT,
|
||||||
VariableEntityType.PARAGRAPH,
|
VariableEntityType.PARAGRAPH,
|
||||||
} and not isinstance(user_input_value, str):
|
} and not isinstance(value, str):
|
||||||
raise ValueError(f"(type '{var.type}') {var.variable} in input form must be a string")
|
raise ValueError(
|
||||||
|
f"(type '{variable_entity.type}') {variable_entity.variable} in input form must be a string"
|
||||||
|
)
|
||||||
|
|
||||||
if var.type == VariableEntityType.NUMBER and isinstance(user_input_value, str):
|
if variable_entity.type == VariableEntityType.NUMBER and isinstance(value, str):
|
||||||
# may raise ValueError if user_input_value is not a valid number
|
# may raise ValueError if user_input_value is not a valid number
|
||||||
try:
|
try:
|
||||||
if "." in user_input_value:
|
if "." in value:
|
||||||
return float(user_input_value)
|
return float(value)
|
||||||
else:
|
else:
|
||||||
return int(user_input_value)
|
return int(value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValueError(f"{var.variable} in input form must be a valid number")
|
raise ValueError(f"{variable_entity.variable} in input form must be a valid number")
|
||||||
|
|
||||||
match var.type:
|
match variable_entity.type:
|
||||||
case VariableEntityType.SELECT:
|
case VariableEntityType.SELECT:
|
||||||
if user_input_value not in var.options:
|
if value not in variable_entity.options:
|
||||||
raise ValueError(f"{var.variable} in input form must be one of the following: {var.options}")
|
raise ValueError(
|
||||||
|
f"{variable_entity.variable} in input form must be one of the following: "
|
||||||
|
f"{variable_entity.options}"
|
||||||
|
)
|
||||||
case VariableEntityType.TEXT_INPUT | VariableEntityType.PARAGRAPH:
|
case VariableEntityType.TEXT_INPUT | VariableEntityType.PARAGRAPH:
|
||||||
if var.max_length and len(user_input_value) > var.max_length:
|
if variable_entity.max_length and len(value) > variable_entity.max_length:
|
||||||
raise ValueError(f"{var.variable} in input form must be less than {var.max_length} characters")
|
raise ValueError(
|
||||||
|
f"{variable_entity.variable} in input form must be less than {variable_entity.max_length} "
|
||||||
|
"characters"
|
||||||
|
)
|
||||||
case VariableEntityType.FILE:
|
case VariableEntityType.FILE:
|
||||||
if not isinstance(user_input_value, dict) and not isinstance(user_input_value, File):
|
if not isinstance(value, dict) and not isinstance(value, File):
|
||||||
raise ValueError(f"{var.variable} in input form must be a file")
|
raise ValueError(f"{variable_entity.variable} in input form must be a file")
|
||||||
case VariableEntityType.FILE_LIST:
|
case VariableEntityType.FILE_LIST:
|
||||||
# if number of files exceeds the limit, raise ValueError
|
# if number of files exceeds the limit, raise ValueError
|
||||||
if not (
|
if not (
|
||||||
isinstance(user_input_value, list)
|
isinstance(value, list)
|
||||||
and (
|
and (all(isinstance(item, dict) for item in value) or all(isinstance(item, File) for item in value))
|
||||||
all(isinstance(item, dict) for item in user_input_value)
|
|
||||||
or all(isinstance(item, File) for item in user_input_value)
|
|
||||||
)
|
|
||||||
):
|
):
|
||||||
raise ValueError(f"{var.variable} in input form must be a list of files")
|
raise ValueError(f"{variable_entity.variable} in input form must be a list of files")
|
||||||
|
|
||||||
if var.max_length and len(user_input_value) > var.max_length:
|
if variable_entity.max_length and len(value) > variable_entity.max_length:
|
||||||
raise ValueError(f"{var.variable} in input form must be less than {var.max_length} files")
|
raise ValueError(
|
||||||
|
f"{variable_entity.variable} in input form must be less than {variable_entity.max_length} files"
|
||||||
|
)
|
||||||
|
|
||||||
return user_input_value
|
return value
|
||||||
|
|
||||||
def _sanitize_value(self, value: Any) -> Any:
|
def _sanitize_value(self, value: Any) -> Any:
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from core.app.app_config.entities import VariableEntity, VariableEntityType
|
||||||
|
from core.app.apps.base_app_generator import BaseAppGenerator
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_inputs_with_zero():
|
||||||
|
base_app_generator = BaseAppGenerator()
|
||||||
|
|
||||||
|
var = VariableEntity(
|
||||||
|
variable="test_var",
|
||||||
|
label="test_var",
|
||||||
|
type=VariableEntityType.NUMBER,
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test with input 0
|
||||||
|
result = base_app_generator._validate_inputs(
|
||||||
|
variable_entity=var,
|
||||||
|
value=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result == 0
|
||||||
|
|
||||||
|
# Test with input "0" (string)
|
||||||
|
result = base_app_generator._validate_inputs(
|
||||||
|
variable_entity=var,
|
||||||
|
value="0",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_input_with_none_for_required_variable():
|
||||||
|
base_app_generator = BaseAppGenerator()
|
||||||
|
|
||||||
|
for var_type in VariableEntityType:
|
||||||
|
var = VariableEntity(
|
||||||
|
variable="test_var",
|
||||||
|
label="test_var",
|
||||||
|
type=var_type,
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test with input None
|
||||||
|
with pytest.raises(ValueError) as exc_info:
|
||||||
|
base_app_generator._validate_inputs(
|
||||||
|
variable_entity=var,
|
||||||
|
value=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert str(exc_info.value) == "test_var is required in input form"
|
Loading…
Reference in New Issue
Block a user