远端运行环境
脚本发送到远端环境运行,包括用于桌面开发的桌面助手,以及用于自动化脚本的站点机器人
.. contents:: .. sectnum::
通过前端组件在桌面运行 (联机桌面脚本)
把联机脚本,下发到桌面助手运行。出于安全考虑,联机桌面脚本需要签名。
用户可以在前端点击浏览器的某个链接按钮触发联机脚本::
view.native.call_script(script_name,
args=None, kw=None, onduplicate='warn', on_return_url='')
参数说明:
-
script_name:
脚本的完整名字,例如 zopen.aaa:bbb -
args: <tuple/list/None> 参数列表
-
kw: <dict/None> 命名参数列表
-
disable_upgrade:如果桌面助手版本太低,是否禁止升级(默认会升级)
-
onduplicate:
任务重复时的处理策略,可选值 warn/run/ignore: - warn: 冒泡提示用户任务重复,并且不运行
- run: 仍然运行重复的任务
- ignore: 不提示用户,且不运行
-
on_return_url:
处理脚本运行结果的URL。指定此参数则脚本将同步(阻塞式)运行,并将脚本返回的结果POST给这个URL。 - 如果运行成功,脚本的返回结果经过 JSON dumps 之后存放在result字段;
- 如果运行出错,traceback信息经过 JSON dumps 之后存放在traceback字段;
发送给连接的用户运行(联机服务脚本)
也可以在后台给指定用户发送脚本执行指令::
remote = root.get_remote(receiver='')
其中 receivers 运行脚本的机器人。
可以在远端异步调用一个脚本::
taskid = remote.call_script_async(
'zopen.xxx:xxxx',
args=(),
kw={},
callback_url='',
error_callback_url ='',
)
其中:
-
args/kw: 运行这个脚本传入的参数
-
callback_url: 脚本运行成功的回调URL。脚本的返回结果会以POST方式发送给这个地址,包含以下参数:
result
: 脚本的返回值 经过JSON序列化 后的内容
-
error_callback_url: 设置脚本出错后的回调URL。如果脚本运行出错:
-
没有设置error_callback_url,则会通过系统通知渠道,告知发送脚本的用户(调用
root.get_remote()
时的当前用户); -
如果有设置error_callback_url,则会发送一个POST请求到这个地址,包含以下数据:
traceback
: 脚本发生错误时捕获的错误堆栈信息(字符串)
-
callback_url和error_callback_url可用下面地址生成::
obj.api_url(requset, script_name, auth_=True)
直接调用远端 (联机服务脚本)
先用token来链接远端::
remote = root.get_remote(host='', port=0, token="")
可以继续异步调用::
taskid = remote.call_script_async(
'zopen.xxx:xxxx',
args=(),
kw={},
callback_url='',
error_callback_url ='',
)
也可以同步调用::
remote.call_script('zopen.xxx:xxxx', args=(), kw={})
联机脚本函数
如果联机脚本太复杂,或者有可重用的逻辑,可以封装到独立的脚本中,调用方法为::
call_script(script_name, *args, **kwargs)
例如,以下代码会调用 zopen.xx:yy
脚本::
call_script('zopen.xx:yy', a, b, c d=1, e=2)
call_script 会实时下载指定脚本来运行,下载失败将抛出 ScriptDownloadError
,带有一个 error
属性保存了原始的异常实例。
如果调用的脚本运行时抛出了异常,call_script 将不会做任何处理,直接抛出。
注意,只能调用受信任的脚本。
远端运行环境类库
可用的类库
除了标准库,shell脚本还可以用如下第三方库:
- requests
- reportlab
- PyPDF2
- PyCrypto
- certifi
- watchdog
- python-dateutil
- psutil
- sh (只在 Linux/Mac 系统可用)
- fabric2
- fabric
可以用 install_addon
安装插件::
install_addon('http://xxx/edo_fabric.py', '0.1')
或者使用 require(package_name)
安装额外的第三方包
-
调用 pip 安装额外的第三方包到
~/edo_assistent/addons
目录中。 -
调用完成后即可使用 import 来导入安装的第三方包。如果 addons 目录中已经安装了指定的包,则不会重复安装。
- 此功能在 Windows 平台上,需要独立安装的 Python 2 和 pip 工具,并且 pip 工具需要在 PATH 中。
- 如果使用 Linux 版本的 deb 包安装SiteBot,此功能也需要独立安装的 Python 2 和 pip 工具。
- 如果指定的包需要编译或其他预处理才能安装,机器上需要安装有对应的编译器或预处理工具,且要保证可被 pip 调用。
utils: 工具模块
包含的主要函数:
- getmtimt(path) 获取本地文件的修改时间。内部会对异常的时间做修复处理。
- get_file_md5(path) 获取本地文件的 MD5
- get_file_size(path) 获取本地文件大小
- get_human_ltime(dt) 获取 datetime 对象的友好形式。
- get_human_size(size) 获取文件大小的友好形式。
- get_numbered_filename(name) 获取编号后的文件名,例如
file-1.txt
会返回file-2.txt
。 - get_site_public_key(wo_server, account, instance, token=None) 获取指定站点的公钥(优先使用缓存的公钥)。
- get_message_client(token=None, server=None, account=None, instance=None) 获取一个 edo_client.MessageClient 实例。
- get_upload_client(token=None, server=None, account=None, instance=None) 获取一个 edo_client.UploadClient 实例。
- get_wo_client(token=None, server=None, account=None, instance=None) 获取一个 edo_client.WoClient 实例。
内置的变量和方法
worker_db: 当前任务的数据
......................................
包括了访问服务器的信息,接口与 dict 完全一致。需要持久化到磁盘时调用 .sync()
方法即可。
包含如下一组固定变量:
- server: 指定wo服务器
- oc_server: 指定 oc 服务器
- account: 指定账户
- instance: 指定实例
- token: 当前用户的oauth认证token
report(text) 通知脚本发送者 ...................................... 一个快捷函数,用于发送一条通知消息给下发脚本的用户。
如果需要向下发脚本的用户发一个通知消息,可以如下代码示例::
report('Hi, this notification comes from the running script worker.')
acquire_lock(name, timeout=0, description=None) 加锁 ............................................................... 锁可以用于协调多个脚本任务的资源占用。当一个任务已经加锁之后,其他任务再加同一把锁会失败。
例如,以下代码示例尝试加一把名为 test-lock
的锁,如果超过两分钟加锁还未成功,将会显示一个错误消息::
try:
acquire_lock('test-lock', timeout=120) # 此方法会阻塞,直到锁获取成功或超时(由 timeout 指定)
except LockAcquireTimeout:
ui_client.message('加锁', '超过 2 分钟仍未加锁成功')
如果没有指定 timeout,则默认为 0。此时如果加锁失败会直接抛出 LockAcquireFailure
错误。
release_lock(name) 解锁
...............................................................
以下代码示例将会解开一把名为 test-lock
的锁,如果失败将显示一个消息::
try:
release_lock('test-lock')
except LockReleaseFailure:
ui_client.message('解锁', '解锁失败')
safe_call(cmd, shell=False, timeout=10*60) 调用外部程序
...............................................................
如果外部程序没有在指定时间内完成,将会被杀死(包括调用产生的所有子进程),是作为 subprocess.call
的一个替代。
以下代码将会打开 python 解释器,并在 10 秒后杀死解释器进程::
safe_call('python', timeout=10)
异常类
LockAcquireTimeout 加锁超时 ............................................................... 具有如下属性:
- worker_id 任务 ID
- lock_name 锁的名字
- timeout_value 按秒计算的超时时间
LockAcquireFailure 加锁失败 ............................................................... 具有与 LockAcquireTimeout 一致的属性
LockReleaseFailure 解锁失败 ............................................................... 具有与 LockAcquireTimeout 一致的属性
ScriptDownloadError 下载脚本失败 ............................................................... 具有如下属性
- script_name 脚本名字
- error 抛出的原始异常实例