apppublic/aidocs/restrictedEnv.md
2025-10-05 11:23:33 +08:00

6.0 KiB
Raw Permalink Blame History

RestrictedEnv 类技术文档

概述

RestrictedEnv 是一个轻量级的沙箱环境类,用于在受限上下文中安全地执行与日期/时间相关的表达式。它通过注册特定函数并利用 Python 的 exec 动态执行字符串形式的代码,提供了一种简洁的方式来解析和计算时间表达式,同时避免直接暴露完整的 Python 执行环境。

该类主要适用于需要动态解析时间表达式的场景(如配置文件、规则引擎等),且希望限制可调用函数范围以增强安全性。


依赖

  • appPublic.timeUtils as tu:提供日期/时间格式化与解析工具函数。
  • datetime as dtPython 标准库中的 datetime 模块,用于处理日期和时间对象。

⚠️ 注意:确保 appPublic.timeUtils 模块已正确安装并包含所需方法。


类定义

class RestrictedEnv:

构造函数 __init__

初始化 RestrictedEnv 实例,并注册一组预定义的时间相关函数到内部命名空间。

注册的函数:

函数名 对应方法 描述
today self.today() 返回今天的日期(仅年月日)
date self.date(dstr) 将字符串转换为日期对象
datetime self.datetime(dstr) 将字符串转换为 datetime 对象
now dt.datetime.now(原生) 获取当前精确到微秒的日期时间

示例:

env = RestrictedEnv()
# 此时 env 已经可以识别 'today()', 'date(...)', 'datetime(...)', 'now()' 等表达式

方法说明

reg(k: str, v: callable) -> None

将键值对 (k, v) 注册到实例的命名空间中,使得后续可通过字符串表达式调用 v

参数:

  • k (str): 在表达式中使用的函数或变量名称。
  • v (callable): 可调用对象函数、方法、lambda 等)或数据。

实现方式:

使用 self.__dict__[k] = v 将其注入局部作用域。

示例:

ns.reg('pi', 3.14159)
result = ns.run('pi * 2')  # 返回 6.28318

run(dstr: str) -> Any

在受限环境中执行给定的表达式字符串,并返回其结果。

参数:

  • dstr (str): 要执行的表达式字符串(如 'today()', "date('2023-01-01')")。

返回值:

表达式计算的结果。

原理:

  1. 将输入表达式包装为赋值语句:__tempkey__ = <表达式>
  2. 使用 exec() 在全局 globals() 和实例局部命名空间 self.__dict__ 中执行。
  3. 返回临时变量 self.__tempkey__ 的值。

安全提示:虽然名为“受限”,但由于使用了 exec,仍需谨慎处理不可信输入,防止代码注入风险。

示例:

result = ns.run("today()")        # 返回今天日期Date 类型)
result = ns.run("now()")          # 返回当前 datetime 对象

today() -> date

获取当前日期(仅年-月-日部分),忽略时间信息。

返回:

  • date 对象,由 tu.ymdDate(year, month, day) 生成。

内部逻辑:

now = dt.datetime.now()
return tu.ymdDate(now.year, now.month, now.day)

示例:

ns.run("today()")  # 输出类似: 2025-04-05

date(dstr: str) -> date

将日期字符串转换为日期对象。

参数:

  • dstr (str): 格式化的日期字符串,例如 '2023-12-25'

返回:

  • date 对象,由 tu.str2Date(dstr) 解析得到。

示例:

ns.run("date('2023-01-01')")  # 返回对应日期对象

datetime(dstr: str) -> datetime

将日期时间字符串转换为 datetime 对象。

参数:

  • dstr (str): 包含时间和日期的字符串,如 "2023-06-15 14:30:00"

返回:

  • datetime 对象,由 tu.str2Datetime(dstr) 解析生成。

示例:

ns.run('datetime("2023-07-04 12:00:00")')

使用示例

以下是在主模块中运行的测试代码:

if __name__ == '__main__':
    ns = RestrictedEnv()
    a = ns.run('today()')                           # 当前日期
    b = ns.run("date('2011-10-31')")                # 自定义日期对象
    c = ns.run('datetime("2012-03-12 10:22:22")')   # 自定义 datetime
    d = ns.run('now()')                             # 当前完整时间戳

预期输出类型:

表达式 返回类型 示例值
today() date 2025-04-05
date(...) date 2011-10-31
datetime(...) datetime 2012-03-12 10:22:22
now() datetime 2025-04-05 10:15:30.123456

安全性说明

⚠️ 警告:尽管称为“受限环境”,但因使用了 exec(),若传入恶意字符串可能导致任意代码执行。

建议:

  • 仅用于可信输入或受控环境。
  • 不应用于解析用户提交的表达式,除非有额外语法校验层。
  • 可考虑替换为更安全的表达式解析器(如 asteval, simpleeval)以提升安全性。

扩展建议

你可以通过继承或修改 reg 调用来扩展功能,例如添加数学函数、条件判断等:

import math
ns.reg('sqrt', math.sqrt)
result = ns.run('sqrt(16)')  # 得到 4.0

但请始终注意作用域控制与安全性。


总结

RestrictedEnv 提供了一个简单而有效的方式,在隔离环境下动态求值时间表达式。适合集成于规则系统、报表脚本或配置驱动的应用程序中,作为时间处理的 DSL领域专用语言入口点。

特性 说明
易用性 支持自然的时间表达式写法
可扩展 通过 reg() 添加新函数
⚠️ 安全性 使用 exec,需防范注入风险
📦 轻量 无外部依赖(除 appPublic.timeUtils

推荐用途:内部工具、自动化脚本、配置解析器
不推荐用途Web API 输入解析、不受信用户输入处理