Hi in my Airflow DAG I'd like to set some arguments to values directly from the conf --conf parameters, i.e.,
{{ dag_run.conf['key'] }}
#or
context['dag_run'].conf['key']
For example, if I have a DAG that involves emailing a recipient address and I want to assign the recipient address in the 'to' argument of the EmailOperator task from conf. I found that I can accomplish this using logic involving Variable.set() and Variable.get() in a PythonOperator.
with DAG("my-dag") as dag:
ping = SimpleHttpOperator(endpoint="http://example.com/update/")
email = EmailOperator(to="admin@example.com", subject="Update complete")
ping >> email
def conf_func(**context):
Variable.set("email_address", context["dag_run"].conf["email_address"])
with DAG("my-dag") as dag:
ping = SimpleHttpOperator(endpoint="http://example.com/update/")
set_variable = PythonOperator(python_callable = conf_func, provide_context = True)
email = EmailOperator(to=Variable.get("email_address"), subject="Update complete")
ping >> set_variable >> email
However, some folks on Stackoverflow have pointed out that using Variable in this fashion is a bad practice. Since the Airflow Variable is not local/specific to each DAG run, it looks like you can have issues if you have multiple runs of the same DAG that set/retrieve different values from the same Variable key. I'm guessing bad things also happens if you have different DAGs that call the same Variable.
That being said, are there any better ways to pass values from dag_run conf into the parameter fields of Airflow tasks? (Values that may also include JSON objects other than strings, like lists and dictionaries?)
Edit: Update to include code for custom operator from this post:
class ExtenedK8sPodOperator(KubernetesPodOperator):
template_fields = (*KubernetesPodOperator.template_fields, 'volumes', 'volume_mounts', 'V1Toleration')
def __init__(self, **kwargs):
vols = kwargs.get('volumes', [])
for vol in vols:
vol.template_fields = ('name')
kwargs['volumes'] = vols
vol_mounts = kwargs.get('volume_mounts', [])
for vol_mount in vol_mounts:
vol_mount.template_fields = ('name')
kwargs['volume_mounts'] = v
super().__init__(**kwargs)