如何从Airflow SimpleHttpOperator GET请求访问响应

时间:2017-10-10 21:39:13

标签: airflow apache-airflow data-pipeline

我正在学习Airflow并且有一个简单的问题。以下是我的DAG,名为dog_retriever

import airflow
from airflow import DAG
from airflow.operators.http_operator import SimpleHttpOperator
from airflow.operators.sensors import HttpSensor
from datetime import datetime, timedelta
import json



default_args = {
    'owner': 'Loftium',
    'depends_on_past': False,
    'start_date': datetime(2017, 10, 9),
    'email': 'rachel@loftium.com',
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 3,
    'retry_delay': timedelta(minutes=3),
}

dag = DAG('dog_retriever',
    schedule_interval='@once',
    default_args=default_args)

t1 = SimpleHttpOperator(
    task_id='get_labrador',
    method='GET',
    http_conn_id='http_default',
    endpoint='api/breed/labrador/images',
    headers={"Content-Type": "application/json"},
    dag=dag)

t2 = SimpleHttpOperator(
    task_id='get_breeds',
    method='GET',
    http_conn_id='http_default',
    endpoint='api/breeds/list',
    headers={"Content-Type": "application/json"},
    dag=dag)

t2.set_upstream(t1)

作为测试Airflow的一种方法,我只是在这个非常简单的http://dog.ceo API中向某些端点发出两个GET请求。目标是学习如何处理通过Airflow检索的一些数据

执行正在运行 - 我的代码成功调用了任务t1和t2中的enpoints,我可以看到它们是按照我写的set_upstream规则以正确的顺序记录在Airflow UI中的。

我无法弄清楚如何访问这两个任务的json响应。看起来很简单,但我无法弄清楚。在SimpleHtttpOperator中,我看到了response_check的参数,但没有简单的打印,存储或查看json响应。

感谢。

2 个答案:

答案 0 :(得分:8)

因为这是SimpleHttpOperator,实际的json被推送到XCOM,你可以从那里得到它。以下是该操作的代码行:https://github.com/apache/incubator-airflow/blob/master/airflow/operators/http_operator.py#L87

您需要做的是设置xcom_push=True,因此您的第一个t1将是以下内容:

t1 = SimpleHttpOperator(
    task_id='get_labrador',
    method='GET',
    http_conn_id='http_default',
    endpoint='api/breed/labrador/images',
    headers={"Content-Type": "application/json"},
    xcom_push=True,
    dag=dag)

您应该能够在XCOM中找到return value的所有JSON,有关XCOM的更多详细信息,请访问:https://airflow.incubator.apache.org/concepts.html#xcoms

答案 1 :(得分:1)

我主要为尝试从流程中呼叫呼叫并接收任何的任何人添加此答案DAG活动产生的>数据。

要理解运行DAG需要HTTP POST,并且在Airflow中对此POST的响应硬编码的,这是重要 ,即在不更改Airflow代码本身的情况下, Airflow只会向请求过程返回状态代码和消息

Airflow似乎主要用于为ETL(提取,转换,加载)工作流,现有的 Airflow Operators (例如, SimpleHttpOperator,可以从RESTful Web服务获取数据,进行处理,然后使用其他运算符将其写入数据库,但不要在运行的HTTP POST响应中返回工作流程DAG。

即使操作员确实在响应中返回了这些数据,查看Airflow源代码也可以确认trigger_dag()方法不会检查或返回它:

apache_airflow_airflow_www_api_experimental_endpoints.py

apache_airflow_airflow_api_client_json_client.py

它只会返回以下确认消息:

Airflow DagRun Message Received in Orchestration Service

由于Airflow是开放源代码,因此我想我们可以修改trigger_dag()方法以返回数据,但随后我们将不得不维护分叉的代码库,而我们将无法使用云托管的Airflow- Google Cloud Platform上的Cloud Composer等基于服务的服务,因为其中不包括我们的修改。

更糟糕的是,Apache Airflow甚至没有正确返回其硬编码状态消息。

当我们成功 POST 到Airflow /dags/{DAG-ID}/dag_runs端点时,我们会收到“ 200 OK”响应,不是应有的“ 201 Created”响应。然后,Airflow会使用其“已创建...”状态消息对响应的内容主体进行“硬编码”。 标准,但是是在响应标头中返回新创建的资源的Uri ,而不是在正文中……这将使正文自由返回生成的任何数据/在创建过程中(或由此产生)聚集。

我将此缺陷归因于敏捷/ MVP驱动的“盲”(或我所说的“天真”)方法,该方法仅添加了所需的功能,而没有意识到并留有余地以供更多通用工具使用。由于 Airflow被绝大多数用于(和由)数据科学家(而非软件工程师)创建数据管道,因此 Airflow运营商可以使用其专有的内部数据来相互共享数据。 @Chengzhi的有用答案的XCom功能指出了(谢谢!)但是在任何情况下都不能将数据返回给启动DAG的请求者,即SimpleHttpOperator可以从第三方检索数据RESTful服务,可以与PythonOperator共享该数据(通过XCom),以丰富,聚合和/或转换它。然后,PythonOperator可以与将结果直接存储在数据库中的PostgresOperator共享其数据。但是结果永远无法返回到要求完成工作的流程中,即我们的编排服务,这使得Airflow在任何用例中都无济于事,只是由当前用户所驱动。

这里的收获(至少对我而言)是1)永远不要将过多的专业知识归于任何人或任何组织。 Apache是​​一个重要的组织,在软件开发中有着深厚的基础,但它们并不完美。 2)始终提防内部专有解决方案。开放,基于标准的解决方案已经从许多不同的角度进行了审查和审查,而不仅仅是一个角度。

我花了将近一个星期的时间去追寻不同的方式去做一件看起来非常简单和合理的事情。我希望这个答案可以节省其他人的时间。