chore(api/core): apply ruff reformatting (#7624)
This commit is contained in:
@@ -25,11 +25,10 @@ class CodeNode(BaseNode):
|
||||
"""
|
||||
code_language = CodeLanguage.PYTHON3
|
||||
if filters:
|
||||
code_language = (filters.get("code_language", CodeLanguage.PYTHON3))
|
||||
code_language = filters.get("code_language", CodeLanguage.PYTHON3)
|
||||
|
||||
providers: list[type[CodeNodeProvider]] = [Python3CodeProvider, JavascriptCodeProvider]
|
||||
code_provider: type[CodeNodeProvider] = next(p for p in providers
|
||||
if p.is_accept_language(code_language))
|
||||
code_provider: type[CodeNodeProvider] = next(p for p in providers if p.is_accept_language(code_language))
|
||||
|
||||
return code_provider.get_default_config()
|
||||
|
||||
@@ -63,17 +62,9 @@ class CodeNode(BaseNode):
|
||||
# Transform result
|
||||
result = self._transform_result(result, node_data.outputs)
|
||||
except (CodeExecutionException, ValueError) as e:
|
||||
return NodeRunResult(
|
||||
status=WorkflowNodeExecutionStatus.FAILED,
|
||||
inputs=variables,
|
||||
error=str(e)
|
||||
)
|
||||
return NodeRunResult(status=WorkflowNodeExecutionStatus.FAILED, inputs=variables, error=str(e))
|
||||
|
||||
return NodeRunResult(
|
||||
status=WorkflowNodeExecutionStatus.SUCCEEDED,
|
||||
inputs=variables,
|
||||
outputs=result
|
||||
)
|
||||
return NodeRunResult(status=WorkflowNodeExecutionStatus.SUCCEEDED, inputs=variables, outputs=result)
|
||||
|
||||
def _check_string(self, value: str, variable: str) -> str:
|
||||
"""
|
||||
@@ -87,12 +78,14 @@ class CodeNode(BaseNode):
|
||||
return None
|
||||
else:
|
||||
raise ValueError(f"Output variable `{variable}` must be a string")
|
||||
|
||||
if len(value) > dify_config.CODE_MAX_STRING_LENGTH:
|
||||
raise ValueError(f'The length of output variable `{variable}` must be'
|
||||
f' less than {dify_config.CODE_MAX_STRING_LENGTH} characters')
|
||||
|
||||
return value.replace('\x00', '')
|
||||
if len(value) > dify_config.CODE_MAX_STRING_LENGTH:
|
||||
raise ValueError(
|
||||
f"The length of output variable `{variable}` must be"
|
||||
f" less than {dify_config.CODE_MAX_STRING_LENGTH} characters"
|
||||
)
|
||||
|
||||
return value.replace("\x00", "")
|
||||
|
||||
def _check_number(self, value: Union[int, float], variable: str) -> Union[int, float]:
|
||||
"""
|
||||
@@ -108,20 +101,24 @@ class CodeNode(BaseNode):
|
||||
raise ValueError(f"Output variable `{variable}` must be a number")
|
||||
|
||||
if value > dify_config.CODE_MAX_NUMBER or value < dify_config.CODE_MIN_NUMBER:
|
||||
raise ValueError(f'Output variable `{variable}` is out of range,'
|
||||
f' it must be between {dify_config.CODE_MIN_NUMBER} and {dify_config.CODE_MAX_NUMBER}.')
|
||||
raise ValueError(
|
||||
f"Output variable `{variable}` is out of range,"
|
||||
f" it must be between {dify_config.CODE_MIN_NUMBER} and {dify_config.CODE_MAX_NUMBER}."
|
||||
)
|
||||
|
||||
if isinstance(value, float):
|
||||
# raise error if precision is too high
|
||||
if len(str(value).split('.')[1]) > dify_config.CODE_MAX_PRECISION:
|
||||
raise ValueError(f'Output variable `{variable}` has too high precision,'
|
||||
f' it must be less than {dify_config.CODE_MAX_PRECISION} digits.')
|
||||
if len(str(value).split(".")[1]) > dify_config.CODE_MAX_PRECISION:
|
||||
raise ValueError(
|
||||
f"Output variable `{variable}` has too high precision,"
|
||||
f" it must be less than {dify_config.CODE_MAX_PRECISION} digits."
|
||||
)
|
||||
|
||||
return value
|
||||
|
||||
def _transform_result(self, result: dict, output_schema: Optional[dict[str, CodeNodeData.Output]],
|
||||
prefix: str = '',
|
||||
depth: int = 1) -> dict:
|
||||
def _transform_result(
|
||||
self, result: dict, output_schema: Optional[dict[str, CodeNodeData.Output]], prefix: str = "", depth: int = 1
|
||||
) -> dict:
|
||||
"""
|
||||
Transform result
|
||||
:param result: result
|
||||
@@ -139,183 +136,181 @@ class CodeNode(BaseNode):
|
||||
self._transform_result(
|
||||
result=output_value,
|
||||
output_schema=None,
|
||||
prefix=f'{prefix}.{output_name}' if prefix else output_name,
|
||||
depth=depth + 1
|
||||
prefix=f"{prefix}.{output_name}" if prefix else output_name,
|
||||
depth=depth + 1,
|
||||
)
|
||||
elif isinstance(output_value, int | float):
|
||||
self._check_number(
|
||||
value=output_value,
|
||||
variable=f'{prefix}.{output_name}' if prefix else output_name
|
||||
value=output_value, variable=f"{prefix}.{output_name}" if prefix else output_name
|
||||
)
|
||||
elif isinstance(output_value, str):
|
||||
self._check_string(
|
||||
value=output_value,
|
||||
variable=f'{prefix}.{output_name}' if prefix else output_name
|
||||
value=output_value, variable=f"{prefix}.{output_name}" if prefix else output_name
|
||||
)
|
||||
elif isinstance(output_value, list):
|
||||
first_element = output_value[0] if len(output_value) > 0 else None
|
||||
if first_element is not None:
|
||||
if isinstance(first_element, int | float) and all(value is None or isinstance(value, int | float) for value in output_value):
|
||||
if isinstance(first_element, int | float) and all(
|
||||
value is None or isinstance(value, int | float) for value in output_value
|
||||
):
|
||||
for i, value in enumerate(output_value):
|
||||
self._check_number(
|
||||
value=value,
|
||||
variable=f'{prefix}.{output_name}[{i}]' if prefix else f'{output_name}[{i}]'
|
||||
variable=f"{prefix}.{output_name}[{i}]" if prefix else f"{output_name}[{i}]",
|
||||
)
|
||||
elif isinstance(first_element, str) and all(value is None or isinstance(value, str) for value in output_value):
|
||||
elif isinstance(first_element, str) and all(
|
||||
value is None or isinstance(value, str) for value in output_value
|
||||
):
|
||||
for i, value in enumerate(output_value):
|
||||
self._check_string(
|
||||
value=value,
|
||||
variable=f'{prefix}.{output_name}[{i}]' if prefix else f'{output_name}[{i}]'
|
||||
variable=f"{prefix}.{output_name}[{i}]" if prefix else f"{output_name}[{i}]",
|
||||
)
|
||||
elif isinstance(first_element, dict) and all(value is None or isinstance(value, dict) for value in output_value):
|
||||
elif isinstance(first_element, dict) and all(
|
||||
value is None or isinstance(value, dict) for value in output_value
|
||||
):
|
||||
for i, value in enumerate(output_value):
|
||||
if value is not None:
|
||||
self._transform_result(
|
||||
result=value,
|
||||
output_schema=None,
|
||||
prefix=f'{prefix}.{output_name}[{i}]' if prefix else f'{output_name}[{i}]',
|
||||
depth=depth + 1
|
||||
prefix=f"{prefix}.{output_name}[{i}]" if prefix else f"{output_name}[{i}]",
|
||||
depth=depth + 1,
|
||||
)
|
||||
else:
|
||||
raise ValueError(f'Output {prefix}.{output_name} is not a valid array. make sure all elements are of the same type.')
|
||||
raise ValueError(
|
||||
f"Output {prefix}.{output_name} is not a valid array. make sure all elements are of the same type."
|
||||
)
|
||||
elif isinstance(output_value, type(None)):
|
||||
pass
|
||||
else:
|
||||
raise ValueError(f'Output {prefix}.{output_name} is not a valid type.')
|
||||
|
||||
raise ValueError(f"Output {prefix}.{output_name} is not a valid type.")
|
||||
|
||||
return result
|
||||
|
||||
parameters_validated = {}
|
||||
for output_name, output_config in output_schema.items():
|
||||
dot = '.' if prefix else ''
|
||||
dot = "." if prefix else ""
|
||||
if output_name not in result:
|
||||
raise ValueError(f'Output {prefix}{dot}{output_name} is missing.')
|
||||
|
||||
if output_config.type == 'object':
|
||||
raise ValueError(f"Output {prefix}{dot}{output_name} is missing.")
|
||||
|
||||
if output_config.type == "object":
|
||||
# check if output is object
|
||||
if not isinstance(result.get(output_name), dict):
|
||||
if isinstance(result.get(output_name), type(None)):
|
||||
transformed_result[output_name] = None
|
||||
else:
|
||||
raise ValueError(
|
||||
f'Output {prefix}{dot}{output_name} is not an object, got {type(result.get(output_name))} instead.'
|
||||
f"Output {prefix}{dot}{output_name} is not an object, got {type(result.get(output_name))} instead."
|
||||
)
|
||||
else:
|
||||
transformed_result[output_name] = self._transform_result(
|
||||
result=result[output_name],
|
||||
output_schema=output_config.children,
|
||||
prefix=f'{prefix}.{output_name}',
|
||||
depth=depth + 1
|
||||
prefix=f"{prefix}.{output_name}",
|
||||
depth=depth + 1,
|
||||
)
|
||||
elif output_config.type == 'number':
|
||||
elif output_config.type == "number":
|
||||
# check if number available
|
||||
transformed_result[output_name] = self._check_number(
|
||||
value=result[output_name],
|
||||
variable=f'{prefix}{dot}{output_name}'
|
||||
value=result[output_name], variable=f"{prefix}{dot}{output_name}"
|
||||
)
|
||||
elif output_config.type == 'string':
|
||||
elif output_config.type == "string":
|
||||
# check if string available
|
||||
transformed_result[output_name] = self._check_string(
|
||||
value=result[output_name],
|
||||
variable=f'{prefix}{dot}{output_name}',
|
||||
variable=f"{prefix}{dot}{output_name}",
|
||||
)
|
||||
elif output_config.type == 'array[number]':
|
||||
elif output_config.type == "array[number]":
|
||||
# check if array of number available
|
||||
if not isinstance(result[output_name], list):
|
||||
if isinstance(result[output_name], type(None)):
|
||||
transformed_result[output_name] = None
|
||||
else:
|
||||
raise ValueError(
|
||||
f'Output {prefix}{dot}{output_name} is not an array, got {type(result.get(output_name))} instead.'
|
||||
f"Output {prefix}{dot}{output_name} is not an array, got {type(result.get(output_name))} instead."
|
||||
)
|
||||
else:
|
||||
if len(result[output_name]) > dify_config.CODE_MAX_NUMBER_ARRAY_LENGTH:
|
||||
raise ValueError(
|
||||
f'The length of output variable `{prefix}{dot}{output_name}` must be'
|
||||
f' less than {dify_config.CODE_MAX_NUMBER_ARRAY_LENGTH} elements.'
|
||||
f"The length of output variable `{prefix}{dot}{output_name}` must be"
|
||||
f" less than {dify_config.CODE_MAX_NUMBER_ARRAY_LENGTH} elements."
|
||||
)
|
||||
|
||||
transformed_result[output_name] = [
|
||||
self._check_number(
|
||||
value=value,
|
||||
variable=f'{prefix}{dot}{output_name}[{i}]'
|
||||
)
|
||||
self._check_number(value=value, variable=f"{prefix}{dot}{output_name}[{i}]")
|
||||
for i, value in enumerate(result[output_name])
|
||||
]
|
||||
elif output_config.type == 'array[string]':
|
||||
elif output_config.type == "array[string]":
|
||||
# check if array of string available
|
||||
if not isinstance(result[output_name], list):
|
||||
if isinstance(result[output_name], type(None)):
|
||||
transformed_result[output_name] = None
|
||||
else:
|
||||
raise ValueError(
|
||||
f'Output {prefix}{dot}{output_name} is not an array, got {type(result.get(output_name))} instead.'
|
||||
f"Output {prefix}{dot}{output_name} is not an array, got {type(result.get(output_name))} instead."
|
||||
)
|
||||
else:
|
||||
if len(result[output_name]) > dify_config.CODE_MAX_STRING_ARRAY_LENGTH:
|
||||
raise ValueError(
|
||||
f'The length of output variable `{prefix}{dot}{output_name}` must be'
|
||||
f' less than {dify_config.CODE_MAX_STRING_ARRAY_LENGTH} elements.'
|
||||
f"The length of output variable `{prefix}{dot}{output_name}` must be"
|
||||
f" less than {dify_config.CODE_MAX_STRING_ARRAY_LENGTH} elements."
|
||||
)
|
||||
|
||||
transformed_result[output_name] = [
|
||||
self._check_string(
|
||||
value=value,
|
||||
variable=f'{prefix}{dot}{output_name}[{i}]'
|
||||
)
|
||||
self._check_string(value=value, variable=f"{prefix}{dot}{output_name}[{i}]")
|
||||
for i, value in enumerate(result[output_name])
|
||||
]
|
||||
elif output_config.type == 'array[object]':
|
||||
elif output_config.type == "array[object]":
|
||||
# check if array of object available
|
||||
if not isinstance(result[output_name], list):
|
||||
if isinstance(result[output_name], type(None)):
|
||||
transformed_result[output_name] = None
|
||||
else:
|
||||
raise ValueError(
|
||||
f'Output {prefix}{dot}{output_name} is not an array, got {type(result.get(output_name))} instead.'
|
||||
f"Output {prefix}{dot}{output_name} is not an array, got {type(result.get(output_name))} instead."
|
||||
)
|
||||
else:
|
||||
if len(result[output_name]) > dify_config.CODE_MAX_OBJECT_ARRAY_LENGTH:
|
||||
raise ValueError(
|
||||
f'The length of output variable `{prefix}{dot}{output_name}` must be'
|
||||
f' less than {dify_config.CODE_MAX_OBJECT_ARRAY_LENGTH} elements.'
|
||||
f"The length of output variable `{prefix}{dot}{output_name}` must be"
|
||||
f" less than {dify_config.CODE_MAX_OBJECT_ARRAY_LENGTH} elements."
|
||||
)
|
||||
|
||||
|
||||
for i, value in enumerate(result[output_name]):
|
||||
if not isinstance(value, dict):
|
||||
if isinstance(value, type(None)):
|
||||
pass
|
||||
else:
|
||||
raise ValueError(
|
||||
f'Output {prefix}{dot}{output_name}[{i}] is not an object, got {type(value)} instead at index {i}.'
|
||||
f"Output {prefix}{dot}{output_name}[{i}] is not an object, got {type(value)} instead at index {i}."
|
||||
)
|
||||
|
||||
transformed_result[output_name] = [
|
||||
None if value is None else self._transform_result(
|
||||
None
|
||||
if value is None
|
||||
else self._transform_result(
|
||||
result=value,
|
||||
output_schema=output_config.children,
|
||||
prefix=f'{prefix}{dot}{output_name}[{i}]',
|
||||
depth=depth + 1
|
||||
prefix=f"{prefix}{dot}{output_name}[{i}]",
|
||||
depth=depth + 1,
|
||||
)
|
||||
for i, value in enumerate(result[output_name])
|
||||
]
|
||||
else:
|
||||
raise ValueError(f'Output type {output_config.type} is not supported.')
|
||||
|
||||
raise ValueError(f"Output type {output_config.type} is not supported.")
|
||||
|
||||
parameters_validated[output_name] = True
|
||||
|
||||
# check if all output parameters are validated
|
||||
if len(parameters_validated) != len(result):
|
||||
raise ValueError('Not all output parameters are validated.')
|
||||
raise ValueError("Not all output parameters are validated.")
|
||||
|
||||
return transformed_result
|
||||
|
||||
@classmethod
|
||||
def _extract_variable_selector_to_variable_mapping(
|
||||
cls,
|
||||
graph_config: Mapping[str, Any],
|
||||
node_id: str,
|
||||
node_data: CodeNodeData
|
||||
cls, graph_config: Mapping[str, Any], node_id: str, node_data: CodeNodeData
|
||||
) -> Mapping[str, Sequence[str]]:
|
||||
"""
|
||||
Extract variable selector to variable mapping
|
||||
@@ -325,5 +320,6 @@ class CodeNode(BaseNode):
|
||||
:return:
|
||||
"""
|
||||
return {
|
||||
node_id + '.' + variable_selector.variable: variable_selector.value_selector for variable_selector in node_data.variables
|
||||
node_id + "." + variable_selector.variable: variable_selector.value_selector
|
||||
for variable_selector in node_data.variables
|
||||
}
|
||||
|
@@ -11,9 +11,10 @@ class CodeNodeData(BaseNodeData):
|
||||
"""
|
||||
Code Node Data.
|
||||
"""
|
||||
|
||||
class Output(BaseModel):
|
||||
type: Literal['string', 'number', 'object', 'array[string]', 'array[number]', 'array[object]']
|
||||
children: Optional[dict[str, 'Output']] = None
|
||||
type: Literal["string", "number", "object", "array[string]", "array[number]", "array[object]"]
|
||||
children: Optional[dict[str, "Output"]] = None
|
||||
|
||||
class Dependency(BaseModel):
|
||||
name: str
|
||||
@@ -23,4 +24,4 @@ class CodeNodeData(BaseNodeData):
|
||||
code_language: Literal[CodeLanguage.PYTHON3, CodeLanguage.JAVASCRIPT]
|
||||
code: str
|
||||
outputs: dict[str, Output]
|
||||
dependencies: Optional[list[Dependency]] = None
|
||||
dependencies: Optional[list[Dependency]] = None
|
||||
|
Reference in New Issue
Block a user