Airflow REST API的使用

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值