脚本开发 / 基本概念
DataFlux Func 中,存在一些 DataFlux Func 中特有的概念,本文档将对此进行说明。
1. 脚本集、脚本和函数
脚本集、脚本和函数可在「开发 / 脚本库」中创建,是 DataFlux Func 的核心概念,ID 在用户创建 / 编写代码时直接指定。
- 「脚本集」为数个脚本的集合,ID 在创建时由用户直接指定,且只能包含脚本。
- 「脚本」即 Python 脚本本身,必然属于某一个脚本集,ID 在创建时由用户直接指定。
- 「函数」在 DataFlux Func 中特指被
@DFF.API(...)装饰器装饰的最顶层函数,可以被函数 API、定时任务等作为调用的入口函数。
脚本集不是文件夹
脚本集与文件夹类似,但这个「文件夹」与一般 Python 编码中的文件夹无关
在 DataFlux Func 中进行编码时,会大量涉及到脚本集、脚本和函数的 ID,并且这些 ID 之间存在紧密的联系。
脚本集、脚本和函数 ID 之间关系
按照脚本集、脚本和函数层级关系,下层概念的 ID 一定包含了上层概念的 ID。
假设存在一个 ID 为 demo 的脚本集,那么属于此脚本集的所有脚本必然以 demo__(双下划线)开头。
再假设此脚本集下有 ID 为 demo__test的脚本,它包含一个函数 def hello(...),那么这个函数的 ID 即为 demo__test.hello。
ID 示例表如下:
| 概念 | ID 示例 |
|---|---|
| 脚本集 | demo |
| 脚本 | demo__test |
| 函数 | demo__test.hello |
编码中相互引用
在 DataFlux Func 的脚本中,允许引用另一脚本来实现代码复用。
假设存在脚本 demo__script_a,其包含一个函数 func_a()。那么,在脚本 demo__script_b 中引用此函数时,可以使用如下方法:
| demo__script_a | |
|---|---|
1 2 | |
| demo__script_b | |
|---|---|
1 2 3 4 | |
Python 的as语句也同样可以使用:
| demo__script_b | |
|---|---|
1 2 3 4 | |
也可以使用 from ... import 语句只导入所需函数:
| demo__script_b | |
|---|---|
1 2 3 4 | |
对于属于同一个脚本集的脚本之间引用,可以忽略脚本集 ID,以 __(双下划线)开头的缩略形式表示:
| demo__script_b | |
|---|---|
1 2 3 4 | |
尽可能使用缩略形式
在脚本集内部相互引用应当尽量使用缩略形式(即忽略脚本集 ID 并以 __ 开头的形式)。
这样,在将整个脚本集克隆,脚本集 ID 发生改变后,克隆出来的新脚本集内的代码依然可以正确引用本脚本集内的脚本。
2. 连接器
连接器可在「开发 / 连接器」中创建,是由 DataFlux Func 提供的连接外部系统的工具,ID 在创建时由用户直接指定。
实际上,在 DataFlux Func 编写 Python 代码与原版 Python 并无太大区别。开发者完全可以忽略连接器,自行在代码中连接外部系统。
但对于一些存在连接池概念的外部系统来说,连接器内置了连接池,可在函数反复运行的过程中保持链接,避免反复创建 / 关闭与外部系统的连接。
假设用户已经配置好了一个 ID 为 mysql 的连接器,那么获取这个连接器的操作对象代码如下:
| Python | |
|---|---|
1 | |
具体不同的连接器具有不同的操作方法和参数,详情请参考 脚本开发 / 连接器对象 DFF.CONN
3. 环境变量
环境变量可在「开发 / 环境变量」中创建,是由 DataFlux Func 提供的简单 Key-Value 配置读取工具,ID 在创建时由用户直接指定。
环境变量特别适合用于同一套代码运行在不同环境下的场景。
如脚本需要访问的系统区分了测试 / 生产环境,那么可以通过设置环境变量,实现在不改变代码的情况下,切换测试 / 生产环境。
假设用户已经配置好了一个 ID 为 api_endpoint 的环境变量,那么获取这个环境变量值的代码如下:
| Python | |
|---|---|
1 | |
4. 函数 API
函数 API 可在「管理 / 函数 API」中创建,是外部调用 DataFlux Func 中函数的一种常见方式,调用过程可选同步或异步,同步执行时,函数执行完成后可以将结果直接返回给调用方。
为函数创建函数 API 后,支持多种不同的调用方法。
函数 API 支持 GET、POST 两种方式。两种不同方式的参数传递同时支持「简化形式」、「标准形式」。
此外,POST 方式的「简化」形式还支持文件上传,以下是各种调用方式的功能支持列表:
| 调用方式 | 传递 kwargs 参数 |
kwargs 参数类型 |
传递 options |
文件上传 | 提交任意格式的 Body |
|---|---|---|---|---|---|
GET 简化形式 |
支持 | 仅限字符串 | 不支持 | 不支持 | 不支持 |
GET 标准形式 |
支持 | JSON 中的数据类型 | 支持 | 不支持 | 不支持 |
POST 简化形式 |
支持 | 仅限字符串 | 不支持 | 支持 | 支持 |
POST 标准形式 |
支持 | JSON 中的数据类型 | 支持 | 不支持 | 不支持 |
传递方式不同会导致参数类型存在限制
对于 kwargs 中参数只能传递字符串的调用方式,需要在函数中对参数进行类型转换。在函数 API 列表,可以点击「API 调用示例」来查看具体调用方式
假设存在如下函数:
| Python | |
|---|---|
1 2 3 | |
假设为此函数创建的「函数 API」ID 为 func-api-xxxxx,传递的参数为 x=100(整数), y="hello"(字符串)。
那么,各种不同的调用方式如下:
GET 简化形式传参
如果函数的参数比较简单,可以使用 GET 简化形式传递参数,接口将更加直观。
由于 URL 中传递参数时,无法区分字符串的 "100" 和整数的 100,
所以函数在被调用时,接收到的参数都是字符串。
函数需要自行对参数进行类型转换。
| Text Only | |
|---|---|
1 | |
为了便于阅读,示例为 URLEncode 之前的内容,实际 URL 参数需要进行 URLEncode
GET 标准形式传参
在某些情况下,如果无法发送 POST 请求,也可以使用 GET 方式调用接口。
GET 标准形式传参时,将整个 kwargs 进行 JSON 序列化后,作为 URL 参数传递即可。
由于参数实际还是以 JSON 格式发送,因此参数的原始类型都会保留。
函数无需再对参数进行类型转换。
如本例中,函数接收到的 x 参数即为整数,无需类型转换。
| Text Only | |
|---|---|
1 | |
为了便于阅读,示例为 URLEncode 之前的内容,实际 URL 参数需要进行 URLEncode
POST 简化形式传参
在某些情况下,如果无法发送请求体为 JSON 的 HTTP 请求, 那么也可以类似 Form 表单的形式传递参数,各字段名即为参数名。
由于 Form 表单提交数据时,无法区分字符串的 "100" 和整数的 100,所以函数在被调用时,接收到的参数都是字符串,函数需要自行对参数进行类型转换。
| Text Only | |
|---|---|
1 2 3 4 | |
此外,POST 简化形式传参还额外支持文件上传(参数/字段名必须为 files),
需要使用 form-data/multipart 方式进行处理。
页面 HTML 代码示例如下:
| HTML | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
POST 标准形式传参
POST 标准形式传参是最常见的调用方式。
由于参数以 JSON 格式通过请求体发送,因此参数的原始类型都会保留。
函数无需再对参数进行类型转换。
如本例中,函数接收到的 x 参数即为整数,无需类型转换。
| Text Only | |
|---|---|
1 2 3 4 5 6 7 8 9 | |
5. 定时任务
定时任务可在「管理 / 定时任务」中创建,用于让 DataFlux Func 定期自动调用函数。
为函数创建定时任务后,函数则会所指定的 Crontab 表达式定时执行,不需要外部进行调用。
正因为如此,所执行的函数的所有参数必须都已满足,即:
- 函数不需要输入参数
- 函数需要输入参数,但都是可选参数
- 函数需要必选参数,并在定时任务中为其配置具体的值
区分函数运行时所属执行功能
如果函数同时配置了「定时任务」和其他执行功能,并且希望在不同的执行功能中进行区分处理,可以判断内置变量 _DFF_CRONTAB 区分:
| Python | |
|---|---|
1 2 3 4 5 6 7 8 9 | |