VWED_server/docs/script_registration_examples.md

22 KiB
Raw Blame History

VWED脚本注册声明示例文档

概述

本文档详细说明了在VWED在线脚本中如何注册和声明各种类型的内置函数包括API接口、自定义函数、事件监听器和定时任务。


1. API接口注册示例

1.1 基本GET接口

#!/usr/bin/env python
# -*- coding: utf-8 -*-
def boot():
    """脚本启动函数"""
    
    # 注册GET接口 - 传参数和定义执行逻辑分开
    VWED.api.register_route(
        path="/hello",
        method="GET", 
        handler=hello_handler,
        description="问候接口"
    )

def hello_handler(request_data):
    """处理问候请求"""
    name = request_data["query_params"].get("name", "World")
    return {"message": f"Hello, {name}!"}

请求示例: GET /api/dynamic/hello?name=张三

响应示例:

{
    "message": "Hello, 张三!"
}

1.2 带参数定义的POST接口

def boot():
    # 注册POST接口简化参数定义 - 传参数和定义执行逻辑分开
    VWED.api.register_route(
        path="/calculate",
        method="POST", 
        handler=calculate_handler,
        description="数学计算接口",
        params={"a": 0, "b": 0, "operation": "add"}  # 简化的参数定义:键值对形式的默认值
    )

def calculate_handler(a: int, b: int, operation: str):
    """数学计算处理器 - 直接接收参数"""
    
    # 执行计算
    if operation == "add":
        result = a + b
    elif operation == "subtract":
        result = a - b
    elif operation == "multiply":
        result = a * b
    elif operation == "divide":
        result = a / b if b != 0 else None
    else:
        result = None
    
    # 记录日志
    VWED.log.sync_info(f"计算执行: {a} {operation} {b} = {result}")
    
    return {
        "result": result,
        "operation": operation,
        "operand_a": a,
        "operand_b": b,
        "timestamp": VWED.util.now()
    }

请求示例:

POST /api/dynamic/calculate
Content-Type: application/json

{
    "a": 10,
    "b": 5,
    "operation": "multiply"
}

1.3 数据处理接口

def boot():
    # 注册数据处理接口 - 传参数和定义执行逻辑分开
    VWED.api.register_route(
        path="/process-data",
        method="POST",
        handler=process_data_handler,
        description="数据处理接口",
        params={"data_list": [], "process_type": "filter"}  # 简化的参数定义
    )

def process_data_handler(data_list: list, process_type: str):
    """处理批量数据 - 直接接收参数"""
    
    if process_type == "filter":
        # 过滤正数
        result = [x for x in data_list if isinstance(x, (int, float)) and x > 0]
    elif process_type == "sort":
        # 排序
        result = sorted(data_list)
    elif process_type == "sum":
        # 求和
        result = sum(x for x in data_list if isinstance(x, (int, float)))
    else:
        result = data_list
    
    VWED.log.sync_info(f"数据处理完成: {process_type}, 输入{len(data_list)}项,输出{len(result) if isinstance(result, list) else 1}项")
    
    return {
        "original_data": data_list,
        "processed_data": result,
        "process_type": process_type,
        "input_count": len(data_list),
        "output_count": len(result) if isinstance(result, list) else 1
    }

2. 自定义函数注册示例

2.1 简单计算函数

def boot():
    # 注册简单函数 - 传参数和定义执行逻辑分开
    VWED.function.register(
        name="simple_add",
        handler=simple_add,
        description="简单加法函数",
        params={"a": 0, "b": 0}  # 简化的参数定义
    )

def simple_add(a: int, b: int):
    """供VWED任务调用的加法函数 - 直接接收参数"""
    result = a + b
    
    VWED.log.sync_info(f"执行加法: {a} + {b} = {result}")
    return {"result": result}

VWED任务中的调用方式:

{
    "block_type": "script",
    "execution_mode": "function_call",
    "function_name": "simple_add",
    "function_args": {
        "a": 10,
        "b": 20
    }
}

2.2 带多个参数的函数

def boot():
    # 注册多参数函数 - 简化的参数定义
    VWED.function.register(
        name="data_statistics",
        handler=data_statistics,
        description="数据统计函数",
        params={"numbers": [1, 2, 3], "operation": "sum", "round_digits": 2}  # 简化的参数定义
    )

