#!/usr/bin/env python # -*- coding: utf-8 -*- """ 块处理器基类模块 提供所有块处理器的基类和注册功能 """ from abc import ABC, abstractmethod from typing import Dict, List, Any, Optional, Type, Callable import json import logging # 获取日志记录器 logger = logging.getLogger(__name__) # 块处理器注册表 _block_handlers = {} class BlockHandler(ABC): """ 块处理器抽象基类 所有具体的块处理器都应该继承这个类 """ @abstractmethod async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: Any # TaskContext类型,避免循环导入 ) -> Dict[str, Any]: """ 执行块 Args: block: 块定义 input_params: 解析后的输入参数 context: 任务上下文 Returns: Dict[str, Any]: 执行结果,必须包含success字段 """ pass async def _record_task_log( self, block: Dict[str, Any], result: Dict[str, Any], context: Any # TaskContext类型,避免循环导入 ) -> None: """ 记录任务日志 Args: block: 块定义 result: 执行结果 context: 任务上下文 """ from sqlalchemy import insert from data.models.tasklog import VWEDTaskLog from data.session import get_async_session import uuid from datetime import datetime try: # 创建任务日志记录 task_log_id = str(uuid.uuid4()) # 自定义JSON序列化器,处理datetime对象和bytes对象 def json_serializer(obj): if isinstance(obj, datetime): return obj.isoformat() if isinstance(obj, bytes): return obj.decode('utf-8', errors='backslashreplace') raise TypeError(f"Object of type {type(obj)} is not JSON serializable") async with get_async_session() as session: stmt = insert(VWEDTaskLog).values( id=task_log_id, level=1 if result.get("success", False) else 3, # 1: 信息, 3: 错误 message=json.dumps(result, ensure_ascii=False, default=json_serializer), task_block_id=block.get("id", "unknown"), task_id=context.task_def_id, task_record_id=context.task_record_id ) await session.execute(stmt) await session.commit() except Exception as e: logger.error(f"记录任务日志失败: {str(e)}") # 注册装饰器 def register_handler(block_type: str): """ 注册块处理器的装饰器 Args: block_type: 块类型 """ def decorator(cls): _block_handlers[block_type] = cls() return cls return decorator # 获取块处理器 def get_block_handler(block_type: str) -> Optional[BlockHandler]: """ 获取块处理器 Args: block_type: 块类型 Returns: Optional[BlockHandler]: 对应的块处理器,如果不存在则返回None """ return _block_handlers.get(block_type)