From 3e2fecc68bb111e8d47b6e4f6b1b9c4ef1ef9261 Mon Sep 17 00:00:00 2001 From: Nathan Hadfield Date: Thu, 29 Jul 2021 18:10:08 +0100 Subject: [PATCH 1/3] Added the handling of paths in `template_fields_renderers` which enables information contained in dictionaries to be unpacked and rendered appropriately. --- .../google/cloud/operators/bigquery.py | 2 +- airflow/www/views.py | 47 ++++++++++++++++++- tests/www/views/test_views.py | 25 +++++++++- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/airflow/providers/google/cloud/operators/bigquery.py b/airflow/providers/google/cloud/operators/bigquery.py index 66980aee35cd2..4a0f6c007adc1 100644 --- a/airflow/providers/google/cloud/operators/bigquery.py +++ b/airflow/providers/google/cloud/operators/bigquery.py @@ -2196,7 +2196,7 @@ class BigQueryInsertJobOperator(BaseOperator): "impersonation_chain", ) template_ext = (".json",) - template_fields_renderers = {"configuration": "json"} + template_fields_renderers = {"configuration": "json", "configuration.query.query": "sql"} ui_color = BigQueryUIColors.QUERY.value def __init__( diff --git a/airflow/www/views.py b/airflow/www/views.py index 3769c1ac4f072..fdde56fc750be 100644 --- a/airflow/www/views.py +++ b/airflow/www/views.py @@ -279,6 +279,29 @@ def task_group_to_dict(task_group): } +def get_key_paths(input_dict): + """Return a list of dot-separated dictionary paths""" + for key, value in input_dict.items(): + if isinstance(value, dict): + for sub_key in get_key_paths(value): + yield '.'.join((key, sub_key)) + else: + yield key + + +def get_value_from_path(key_path, content): + """Return the value from a dictionary based on dot-separated path of keys""" + elem = content + for x in key_path.strip(".").split("."): + try: + x = int(x) + elem = elem[x] + except ValueError: + elem = elem.get(x) + + return elem + + def dag_edges(dag): """ Create the list of edges needed to construct the Graph view. @@ -995,11 +1018,31 @@ def rendered_templates(self): renderer = task.template_fields_renderers.get(template_field, template_field) if renderer in renderers: if isinstance(content, (dict, list)): - content = json.dumps(content, sort_keys=True, indent=4) - html_dict[template_field] = renderers[renderer](content) + json_content = json.dumps(content, sort_keys=True, indent=4) + html_dict[template_field] = renderers[renderer](json_content) + else: + html_dict[template_field] = renderers[renderer](content) else: html_dict[template_field] = Markup("
{}
").format(pformat(content)) + if isinstance(content, dict): + if template_field == 'op_kwargs': + for key, value in content.items(): + renderer = task.template_fields_renderers.get(key, key) + if renderer in renderers: + html_dict['.'.join([template_field, key])] = renderers[renderer](value) + else: + html_dict['.'.join([template_field, key])] = Markup( + "
{}
" + ).format(pformat(value)) + else: + for dict_keys in get_key_paths(content): + template_path = '.'.join((template_field, dict_keys)) + renderer = task.template_fields_renderers.get(template_path, template_path) + if renderer in renderers: + content_value = get_value_from_path(dict_keys, content) + html_dict[template_path] = renderers[renderer](content_value) + return self.render_template( 'airflow/ti_code.html', html_dict=html_dict, diff --git a/tests/www/views/test_views.py b/tests/www/views/test_views.py index ebb4f462a2985..a15f708e5f354 100644 --- a/tests/www/views/test_views.py +++ b/tests/www/views/test_views.py @@ -22,7 +22,7 @@ from airflow.configuration import initialize_config from airflow.plugins_manager import AirflowPlugin, EntryPointSource -from airflow.www.views import get_safe_url, truncate_task_duration +from airflow.www.views import get_key_paths, get_safe_url, get_value_from_path, truncate_task_duration from tests.test_utils.config import conf_vars from tests.test_utils.mock_plugins import mock_plugin_manager from tests.test_utils.www import check_content_in_response, check_content_not_in_response @@ -243,3 +243,26 @@ def get_task_instance(session, task): dagrun.refresh_from_db(session=session) # dagrun should be set to QUEUED assert dagrun.get_state() == State.QUEUED + + +TEST_CONTENT_DICT = {"key1": {"key2": "val2", "key3": "val3", "key4": {"key5": "val5"}}} + + +@pytest.mark.parametrize( + "test_content_dict, expected_paths", [(TEST_CONTENT_DICT, ("key1.key2", "key1.key3", "key1.key4.key5"))] +) +def test_generate_key_paths(test_content_dict, expected_paths): + for key_path in get_key_paths(test_content_dict): + assert key_path in expected_paths + + +@pytest.mark.parametrize( + "test_content_dict, test_key_path, expected_value", + [ + (TEST_CONTENT_DICT, "key1.key2", "val2"), + (TEST_CONTENT_DICT, "key1.key3", "val3"), + (TEST_CONTENT_DICT, "key1.key4.key5", "val5"), + ], +) +def test_get_value_from_path(test_content_dict, test_key_path, expected_value): + assert expected_value == get_value_from_path(test_key_path, test_content_dict) From 64dfc30282398f3eb7d6c8de61ac8d8355826d89 Mon Sep 17 00:00:00 2001 From: Nathan Hadfield Date: Mon, 2 Aug 2021 12:37:35 +0100 Subject: [PATCH 2/3] Updated how-to explaining template field renderer paths. --- docs/apache-airflow/howto/custom-operator.rst | 35 +++++++++++++++++- .../img/template_field_renderer_path.png | Bin 0 -> 64442 bytes 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 docs/apache-airflow/img/template_field_renderer_path.png diff --git a/docs/apache-airflow/howto/custom-operator.rst b/docs/apache-airflow/howto/custom-operator.rst index 8074bf534eb0a..09946a32cd9ae 100644 --- a/docs/apache-airflow/howto/custom-operator.rst +++ b/docs/apache-airflow/howto/custom-operator.rst @@ -195,7 +195,7 @@ with actual value. Note that Jinja substitutes the operator attributes and not t In the example, the ``template_fields`` should be ``['guest_name']`` and not ``['name']`` -Additionally you may provide ``template_fields_renderers`` dictionary which defines in what style the value +Additionally you may provide ``template_fields_renderers`` a dictionary which defines in what style the value from template field renders in Web UI. For example: .. code-block:: python @@ -208,12 +208,45 @@ from template field renders in Web UI. For example: super().__init__(**kwargs) self.request_body = request_body +In the situation where ``template_field`` is itself a dictionary, it is also possible to specify a +dot-separated key path to extract and render individual elements appropriately. For example: + +.. code-block:: python + class MyConfigOperator(BaseOperator): + template_fields = ["configuration"] + template_fields_renderers = { + "configuration": "json", + "configuration.query.sql": "sql", + } + + def __init__(self, configuration: dict, **kwargs) -> None: + super().__init__(**kwargs) + self.configuration = configuration +Then using this template as follows: + +.. code-block:: python + with dag: + config_task = MyConfigOperator( + task_id="task_id_1", + configuration={"query": {"job_id": "123", "sql": "select * from my_table"}}, + dag=dag, + ) + +This will result in the UI rendering ``configuration`` as json in addition to the value contained in the +configuration at ``query.sql`` to be rendered with the SQL lexer. + +.. image:: ../img/template_field_renderer_path.png + Currently available lexers: - bash - doc + - hql + - html + - jinja - json - md + - powershell - py - rst - sql diff --git a/docs/apache-airflow/img/template_field_renderer_path.png b/docs/apache-airflow/img/template_field_renderer_path.png new file mode 100644 index 0000000000000000000000000000000000000000..bbecf61ea5da05f3587f056b208c7cdcf26386e9 GIT binary patch literal 64442 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 literal 0 HcmV?d00001 From 7d7e77fa5b9f5824fbf7fa3b5a1661a925c998ca Mon Sep 17 00:00:00 2001 From: Nathan Hadfield Date: Mon, 2 Aug 2021 14:07:06 +0100 Subject: [PATCH 3/3] Updated how-to explaining template field renderer paths. --- docs/apache-airflow/howto/custom-operator.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/apache-airflow/howto/custom-operator.rst b/docs/apache-airflow/howto/custom-operator.rst index 09946a32cd9ae..25558f76458f5 100644 --- a/docs/apache-airflow/howto/custom-operator.rst +++ b/docs/apache-airflow/howto/custom-operator.rst @@ -212,6 +212,7 @@ In the situation where ``template_field`` is itself a dictionary, it is also pos dot-separated key path to extract and render individual elements appropriately. For example: .. code-block:: python + class MyConfigOperator(BaseOperator): template_fields = ["configuration"] template_fields_renderers = { @@ -222,9 +223,11 @@ dot-separated key path to extract and render individual elements appropriately. def __init__(self, configuration: dict, **kwargs) -> None: super().__init__(**kwargs) self.configuration = configuration + Then using this template as follows: .. code-block:: python + with dag: config_task = MyConfigOperator( task_id="task_id_1",