Airflow REST API的使用
Airflow-2.2.1提供了稳定的REST API,这样可以通过这些REST API来对airflow中的任务进行操作。airflow中的REST接口的说明可以查看这里的文档。
1.配置并创建用户
修改配置文件
修改配置文件
修改配置文件airflow.cfg,把auth_backend选项的值修改成以下值。
auth_backend = airflow.api.auth.backend.basic_auth
1
创建访问用户
添加一个user1用户
通过以下命令来添加一个user1用户,使得他可以通过REST API来访问airflow。
airflow users create -u user1 -p user1 -r Admin -f firstname -l lastname -e user1@example.org
在该命令中:-u是用户名;-p是密码;-f是first name;-l是last name;
-r是角色(这里使用的是Admin);-e是邮箱。
这些参数最好都填上,否则会创建失败。
2.REST API实战
获取dag列表信息
以下请求获取airflow中所有的dag的信息。通过该命令会返回一个dag的列表。
curl --verbose 'http://localhost:20001/api/v1/dags' -H 'content-type: application/json' --user "user1:user1"
若没有任何问题,就会得到目前airflow中所有的dag的列表,和每个dag的基本信息。其输出如下:
{
"dags": [
{
"dag_id": "example_bash_operator",
"description": null,
"file_token": ".eJw9xzESgjAQBdC70MMvUnASa-YDK2SM2Z3doOb2Wtm9N-AW4gGXflWoNbBy07ozQeorYD3NKHn9oZ1a0zQjcpPRuD14SIDZ70XfkA-fVmTZecQ_K-Nc1MTZ1CfrwxcF1CnD.riJklZV8hUinhuzuGUd-a-AxMG8",
"fileloc": "/Users/reyun/opt/anaconda3/envs/py37/lib/python3.7/site-packages/airflow/example_dags/example_bash_operator.py",
"is_active": true,
"is_paused": true,
"is_subdag": false,
"owners": [
"airflow"
],
"root_dag_id": null,
"schedule_interval": {
"__type": "CronExpression",
"value": "0 0 * * *"
},
"tags": [
{
"name": "example"
},
{
"name": "example2"
}
]
},
{
"dag_id": "example_branch_datetime_operator_2",
"description": null,
"file_token": ".eJw9yDsSgzAMRdG90AcVLlhJakbAC3hi
...
},
{
"dag_id": "xhz_hello_world_dag",
"description": "zxh first DAG",
"file_token": "Ii9Vc2Vycy9yZXl1bi9haXJmbG93L2RhZ3MvaGVsbG9fd29ybGQucHki.Mu2a930AhcRoi1WYEO8JE1Dh1r0",
"fileloc": "/Users/reyun/airflow/dags/hello_world.py",
"is_active": true,
"is_paused": true,
"is_subdag": false,
"owners": [
"zxh"
],
"root_dag_id": null,
"schedule_interval": {
"__type": "TimeDelta",
"days": 1,
"microseconds": 0,
"seconds": 0
},
"tags": []
}
],
"total_entries": 33
}
触发某个dag的执行
触发某个dag执行时,需要填写参数,其中execution_date参数是必须要填写的,而且该参数不能和以前提交的任务参数相同。
EXE_DATE=$(TZ=America/Curacao date '+%Y-%m-%dT%H:%M:%SZ')
curl -X POST 'http://localhost:20001/api/v1/dags/xhz_hello_world_dag/dagRuns' \
-d "{\"execution_date\": \"${EXE_DATE}\", \"conf\": {}}" \
-H 'content-type: application/json' \
--user "user1:user1"
通过该命令根据airflow的REST接口来触发某个dag去执行。该命令会返回dag运行时的id。如下:
{
"conf": {},
"dag_id": "xhz_hello_world_dag",
"dag_run_id": "manual__2021-10-09T03:28:59+00:00",
"end_date": null,
"execution_date": "2021-10-09T03:28:59+00:00",
"external_trigger": true,
"start_date": null,
"state": "queued"
}
从以上输出结果可以看出,任务已经在队列中排队了(提交成功)。其中返回的dag_run_id字段,就是基于静态的dag生成的运行的实体的id。可以根据dag_run_id来查看该dag运行时的状态信息。在业务层面,该dag_run_id往往会和某个具体的业务计算的任务关联起来,这样就可以对业务层的任务进行重试,停止等操作。
获取运行任务的信息
可以通过触发任务时,获取到的dag_run_id的值,来获取运行时任务的状态信息。(能获取到日志吗?)
# 获取运行任务的信息
curl 'http://localhost:20001/api/v1/dags/zxh_hello_world_dag/dagRuns/manual__2021-10-09T03:28:59+00:00' \
-H 'content-type: application/json' \
--user "user1:user1"
得到的输出结果如下:
{
"conf": {},
"dag_id": "zxh_hello_world_dag",
"dag_run_id": "manual__2021-10-09T03:28:59+00:00",
"end_date": "2021-10-09T07:29:07.851392+00:00",
"execution_date": "2021-10-09T03:28:59+00:00",
"external_trigger": true,
"start_date": "2021-10-09T07:28:59.887252+00:00",
"state": "success"
}
从以上获取到的结果可以看出,该任务执行成功了。
停止正在运行的dag
通过REST API接口,有两种方式可以用来停止一个正在运行的dag:
(1)一种是停止某个dag_run_id下的task instance;但要注意,这种方式可能无法及时停止所有正在并行运行的task instance。对于依赖简单的dag,可以使用这种方式来停止正在运行的dag。
(2)一种是通过接口来直接停止所有的task instance;注意:这种方式在airflow-2.2.0才开始支持,提供了一个接口用来停止某个正在运行的dag实例。而且,在最新的airflow-2.2.0的文档中,还没有该接口的说明,但在接口说明的yaml文件中可以找到该接口。
1.第一种方式
这种方式需要先找到把哪个task instance设置成failed状态。所以需要先获取dag_run_id的task instance情况,然后找到可以设置状态的task instance,然后才能设置状态。
2.第2种方式:停止所有运行的task instance
这种方式会把正在执行的任务设置成failed状态,已经执行成功的任务的状态不会改变。
ENDPOINT=http://localhost:20001DAG_NAME=hello_dagdag_run_id="manual__2021-10-19T06:21:32.471629+00:00"
curl -X PATCH "${ENDPOINT}/api/v1/dags/${DAG_NAME}/dagRuns/${dag_run_id}" \ -d "{\"state\": \"failed\"}" \ -H 'content-type: application/json' \ --user "user1:user1"
重启正在运行的任务
有时我们可能希望能够重试执行失败的任务。但不是重新启动一个新的运行实体,而是希望能够在原来的运行实体的基础上继续执行。此时,就需要使用下面的接口来实现。下面的接口重新启动已经失败的或停止的任务。
curl --location --request POST 'http://127.0.0.1:20001/api/v1/dags/hello_world_dag/clearTaskInstances' \--header 'Content-Type: application/json' \--data-raw '{ "dry_run": false, "task_ids": [ "sleep_task" ], "start_date": "2021-10-19T06:37:45.156532+00:00", "end_date": "2021-10-19T06:37:45.156532+00:00", "only_failed": true, "only_running": false, "include_subdags": true, "include_parentdag": true, "reset_dag_runs": true}' \--user "user1:user1"
注意,我这里的参数dry_run设置成false,而start_date和end_date这里设置成dag_run_id的开始时间,这样就可以唯一定位到一个dag_run_id了。
以上命令的例子是,把hello_world_dag的2021-10-19T06:37:45.156532+00:00实例(失败状态)重新设置成running,重新运行该实例。
删除一个dag运行实例
根据业务的需要,有时我们可能需要删除一个dag的运行实例。此时可以使用以下接口来实现:
https://airflow.apache.org/api/v1/dags/{dag_id}/dagRuns/{dag_run_id}
例如:
curl -X DELETE "http://127.0.0.1:20001/api/v1/dags/hello_world_dag/dagRuns/${dag_run_id}" \--header 'Content-Type: application/json' \--user "user1:user1"
小结
本文说明了airflow的一些重要的REST API的使用方法。包括:触发dag的执行,停止dag的实例,重启dag的实例,删除dag的运行实例,获取dag_run_id的信息等API。
通过这一组API,就可以通过REST接口来访问airflow,从而可以和其他产品模块解耦,实现一个产品级系统的调度模块。还有一个重要的问题,就是如何通过REST API来对任务传递参数,后面的文章会继续介绍。
历史版本REST API的使用频率比较高的几个测试用例:
- 手动触发DAG&&传参
POST /api/experimental/dags/<DAG_ID>/dag_runs
#================================
curl -X POST \
'http://localhost:8080/api/v1/dags/<DAG_ID>/dag_runs' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/json' \
--data '{"conf":"{\"key\":\"value\"}"}'
#需要传参时间EXE_DATE,不然可能报错
EXE_DATE=$(TZ=America/Curacao date '+%Y-%m-%dT%H:%M:%SZ')
curl -X POST 'http://localhost:20001/api/v1/dags/xhz_hello_world_dag/dagRuns' \
-d "{\"execution_date\": \"${EXE_DATE}\", \"conf\": {}}" \
-H 'content-type: application/json' \
--user "user1:user1"
传参序言在conf加入相关参数https://blog.csdn.net/zg_hover/article/details/121346068
EXE_DATE=$(TZ=America/Curacao date '+%Y-%m-%dT%H:%M:%SZ')
curl -X POST 'http://localhost:8080/api/v1/dags/airflow-xlx/dagRuns' \
-d "{\"execution_date\": \"${EXE_DATE}\", \"conf\": {\"param\":\"${param}\"}}" \
-H 'content-type: application/json' \
--user "user1:user1"
- 查询指定DAG的执行
GET /api/v1/dags/<DAG_ID>/dag_runs
- 查询指定TASK的状态
GET /api/v1/dags/<DAG_ID>/tasks/<TASK_ID>
- 手动停止DAG
GET /api/v1/dags/<DAG_ID>/paused/<string:paused> #停止时设置<string:paused>为'true'
编写脚本实现api批量执行
[root@airflow script]# cat 0001.sh
function trigger_target(){
local dag_id='';
local param='';
local mem='';
local opt;
local OPTIND;
local OPTARG;
func() {
echo "Usage:"
echo "trigger_target -d [tag_id] -o [option] -p [param] -m [mem_stress] "
echo "Description:"
echo "tag_id,the name of tag_id."
echo "option,the param's key"
echo "param,the param's value"
echo "mem_stress is or not true,dafault true "
return 2;
}
mem='flase'
while getopts ':d:p:o:m' OPT; do
case $OPT in
d) dag_id="$OPTARG";;
p) param="$OPTARG";;
o) option="$OPTARG";;
m) mem="true";;
h) func;;
?) func;;
esac
done
shift $((OPTIND-1));
# if [ $# -ne 0 ]; then
# func;
# echo "wrong args: '$@'";
# return 1;
# else
# if [ -z "$dag_id" ]; then
# echo "wrong args: '$@'";
# func;
# return 1;
# fi;
# fi;
echo $mem
EXE_DATE=$(TZ=America/Curacao date '+%Y-%m-%dT%H:%M:%SZ')
curl -X POST "http://localhost:8080/api/v1/dags/$dag_id/dagRuns" \
-d "{\"execution_date\": \"${EXE_DATE}\", \"conf\": {\"${option}\":\"${param}\",\"mem\":\"${mem}\"}}" \
-H 'content-type: application/json' \
--user "user1:user1"
}
执行
[root@airflow script]# trigger_target -d test-skip -p $i -o param test-skip
flase
{
"conf": {
"mem": "flase",
"param": "manual__2023-08-14T03:30:10+00:00"
},
"dag_id": "test-skip",
"dag_run_id": "manual__2023-08-14T03:59:02+00:00",
"data_interval_end": "2023-08-14T03:59:02+00:00",
"data_interval_start": "2023-08-14T03:59:02+00:00",
"end_date": null,
"execution_date": "2023-08-14T03:59:02+00:00",
"external_trigger": true,
"last_scheduling_decision": null,
"logical_date": "2023-08-14T03:59:02+00:00",
"note": null,
"run_type": "manual",
"start_date": null,
"state": "queued"
}
[root@airflow script]# trigger_target -d test-skip -p $i -o param -m test-skip
true
{
"conf": {
"mem": "true",
"param": "manual__2023-08-14T03:30:10+00:00"
},
"dag_id": "test-skip",
"dag_run_id": "manual__2023-08-14T03:59:03+00:00",
"data_interval_end": "2023-08-14T03:59:03+00:00",
"data_interval_start": "2023-08-14T03:59:03+00:00",
"end_date": null,
"execution_date": "2023-08-14T03:59:03+00:00",
"external_trigger": true,
"last_scheduling_decision": null,
"logical_date": "2023-08-14T03:59:03+00:00",
"note": null,
"run_type": "manual",
"start_date": null,
"state": "queued"
}
原文链接:https://blog.csdn.net/zg_hover/article/details/121318167
【airflow】通过RESTAPI外部触发DAG执行用例(Python)_airflow python api_Felier.的博客-CSDN博客
2 python 处理api请求
通过api获取响应数据
import requests
from requests.auth import HTTPBasicAuth
# http://172.17.106.9:8080/api/v1/dags/example_complex/dagRuns?limit=100
airflow_auth = HTTPBasicAuth('user1', 'user1')
def get_dag(dag_id,dag_run_id=None):
url = f"http://172.17.106.9:8080/api/v1/dags/{dag_id}/dagRuns?limit=100"
response = requests.request(method='GET', url=url, timeout=(10, 60), auth=airflow_auth)
# re = response.json()
# print(re)
data = response.json()
print(data)
print(data['dag_runs'][0]['state'])
print(data['total_entries'])
print('dag_run_id:',data['dag_runs'][0]['dag_run_id'])
# return data['dag_runs'][0]['dag_run_id']
get_dag(dag_id='example_complex')
输出:
{'dag_runs': [{'conf': {}, 'dag_id': 'example_complex', 'dag_run_id': 'manual__2024-07-17T07:50:28.591129+00:00', 'data_interval_end': '2024-07-17T07:50:28.591129+00:00', 'data_interval_start': '2024-07-17T07:50:28.591129+00:00', 'end_date': '2024-07-17T07:50:56.877806+00:00', 'execution_date': '2024-07-17T07:50:28.591129+00:00', 'external_trigger': True, 'last_scheduling_decision': '2024-07-17T07:50:56.866159+00:00', 'logical_date': '2024-07-17T07:50:28.591129+00:00', 'run_type': 'manual', 'start_date': '2024-07-17T07:50:29.787175+00:00', 'state': 'success'}], 'total_entries': 1}
success
1
dag_run_id: manual__2024-07-17T07:50:28.591129+00:00