Files
MoviePilot/app/schemas/workflow.py

239 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import Any, List, Optional
from pydantic import BaseModel, ConfigDict, Field
from app.schemas.common import JsonData
from app.schemas.context import Context, MediaInfo
from app.schemas.download import DownloadTask
from app.schemas.file import FileItem
from app.schemas.site import Site
from app.schemas.subscribe import Subscribe
class WorkflowExecutionConfig(BaseModel):
"""工作流调度器的执行参数。"""
max_workers: Optional[int] = Field(default=None, ge=1, description="最大并发动作数")
class WorkflowNodeState(BaseModel):
"""工作流单个动作的持久化执行状态。"""
state: Optional[str] = None
attempt: int = 0
started_at: Optional[str] = None
finished_at: Optional[str] = None
message: Optional[str] = None
class WorkflowRuntimeState(BaseModel):
"""工作流调度器的实时进度摘要。"""
progress: int = 0
finished_actions: int = 0
running_tasks: int = 0
errors: dict[str, str] = Field(default_factory=dict)
node_states: dict[str, str] = Field(default_factory=dict)
attempts: dict[str, int] = Field(default_factory=dict)
class WorkflowExecutionState(BaseModel):
"""可恢复的工作流结构化执行快照。"""
version: int = 1
nodes: dict[str, WorkflowNodeState] = Field(default_factory=dict)
outputs: dict[str, JsonData] = Field(default_factory=dict)
errors: dict[str, str] = Field(default_factory=dict)
runtime: WorkflowRuntimeState = Field(default_factory=WorkflowRuntimeState)
class ActionPosition(BaseModel):
"""工作流画布中的动作坐标。"""
x: float = 0
y: float = 0
class ActionRetry(BaseModel):
"""动作失败后的重试策略。"""
max_attempts: int = Field(default=1, ge=1)
interval: float = Field(default=0, ge=0)
backoff: float = Field(default=1, ge=1)
class Workflow(BaseModel):
"""
工作流信息
"""
id: Optional[int] = Field(default=None, description="工作流ID")
name: Optional[str] = Field(default=None, description="工作流名称")
description: Optional[str] = Field(default=None, description="工作流描述")
timer: Optional[str] = Field(default=None, description="定时器")
trigger_type: Optional[str] = Field(default='timer', description="触发类型timer-定时触发 event-事件触发 manual-手动触发")
event_type: Optional[str] = Field(default=None, description="事件类型当trigger_type为event时使用")
event_conditions: Optional[dict[str, JsonData]] = Field(default_factory=dict, description="事件条件JSON格式用于过滤事件")
state: Optional[str] = Field(default=None, description="状态")
current_action: Optional[str] = Field(default=None, description="已执行动作")
result: Optional[str] = Field(default=None, description="任务执行结果")
run_count: Optional[int] = Field(default=0, description="已执行次数")
actions: Optional[list["Action"]] = Field(default_factory=list, description="任务列表")
flows: Optional[list["ActionFlow"]] = Field(default_factory=list, description="任务流")
execution_config: Optional[WorkflowExecutionConfig] = Field(default_factory=WorkflowExecutionConfig, description="工作流执行配置")
execution_state: Optional[WorkflowExecutionState] = Field(default_factory=WorkflowExecutionState, description="工作流结构化执行状态")
add_time: Optional[str] = Field(default=None, description="创建时间")
last_time: Optional[str] = Field(default=None, description="最后执行时间")
model_config = ConfigDict(from_attributes=True)
class ActionParams(BaseModel):
"""
动作基础参数
"""
loop: Optional[bool] = Field(default=False, description="是否需要循环")
loop_interval: Optional[int] = Field(default=0, description="循环间隔 (秒)")
class Action(BaseModel):
"""
动作信息
"""
id: Optional[str] = Field(default=None, description="动作ID")
type: Optional[str] = Field(default=None, description="动作类型 (类名)")
name: Optional[str] = Field(default=None, description="动作名称")
description: Optional[str] = Field(default=None, description="动作描述")
position: Optional[ActionPosition] = Field(default_factory=ActionPosition, description="位置")
data: Optional[dict[str, JsonData]] = Field(default_factory=dict, description="参数")
inputs: Optional[List[str]] = Field(default_factory=list, description="动作输入声明")
outputs: Optional[dict[str, JsonData]] = Field(default_factory=dict, description="动作输出声明")
join_policy: Optional[str] = Field(default=None, description="多上游节点汇合策略")
fail_policy: Optional[str] = Field(default=None, description="动作失败后的工作流处理策略")
branch_policy: Optional[str] = Field(default=None, description="多出边分支策略")
concurrency_key: Optional[str] = Field(default=None, description="并发互斥键")
timeout: Optional[int] = Field(default=None, description="动作执行超时时间(秒)")
retry: Optional[ActionRetry] = Field(default=None, description="动作重试策略")
class ActionExecution(BaseModel):
"""
动作执行情况
"""
action: Optional[str] = Field(default=None, description="当前动作(名称)")
result: Optional[bool] = Field(default=None, description="执行结果")
message: Optional[str] = Field(default=None, description="执行消息")
class ActionContext(BaseModel):
"""
动作基础上下文,各动作通用数据
"""
content: Optional[str] = Field(default=None, description="文本类内容")
torrents: Optional[List[Context]] = Field(default_factory=list, description="资源列表")
medias: Optional[List[MediaInfo]] = Field(default_factory=list, description="媒体列表")
fileitems: Optional[List[FileItem]] = Field(default_factory=list, description="文件列表")
downloads: Optional[List[DownloadTask]] = Field(default_factory=list, description="下载任务列表")
sites: Optional[List[Site]] = Field(default_factory=list, description="站点列表")
subscribes: Optional[List[Subscribe]] = Field(default_factory=list, description="订阅列表")
workflow_context: Optional[dict[str, JsonData]] = Field(default_factory=dict, description="工作流全局上下文")
node_outputs: Optional[dict[str, JsonData]] = Field(default_factory=dict, description="节点输出数据")
runtime_state: Optional[dict[str, JsonData]] = Field(default_factory=dict, description="运行期状态")
artifacts: Optional[dict[str, JsonData]] = Field(default_factory=dict, description="大对象引用与产物数据")
execute_history: Optional[List[ActionExecution]] = Field(default_factory=list, description="执行历史")
progress: Optional[int] = Field(default=0, description="执行进度(%")
class ActionResult(BaseModel):
"""
动作执行结果。
"""
success: Optional[bool] = Field(default=True, description="动作是否执行成功")
message: Optional[str] = Field(default=None, description="动作执行消息")
context: Optional[ActionContext] = Field(default=None, description="动作执行后的上下文")
# 动作内部可暂存待序列化对象API 输出前由工作流序列化器转为 JsonData。
outputs: Optional[dict[str, Any]] = Field(default_factory=dict, description="当前节点显式输出")
next_policy: Optional[str] = Field(default=None, description="动作完成后的调度策略")
attempts: Optional[int] = Field(default=1, description="动作实际尝试次数")
class ActionFlow(BaseModel):
"""
工作流流程
"""
id: Optional[str] = Field(default=None, description="流程ID")
source: Optional[str] = Field(default=None, description="源动作")
target: Optional[str] = Field(default=None, description="目标动作")
animated: Optional[bool] = Field(default=True, description="是否动画流程")
data: Optional[dict[str, JsonData]] = Field(default_factory=dict, description="流程扩展配置")
condition: Optional[str] = Field(default=None, description="流转条件表达式")
join_policy: Optional[str] = Field(default=None, description="目标节点汇合策略")
branch_policy: Optional[str] = Field(default=None, description="源节点分支策略")
class WorkflowShare(BaseModel):
"""
工作流分享信息
"""
id: Optional[int] = Field(default=None, description="分享ID")
share_title: Optional[str] = Field(default=None, description="分享标题")
share_comment: Optional[str] = Field(default=None, description="分享说明")
share_user: Optional[str] = Field(default=None, description="分享人")
share_uid: Optional[str] = Field(default=None, description="分享人唯一ID")
name: Optional[str] = Field(default=None, description="工作流名称")
description: Optional[str] = Field(default=None, description="工作流描述")
timer: Optional[str] = Field(default=None, description="定时器")
trigger_type: Optional[str] = Field(default=None, description="触发类型")
event_type: Optional[str] = Field(default=None, description="事件类型")
event_conditions: Optional[str] = Field(default=None, description="事件条件")
actions: Optional[str] = Field(default=None, description="任务列表(JSON字符串)")
flows: Optional[str] = Field(default=None, description="任务流(JSON字符串)")
context: Optional[str] = Field(default=None, description="执行上下文(JSON字符串)")
date: Optional[str] = Field(default=None, description="分享时间")
count: Optional[int] = Field(default=0, description="复用人次")
model_config = ConfigDict(from_attributes=True)
class PluginWorkflowActionGroup(BaseModel):
"""单个插件声明的工作流动作组。"""
plugin_id: str
plugin_name: str
actions: list[dict[str, JsonData]] = Field(default_factory=list)
class ActionContractField(BaseModel):
"""动作契约中的单个输入或输出字段。"""
name: str
label: str
kind: str = "scalar"
merge: Optional[str] = None
identity: Optional[str] = None
class ActionContract(BaseModel):
"""工作流动作对编辑器公开的输入输出契约。"""
inputs: list[ActionContractField] = Field(default_factory=list)
outputs: list[ActionContractField] = Field(default_factory=list)
condition_fields: list[ActionContractField] = Field(default_factory=list)
concurrency_key: Optional[str] = None
class WorkflowActionDefinition(BaseModel):
"""可用于工作流编辑器的动作定义。"""
type: str
name: str
description: Optional[str] = None
contract: ActionContract = Field(default_factory=ActionContract)
data: dict[str, JsonData] = Field(default_factory=dict)
class NameValueOption(BaseModel):
"""前端选项的显示文本和值。"""
title: str
value: str