mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
refactor(api): migrate remaining RESTX models to Pydantic (#40399)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Byron Wang <byron@dify.ai>
This commit is contained in:
17 files changed
+768
-665
No files matched your search
@@ -0,0 +1,137 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, override
|
||||
|
||||
from pydantic import model_validator
|
||||
|
||||
from fields.base import ResponseModel
|
||||
from graphon.file import helpers as file_helpers
|
||||
from graphon.variables.segment_group import SegmentGroup
|
||||
from graphon.variables.segments import ArrayFileSegment, FileSegment, Segment
|
||||
from models.workflow import WorkflowDraftVariable
|
||||
|
||||
type JSONValue = str | int | float | bool | dict[str, "JSONValue"] | list["JSONValue"] | None
|
||||
|
||||
|
||||
def _convert_values_to_json_serializable_object(value: Segment) -> JSONValue:
|
||||
match value:
|
||||
case FileSegment():
|
||||
return value.value.model_dump()
|
||||
case ArrayFileSegment():
|
||||
return [item.model_dump() for item in value.value]
|
||||
case SegmentGroup():
|
||||
return [_convert_values_to_json_serializable_object(item) for item in value.value]
|
||||
case _:
|
||||
return value.value
|
||||
|
||||
|
||||
def _serialize_var_value(variable: WorkflowDraftVariable) -> JSONValue:
|
||||
value = variable.get_value()
|
||||
# Create a copy to avoid mutating the model's cached deserialized value.
|
||||
value = value.model_copy(deep=True)
|
||||
# Refresh URL signatures immediately before returning file values to the client.
|
||||
match value:
|
||||
case FileSegment():
|
||||
value.value.remote_url = value.value.generate_url()
|
||||
case ArrayFileSegment():
|
||||
for file in value.value:
|
||||
file.remote_url = file.generate_url()
|
||||
return _convert_values_to_json_serializable_object(value)
|
||||
|
||||
|
||||
class WorkflowDraftVariableFullContentResponse(ResponseModel):
|
||||
size_bytes: int | None
|
||||
value_type: str
|
||||
length: int | None
|
||||
download_url: str
|
||||
|
||||
|
||||
def _serialize_full_content(
|
||||
variable: WorkflowDraftVariable,
|
||||
) -> WorkflowDraftVariableFullContentResponse | None:
|
||||
"""Serialize metadata for a variable whose complete value was offloaded."""
|
||||
if not variable.is_truncated():
|
||||
return None
|
||||
|
||||
variable_file = variable.variable_file
|
||||
assert variable_file is not None
|
||||
|
||||
return WorkflowDraftVariableFullContentResponse(
|
||||
size_bytes=variable_file.size,
|
||||
value_type=str(variable_file.value_type.exposed_type()),
|
||||
length=variable_file.length,
|
||||
download_url=file_helpers.get_signed_file_url(variable_file.upload_file_id, as_attachment=True),
|
||||
)
|
||||
|
||||
|
||||
def _serialize_without_value(variable: WorkflowDraftVariable) -> dict[str, Any]:
|
||||
return {
|
||||
"id": variable.id,
|
||||
"type": str(variable.get_variable_type()),
|
||||
"name": variable.name,
|
||||
"description": variable.description,
|
||||
"selector": variable.get_selector(),
|
||||
"value_type": str(variable.value_type.exposed_type()),
|
||||
"edited": variable.edited,
|
||||
"visible": variable.visible,
|
||||
"is_truncated": variable.is_truncated(),
|
||||
}
|
||||
|
||||
|
||||
class WorkflowDraftVariableWithoutValueResponse(ResponseModel):
|
||||
id: str
|
||||
type: str
|
||||
name: str
|
||||
description: str
|
||||
selector: list[str]
|
||||
value_type: str
|
||||
edited: bool
|
||||
visible: bool
|
||||
is_truncated: bool
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def _from_workflow_draft_variable(cls, value: Any) -> Any:
|
||||
if isinstance(value, WorkflowDraftVariable):
|
||||
return _serialize_without_value(value)
|
||||
return value
|
||||
|
||||
|
||||
class WorkflowDraftVariableResponse(WorkflowDraftVariableWithoutValueResponse):
|
||||
value: JSONValue
|
||||
full_content: WorkflowDraftVariableFullContentResponse | None
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
@override
|
||||
def _from_workflow_draft_variable(cls, value: Any) -> Any:
|
||||
if isinstance(value, WorkflowDraftVariable):
|
||||
return {
|
||||
**_serialize_without_value(value),
|
||||
"value": _serialize_var_value(value),
|
||||
"full_content": _serialize_full_content(value),
|
||||
}
|
||||
return value
|
||||
|
||||
|
||||
class WorkflowDraftVariableListWithoutValueResponse(ResponseModel):
|
||||
items: list[WorkflowDraftVariableWithoutValueResponse]
|
||||
total: int | None
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def _from_workflow_draft_variable_list(cls, value: Any) -> Any:
|
||||
if hasattr(value, "variables") and hasattr(value, "total"):
|
||||
return {"items": value.variables, "total": value.total}
|
||||
return value
|
||||
|
||||
|
||||
class WorkflowDraftVariableListResponse(ResponseModel):
|
||||
items: list[WorkflowDraftVariableResponse]
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def _from_workflow_draft_variable_list(cls, value: Any) -> Any:
|
||||
if hasattr(value, "variables"):
|
||||
return {"items": value.variables}
|
||||
return value
|
||||
Reference in new issue
Block a user