def data_statistics(numbers: list, operation: str, round_digits: int):
    """数据统计函数 - 直接接收参数"""
    
    if not numbers:
        return {"error": "数字数组不能为空"}
    
    # 执行计算
    if operation == "sum":
        result = sum(numbers)
    elif operation == "avg":
        result = sum(numbers) / len(numbers)
    elif operation == "max":
        result = max(numbers)
    elif operation == "min":
        result = min(numbers)
    elif operation == "median":
        sorted_numbers = sorted(numbers)
        n = len(sorted_numbers)
        if n % 2 == 0:
            result = (sorted_numbers[n//2-1] + sorted_numbers[n//2]) / 2
        else:
            result = sorted_numbers[n//2]
    else:
        return {"error": f"不支持的运算类型: {operation}"}
    
    # 四舍五入
    if isinstance(result, float):
        result = round(result, round_digits)
    
    VWED.log.sync_info(f"数据统计: {operation}({numbers}) = {result}")
    
    return {
        "result": result,
        "operation": operation,
        "input_count": len(numbers),
        "input_numbers": numbers
    }

2.3 异步函数示例

def boot():
    # 注册异步函数 - 简化的参数定义
    VWED.function.register(
        name="async_data_fetch",
        handler=async_data_fetch,
        description="异步数据获取函数",
        params={"source": "database", "delay": 1}  # 简化的参数定义
    )

async def async_data_fetch(source: str, delay: int):
    """异步获取和处理数据 - 直接接收参数"""
    
    await VWED.log.info(f"开始异步数据获取: {source}")
    
    # 模拟异步操作
    await VWED.util.async_sleep(delay)
    
    # 模拟数据获取
    mock_data = {
        "database": [{"id": 1, "name": "数据1"}, {"id": 2, "name": "数据2"}],
        "api": [{"status": "success", "data": "API数据"}],
        "file": [{"content": "文件内容", "size": 1024}]
    }
    
    data = mock_data.get(source, [])
    
    await VWED.log.info(f"异步数据获取完成: {source}, 获取到{len(data)}条记录")
    
    return {
        "source": source,
        "data": data,
        "count": len(data),
        "fetch_time": delay,
        "completed_at": VWED.util.now()
    }

2.4 数据验证函数

def boot():
    # 注册数据验证函数 - 简化的参数定义
    VWED.function.register(
        name="validate_user_data",
        handler=validate_user_data,
        description="用户数据验证函数",
        params={"user_data": {"name": "", "age": 0, "email": ""}, "strict_mode": False}  # 简化的参数定义
    )

def validate_user_data(user_data: dict, strict_mode: bool):
    """验证用户数据 - 直接接收参数"""
    
    errors = []
    warnings = []
    
    # 必填字段检查
    if not user_data.get("name"):
        errors.append("姓名是必填字段")
    
    # 年龄验证
    age = user_data.get("age")
    if age is not None:
        if not isinstance(age, int) or age < 0:
            errors.append("年龄必须是非负整数")
        elif age > 150:
            warnings.append("年龄超过150岁请确认")
    
    # 邮箱验证
    email = user_data.get("email")
    if email:
        if "@" not in email or "." not in email:
            if strict_mode:
                errors.append("邮箱格式不正确")
            else:
                warnings.append("邮箱格式可能不正确")
    
    # 记录验证结果
    is_valid = len(errors) == 0
    VWED.log.sync_info(f"用户数据验证: {'通过' if is_valid else '失败'}, 错误{len(errors)}个,警告{len(warnings)}个")
    
    return {
        "is_valid": is_valid,
        "errors": errors,
        "warnings": warnings,
        "validated_fields": list(user_data.keys()),
        "strict_mode": strict_mode
    }

3. 事件监听器注册示例

3.1 基本事件监听器

def boot():
    # 注册基本事件监听器 - 传参数和定义执行逻辑分开
    VWED.event.listen(
        event_name="user_login",
        handler=on_user_login
    )

def on_user_login(event_data):
    """用户登录事件处理"""
    user_id = event_data.get("user_id", "unknown")
    login_time = event_data.get("login_time", VWED.util.now())
    
    VWED.log.sync_info(f"用户登录: {user_id} at {login_time}")
    
    # 更新登录统计
    login_count = VWED.data.get("login_count", 0)
    VWED.data.set("login_count", login_count + 1)
    
    # 记录最近登录用户
    recent_logins = VWED.data.get("recent_logins", [])
    recent_logins.append({"user_id": user_id, "time": login_time})
    # 只保留最近10条记录
    if len(recent_logins) > 10:
        recent_logins = recent_logins[-10:]
    VWED.data.set("recent_logins", recent_logins)

3.2 高优先级事件监听器

def boot():
    # 注册高优先级事件监听器
    @VWED.event.listen("system_error", priority=0)  # 优先级0最高
    def on_system_error(event_data):
        """系统错误事件处理(高优先级)"""
        error_type = event_data.get("error_type", "unknown")
        error_message = event_data.get("error_message", "")
        
        VWED.log.sync_error(f"系统错误: {error_type} - {error_message}")
        
        # 错误统计
        error_count = VWED.data.get("error_count", 0)
        VWED.data.set("error_count", error_count + 1)
        
        # 如果是严重错误,触发告警
        if error_type in ["database_down", "memory_overflow", "security_breach"]:
            # 触发告警事件
            asyncio.create_task(VWED.event.emit("critical_alert", {
                "level": "critical",
                "source": "system_monitor",
                "error_type": error_type,
                "message": error_message,
                "timestamp": VWED.util.now()
            }))

3.3 任务完成事件监听器

def boot():
    # 监听VWED任务完成事件
    @VWED.event.listen("task_completed", priority=1)
    def on_task_completed(event_data):
        """任务完成事件处理"""
        task_id = event_data.get("task_id", "unknown")
        task_status = event_data.get("status", "unknown")
        execution_time = event_data.get("execution_time_ms", 0)
        
        VWED.log.sync_info(f"任务完成: {task_id}, 状态: {task_status}, 耗时: {execution_time}ms")
        
        # 更新任务统计
        completed_tasks = VWED.data.get("completed_tasks", [])
        completed_tasks.append({
            "task_id": task_id,
            "status": task_status,
            "execution_time_ms": execution_time,
            "completed_at": VWED.util.now()
        })
        
        # 只保留最近100条记录
        if len(completed_tasks) > 100:
            completed_tasks = completed_tasks[-100:]
        VWED.data.set("completed_tasks", completed_tasks)
        
        # 如果任务执行时间过长,记录预警
        if execution_time > 30000:  # 超过30秒
            VWED.log.sync_warning(f"任务执行时间过长: {task_id} ({execution_time}ms)")

4. 定时任务注册示例

4.1 周期性定时任务

def boot():
    # 注册周期性定时任务 - 每分钟执行一次 - 传参数和定义执行逻辑分开
    VWED.timer.interval(
        interval=60,  # 60秒间隔
        handler=system_monitor
    )

def system_monitor():
    """系统监控定时任务"""
    # 获取系统统计信息
    stats = {
        "login_count": VWED.data.get("login_count", 0),
        "error_count": VWED.data.get("error_count", 0),
        "completed_tasks": len(VWED.data.get("completed_tasks", [])),
        "check_time": VWED.util.now()
    }
    
    VWED.log.sync_info(f"系统监控: 登录{stats['login_count']}次, 错误{stats['error_count']}个, 完成任务{stats['completed_tasks']}个")
    
    # 保存监控记录
    monitor_history = VWED.data.get("monitor_history", [])
    monitor_history.append(stats)
    
    # 只保留最近24小时的记录
    if len(monitor_history) > 1440:  # 24*60分钟
        monitor_history = monitor_history[-1440:]
    VWED.data.set("monitor_history", monitor_history)

4.2 一次性延迟任务

def boot():
    # 注册一次性延迟任务 - 10秒后执行
    @VWED.timer.once(delay=10)
    def initialization_task():
        """初始化任务(延迟执行)"""
        VWED.log.sync_info("执行初始化任务")
        
        # 初始化数据结构
        if not VWED.data.has("initialized"):
            VWED.data.set("login_count", 0)
            VWED.data.set("error_count", 0)
            VWED.data.set("completed_tasks", [])
            VWED.data.set("monitor_history", [])
            VWED.data.set("initialized", True)
            VWED.data.set("init_time", VWED.util.now())
            
            VWED.log.sync_info("系统数据初始化完成")

4.3 数据清理定时任务

def boot():
    # 注册数据清理任务 - 每小时执行一次
    @VWED.timer.interval(3600)  # 3600秒 = 1小时
    def data_cleanup():
        """数据清理定时任务"""
        VWED.log.sync_info("开始执行数据清理")
        
        cleanup_count = 0
        
        # 清理过期的监控记录
        monitor_history = VWED.data.get("monitor_history", [])
        original_count = len(monitor_history)
        # 只保留最近12小时的记录
        monitor_history = monitor_history[-720:]  # 12*60分钟
        VWED.data.set("monitor_history", monitor_history)
        cleanup_count += original_count - len(monitor_history)
        
        # 清理过期的任务记录
        completed_tasks = VWED.data.get("completed_tasks", [])
        original_count = len(completed_tasks)
        # 只保留最近50条记录
        completed_tasks = completed_tasks[-50:]
        VWED.data.set("completed_tasks", completed_tasks)
        cleanup_count += original_count - len(completed_tasks)
        
        # 清理过期的登录记录
        recent_logins = VWED.data.get("recent_logins", [])
        original_count = len(recent_logins)
        # 只保留最近20条记录
        recent_logins = recent_logins[-20:]
        VWED.data.set("recent_logins", recent_logins)
        cleanup_count += original_count - len(recent_logins)
        
        VWED.log.sync_info(f"数据清理完成,清理了{cleanup_count}条过期记录")
        
        # 记录清理统计
        cleanup_stats = VWED.data.get("cleanup_stats", [])
        cleanup_stats.append({
            "cleanup_time": VWED.util.now(),
            "cleaned_records": cleanup_count
        })
        # 只保留最近10次清理记录
        if len(cleanup_stats) > 10:
            cleanup_stats = cleanup_stats[-10:]
        VWED.data.set("cleanup_stats", cleanup_stats)

5. 完整的脚本示例

以下是一个包含所有类型注册的完整脚本示例:

def boot():
    """脚本启动函数 - 注册所有服务"""
    VWED.log.sync_info("=== 开始注册脚本服务 ===")
    
    # 注册API接口
    register_api_services()
    
    # 注册自定义函数
    register_custom_functions()
    
    # 注册事件监听器
    register_event_listeners()
    
    # 注册定时任务
    register_timer_tasks()
    
    VWED.log.sync_info("=== 脚本服务注册完成 ===")

def register_api_services():
    """注册API服务"""
    VWED.log.sync_info("注册API接口...")
    
    # 传参数和定义执行逻辑分开
    VWED.api.register_route(
        path="/status", 
        method="GET",
        handler=get_system_status,
        description="系统状态查询接口"
    )
    
    VWED.api.register_route(
        path="/trigger-event", 
        method="POST",
        handler=trigger_event,
        description="手动触发事件接口"
    )

def get_system_status(request_data):
    return {
        "status": "running",
        "timestamp": VWED.util.now(),
        "script_id": VWED.get_script_id(),
        "stats": {
            "login_count": VWED.data.get("login_count", 0),
            "error_count": VWED.data.get("error_count", 0),
            "task_count": len(VWED.data.get("completed_tasks", []))
        }
    }

def trigger_event(request_data):
    event_name = request_data["body"].get("event_name")
    event_data = request_data["body"].get("event_data", {})
    
    if event_name:
        # 异步触发事件
        asyncio.create_task(VWED.event.emit(event_name, event_data))
        return {"success": True, "event_triggered": event_name}
    else:
        return {"success": False, "error": "event_name is required"}

def register_custom_functions():
    """注册自定义函数"""
    VWED.log.sync_info("注册自定义函数...")
    
    # 传参数和定义执行逻辑分开
    VWED.function.register(
        name="get_statistics", 
        handler=get_statistics,
        description="获取系统统计信息"
    )
    
    VWED.function.register(
        name="reset_counters", 
        handler=reset_counters,
        description="重置计数器"
    )

def get_statistics(args):
    return {
        "login_count": VWED.data.get("login_count", 0),
        "error_count": VWED.data.get("error_count", 0),
        "completed_tasks": len(VWED.data.get("completed_tasks", [])),
        "monitor_records": len(VWED.data.get("monitor_history", [])),
        "initialized": VWED.data.get("initialized", False),
        "init_time": VWED.data.get("init_time", None)
    }

def reset_counters(args):
    VWED.data.set("login_count", 0)
    VWED.data.set("error_count", 0)
    VWED.data.set("completed_tasks", [])
    
    VWED.log.sync_info("计数器已重置")
    return {"success": True, "reset_time": VWED.util.now()}

def register_event_listeners():
    """注册事件监听器"""
    VWED.log.sync_info("注册事件监听器...")
    
    # 传参数和定义执行逻辑分开
    VWED.event.listen(
        event_name="user_action",
        handler=on_user_action
    )

def on_user_action(event_data):
    action = event_data.get("action", "unknown")
    user_id = event_data.get("user_id", "unknown")
    
    VWED.log.sync_info(f"用户操作: {user_id} 执行了 {action}")
    
    # 记录用户操作
    user_actions = VWED.data.get("user_actions", [])
    user_actions.append({
        "user_id": user_id,
        "action": action,
        "timestamp": VWED.util.now()
    })
    
    # 只保留最近50条记录
    if len(user_actions) > 50:
        user_actions = user_actions[-50:]
    VWED.data.set("user_actions", user_actions)

def register_timer_tasks():
    """注册定时任务"""
    VWED.log.sync_info("注册定时任务...")
    
    # 传参数和定义执行逻辑分开
    VWED.timer.interval(
        interval=30,  # 每30秒
        handler=heartbeat
    )
    
    VWED.timer.once(
        delay=5,  # 5秒后执行一次
        handler=delayed_initialization
    )

def heartbeat():
    heartbeat_count = VWED.data.get("heartbeat_count", 0)
    VWED.data.set("heartbeat_count", heartbeat_count + 1)
    
    if heartbeat_count % 10 == 0:  # 每300秒5分钟记录一次
        VWED.log.sync_info(f"系统心跳 #{heartbeat_count}")

def delayed_initialization():
    VWED.log.sync_info("延迟初始化任务执行")
    VWED.data.set("delayed_init_completed", True)

# 工具函数示例
def format_timestamp(timestamp_str):
    """格式化时间戳"""
    try:
        from datetime import datetime
        dt = datetime.fromisoformat(timestamp_str.replace('Z', '+00:00'))
        return dt.strftime("%Y-%m-%d %H:%M:%S")
    except:
        return timestamp_str

def calculate_average(numbers):
    """计算平均值"""
    if not numbers:
        return 0
    return sum(numbers) / len(numbers)

6. 注册验证和调试技巧

6.1 验证注册状态

在脚本中可以添加验证代码来检查注册状态:

def boot():
    # ... 注册代码 ...
    
    # 验证注册状态
    verify_registrations()

def verify_registrations():
    """验证注册状态"""
    # 可以通过API查询注册状态
    # GET /api/script/registry/status
    
    VWED.log.sync_info("验证注册状态...")
    
    # 这里可以添加自定义验证逻辑
    expected_functions = ["get_statistics", "reset_counters"]
    expected_apis = ["/status", "/trigger-event"]
    
    VWED.log.sync_info(f"预期注册函数: {expected_functions}")
    VWED.log.sync_info(f"预期注册API: {expected_apis}")

6.2 调试技巧

def boot():
    try:
        # 注册代码
        register_all_services()
        VWED.log.sync_info("✓ 所有服务注册成功")
    except Exception as e:
        VWED.log.sync_error(f"✗ 服务注册失败: {str(e)}")
        # 可以根据需要添加详细的错误处理

def register_all_services():
    """集中注册所有服务"""
    service_count = 0
    
    # 注册API带计数
    api_services = register_api_services()
    service_count += api_services
    
    # 注册函数(带计数)
    function_services = register_custom_functions()
    service_count += function_services
    
    # 注册事件监听器(带计数)
    event_services = register_event_listeners()
    service_count += event_services
    
    # 注册定时任务(带计数)
    timer_services = register_timer_tasks()
    service_count += timer_services
    
    VWED.log.sync_info(f"总共注册了 {service_count} 个服务")
    return service_count

总结

本文档提供了VWED脚本中各种注册声明的完整示例包括

  1. API接口注册 - 支持GET/POST/PUT/DELETE等HTTP方法
  2. 自定义函数注册 - 供VWED任务系统调用的函数
  3. 事件监听器注册 - 响应系统和自定义事件
  4. 定时任务注册 - 周期性和一次性任务

每种类型都提供了从简单到复杂的多个示例帮助开发者快速掌握VWED脚本的注册机制。

关键要点:

  • 所有注册都必须在 boot() 函数中进行
  • 使用装饰器语法进行注册声明
  • 支持详细的参数定义和文档描述
  • 提供完整的错误处理和日志记录
  • 支持异步和同步两种执行模式