在Airflow HttpSensor运算符中使用python字符串替换和xcom_pull

时间:2019-05-21 02:00:41

标签: airflow apache-airflow-xcom

我有一个用例,其中Im在for循环内,并且需要动态填充HttpSensor任务中的字段

我尝试使用以下语法:

方法1失败:

s = 'sensor_task_sd_{0}'.format(d)
            sensor_task_sd = HttpSensor(
                task_id=s,
                http_conn_id='ss_api',
                endpoint="/rest/v1/pipeline/{{ti.xcom_pull(key='curr_ss_pipe_id', task_ids={})}}/status?rev=0".format(t),
                request_params={'X-Requested-By': 'abc_123'},
                response_check=lambda response: True if "FINISHED" in response.text else False,
                poke_interval=10,
                soft_fail=True,
                timeout=600,
                dag=dag_subdag,
                )

但是失败,因为在这一行:

endpoint="/rest/v1/pipeline/{{ti.xcom_pull(key='curr_ss_pipe_id', task_ids={})}}/status?rev=0".format(t)

我无法使用.format(t)代替python字符串。

相反,如果我对某些值进行硬编码,则上面的代码可以工作...例如,下面的代码可以正常工作:

方法2成功:

s = 'sensor_task_sd_{0}'.format(d)
sensor_task_sd = HttpSensor(
               task_id=s,
               http_conn_id='ss_api',
        endpoint="/rest/v1/pipeline/{{ti.xcom_pull(key='curr_ss_pipe_id', task_ids='start_pipeline_sd_campaignhistory')}}/status?rev=0",
        request_params={'X-Requested-By': 'abc_123'},
               response_check=lambda response: True if "FINISHED" in response.text else False,
               poke_interval=10,
               soft_fail=True,
               timeout=600,
               dag=dag_subdag)

我只是不明白这一点.....我尝试了各种技巧的组合来使其起作用,只是我并没有采用Iam用来保持代码动态的字符串插值。

所以我的问题很简单:

如何使HttpSensor操作符动态化?我不想在端点字符串(方法2样式)中对函数值进行硬编码,我想使用在运行时设置的值(方法1样式)。

如何使方法1起作用?

1 个答案:

答案 0 :(得分:0)

因此,Airflow使用Jinja对其字符串进行模板化,并且当您混合Jinja模板化和Python格式时,您需要“转义” Jinja所需的花括号,以便Python格式不会占用它们。为此,您需要将每个.format()调用以外的花括号加倍。

这应该为您提供所需的结果。

endpoint="/rest/v1/pipeline/{{{{ ti.xcom_pull(key='curr_ss_pipe_id', task_ids={}) }}}}/status?rev=0".format(t)

顺便说一句,以我使用f字符串(Python 3.6+)或命名格式参数的经验,如果您真的可以在将Airflow脚本中的二者混合使用时确实可以帮助提高代码清晰度。但是您仍然需要“转义”大括号。

f字符串:

endpoint=f"/rest/v1/pipeline/{{{{ ti.xcom_pull(key='curr_ss_pipe_id', task_ids={t})}} }}/status?rev=0"

命名格式参数:

endpoint="/rest/v1/pipeline/{{{{ ti.xcom_pull(key='curr_ss_pipe_id', task_ids={task_id}) }}}}/status?rev=0".format(task_id=t)

希望有帮助:)