用于HTTPS的气流SimpleHttpOperator

时间:2018-08-01 09:54:39

标签: https airflow

我正在尝试使用SimpleHttpOperator来使用RESTful API。但是,顾名思义,它仅支持需要消耗HTTPS URI的HTTP协议。因此,现在,我必须使用来自Python的“ requests”对象或处理应用程序代码中的调用。但是,这可能不是标准方法。因此,我正在寻找可用于从Airflow内部使用HTTPS URI的任何其他选项。谢谢。

5 个答案:

答案 0 :(得分:2)

我对此很感兴趣,并且可以肯定的是,这种行为是气流中的错误。我在这里为此创建了一个票证: https://issues.apache.org/jira/browse/AIRFLOW-2910

目前,您能做的最好的事情是重写SimpleHttpOperator以及HttpHook,以更改HttpHook.get_conn的工作方式(接受https)。我可能最终会这样做,如果可以,我会发布一些代码。

更新:

操作员优先:

from airflow.operators.http_operator import SimpleHttpOperator
from airflow.exceptions import AirflowException
from operators.https_support.https_hook import HttpsHook


class HttpsOperator(SimpleHttpOperator):
    def execute(self, context):
        http = HttpsHook(self.method, http_conn_id=self.http_conn_id)

        self.log.info("Calling HTTP method")

        response = http.run(self.endpoint,
                            self.data,
                            self.headers,
                            self.extra_options)
        if self.response_check:
            if not self.response_check(response):
                raise AirflowException("Response check returned False.")
        if self.xcom_push_flag:
            return response.text

挂钩替代

from airflow.hooks.http_hook import HttpHook
import requests


class HttpsHook(HttpHook):
    def get_conn(self, headers):
        """
        Returns http session for use with requests. Supports https.
        """
        conn = self.get_connection(self.http_conn_id)
        session = requests.Session()

        if "://" in conn.host:
            self.base_url = conn.host
        elif conn.schema:
            self.base_url = conn.schema + "://" + conn.host
        elif conn.conn_type:  # https support
            self.base_url = conn.conn_type + "://" + conn.host
        else:
            # schema defaults to HTTP
            self.base_url = "http://" + conn.host

        if conn.port:
            self.base_url = self.base_url + ":" + str(conn.port) + "/"
        if conn.login:
            session.auth = (conn.login, conn.password)
        if headers:
            session.headers.update(headers)

        return session

用法:

SimpleHttpOperator的直接替换。

答案 1 :(得分:1)

这已经有两个月了,但是值得的是,在Airflow 1.10.2上进行HTTPS调用没有任何问题。

在我的初始测试中,我从sendgrid请求模板,因此连接是这样建立的:

Conn Id   : sendgrid_templates_test
Conn Type : HTTP   
Host      :   https://api.sendgrid.com/
Extra     : { "authorization": "Bearer [my token]"}

,然后在dag代码中:

get_templates = SimpleHttpOperator(
        task_id='get_templates',
        method='GET',
        endpoint='/v3/templates',
        http_conn_id = 'sendgrid_templates_test',
        trigger_rule="all_done",
        xcom_push=True
        dag=dag,
    )

,并且有效。还要注意,我的请求发生在分支运算符之后,因此我需要适当设置触发规则(设置为“ all_done”,以确保即使跳过了一个分支也能触发),这与问题无关,但是我只是想指出这一点。

现在要弄清楚,由于没有启用证书验证,因此我收到了不安全请求警告。但是您可以在下面看到生成的日志

[2019-02-21 16:15:01,333] {http_operator.py:89} INFO - Calling HTTP method
[2019-02-21 16:15:01,336] {logging_mixin.py:95} INFO - [2019-02-21 16:15:01,335] {base_hook.py:83} INFO - Using connection to: id: sendgrid_templates_test. Host:  https://api.sendgrid.com/, Port: None, Schema: None, Login: None, Password: XXXXXXXX, extra: {'authorization': 'Bearer [my token]'}
[2019-02-21 16:15:01,338] {logging_mixin.py:95} INFO - [2019-02-21 16:15:01,337] {http_hook.py:126} INFO - Sending 'GET' to url:  https://api.sendgrid.com//v3/templates
[2019-02-21 16:15:01,956] {logging_mixin.py:95} WARNING - /home/csconnell/.pyenv/versions/airflow/lib/python3.6/site-packages/urllib3/connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
[2019-02-21 16:15:05,242] {logging_mixin.py:95} INFO - [2019-02-21 16:15:05,241] {jobs.py:2527} INFO - Task exited with return code 0

答案 2 :(得分:0)

除了实现HttpsHook之外,我们还可以将一行代码放入HttpsOperator(SimpleHttpOperator)@above中,如下所示

...

self.extra_options['verify'] = True

response = http.run(self.endpoint,
                        self.data,
                        self.headers,
                        self.extra_options)
...

答案 3 :(得分:0)

当尝试使用环境变量设置连接时,我在HTTP / HTTPS上也遇到了同样的问题(尽管当我在UI上设置连接时,它可以工作)。

我已经检查了已打开(<{> 3)的问题 @ melchoir55 ,并且您无需为此创建自定义运算符,问题不在于HttpHook或HttpOperator可以使用HTTPS时,问题在于get_hook处理HTTP时解析连接字符串的方式,它实际上理解第一部分(http://或https://)是连接类型。

总而言之,您不需要自定义运算符,只需在环境中将连接设置如下:

AIRFLOW_CONN_HTTP_EXAMPLE=http://https%3a%2f%2fexample.com/

代替:

AIRFLOW_CONN_HTTP_EXAMPLE=https://example.com/

或在用户界面上设置连接。

这不是建立连接的直观方法,但我认为他们正在研究一种更好的方法来解析Ariflow 2.0的连接。

答案 4 :(得分:0)

在 Airflow 2 中,问题已解决。 只需检查一下:

  • host 连接 UI 表单中的名称,不要以 / 结尾
  • SimpleHttpOperator 的“端点”参数以 / 开头