Apache Airflow如何区分UI与API触发的DAG运行
问题根因
Apache Airflow 2.2.4版本存在原生字段赋值的逻辑缺陷:UI点击触发、API调用触发两类外部触发场景,不会给dag_run的run_type字段赋值差异化枚举值,两类场景下external_trigger都会被标记为True,run_type默认回退为scheduled,因此无法直接通过这两个原生字段判断触发来源。
可落地的区分方案
- 方案1:触发时注入自定义标识参数(生产环境首选,无版本兼容问题,准确率100%)
不需要依赖Airflow原生字段,在触发环节强制传入自定义来源标记即可:- UI触发:选择「Trigger DAG w/ config」入口触发,在弹出的配置JSON输入框中传入固定标识,例如
{"trigger_source": "ui"} - API触发:调用DAG运行接口时,在请求体的
conf参数中传入标识,例如{"trigger_source": "api"}
任务执行时直接通过context['dag_run'].conf.get('trigger_source')即可读取到触发来源,完全不受版本bug影响。
- UI触发:选择「Trigger DAG w/ config」入口触发,在弹出的配置JSON输入框中传入固定标识,例如
- 方案2:通过内置审计字段判断(无需改造触发端,适配2.2.4版本逻辑)
Airflow 2.2.4中两类触发场景的创建主体字段存在差异,可以直接读取dag_run的created_by属性判断,参考代码:def get_trigger_source(**context): dag_run = context['dag_run'] # UI触发为登录用户的前台操作,created_by会绑定对应用户对象 if dag_run.created_by and hasattr(dag_run.created_by, "username"): source = "ui" # 无用户上下文的API调用(比如服务账号Token、匿名接口调用),created_by字段为空 else: source = "api" return source注意:如果API调用使用绑定了平台个人用户的Token发起,
created_by同样会关联对应用户信息,这种场景下该方法失效,只能使用方案1区分。 - 方案3:升级版本使用原生支持的区分逻辑(长期方案)
Airflow 2.3及以上版本修复了该字段赋值bug:所有手动触发场景(含UI触发、API手动调用)的run_type会正确标记为manual,同时新增了专门的触发来源字段可以直接读取,不需要额外做兼容判断。如果业务允许版本升级,升级后直接使用原生字段即可。
内容的提问来源于stack exchange,提问作者Giulia Savorgnan
相关产品推荐
相关产品推荐

