diff --git a/devel-common/src/sphinx_exts/operators_and_hooks_ref.py b/devel-common/src/sphinx_exts/operators_and_hooks_ref.py index 097e2029df0e8..61a82a1f44faf 100644 --- a/devel-common/src/sphinx_exts/operators_and_hooks_ref.py +++ b/devel-common/src/sphinx_exts/operators_and_hooks_ref.py @@ -29,10 +29,11 @@ from docutils import nodes from docutils.parsers.rst import Directive, directives from docutils.statemachine import StringList -from provider_yaml_utils import get_all_provider_yaml_paths, load_package_data from sphinx.util import nested_parse_with_titles from sphinx.util.docutils import switch_source_input +from sphinx_exts.provider_yaml_utils import get_all_provider_yaml_paths, load_package_data + if TYPE_CHECKING: from docutils.nodes import Element @@ -106,6 +107,7 @@ def _prepare_operators_data(tags: set[str] | None): all_operators_by_integration = _prepare_resource_index(package_data, "operators") all_hooks_by_integration = _prepare_resource_index(package_data, "hooks") all_sensors_by_integration = _prepare_resource_index(package_data, "sensors") + all_triggers_by_integration = _prepare_resource_index(package_data, "triggers") results = [] for integration in to_display_integration: @@ -115,6 +117,7 @@ def _prepare_operators_data(tags: set[str] | None): operators = all_operators_by_integration.get(integration["integration-name"]) sensors = all_sensors_by_integration.get(integration["integration-name"]) hooks = all_hooks_by_integration.get(integration["integration-name"]) + triggers = all_triggers_by_integration.get(integration["integration-name"]) if "how-to-guide" in item["integration"]: item["integration"]["how-to-guide"] = [_docs_path(d) for d in item["integration"]["how-to-guide"]] @@ -124,7 +127,9 @@ def _prepare_operators_data(tags: set[str] | None): item["sensors"] = sensors if hooks: item["hooks"] = hooks - if operators or sensors or hooks: + if triggers: + item["triggers"] = triggers + if operators or sensors or hooks or triggers: results.append(item) return sorted(results, key=lambda d: d["integration"]["integration-name"].lower()) diff --git a/devel-common/src/sphinx_exts/templates/operators_and_hooks_ref.rst.jinja2 b/devel-common/src/sphinx_exts/templates/operators_and_hooks_ref.rst.jinja2 index f71e945eba32c..a1b019240b8e7 100644 --- a/devel-common/src/sphinx_exts/templates/operators_and_hooks_ref.rst.jinja2 +++ b/devel-common/src/sphinx_exts/templates/operators_and_hooks_ref.rst.jinja2 @@ -29,6 +29,9 @@ {%- if "sensors" in item %} :Sensors: {% for python_module in item["sensors"]["python-modules"] %}:mod:`{{ python_module }}`{% if not loop.last %}, {% else %}.{% endif %}{%- endfor %} {%- endif %} +{%- if "triggers" in item %} +:Triggers: {% for python_module in item["triggers"]["python-modules"] %}:mod:`{{ python_module }}`{% if not loop.last %}, {% else %}.{% endif %}{%- endfor %} +{%- endif %} {%- if 'how-to-guide' in item["integration"] %} :Guides: {% for guide in item["integration"]['how-to-guide'] %}:doc:`{{ guide }}`{% if not loop.last %}, {% else %}.{% endif %}{%- endfor %} {%- endif %} diff --git a/devel-common/tests/unit/sphinx_exts/test_operators_and_hooks_ref.py b/devel-common/tests/unit/sphinx_exts/test_operators_and_hooks_ref.py new file mode 100644 index 0000000000000..188f01d02b675 --- /dev/null +++ b/devel-common/tests/unit/sphinx_exts/test_operators_and_hooks_ref.py @@ -0,0 +1,48 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +from unittest import mock + +from sphinx_exts.operators_and_hooks_ref import _render_operator_content + + +@mock.patch("sphinx_exts.operators_and_hooks_ref.load_package_data", autospec=True) +def test_render_operator_content_includes_trigger_only_integrations(mock_load_package_data): + mock_load_package_data.return_value = [ + { + "package-name": "apache-airflow-providers-example", + "integrations": [ + { + "integration-name": "Example", + "external-doc-url": "https://example.com", + } + ], + "triggers": [ + { + "integration-name": "Example", + "python-modules": ["airflow.providers.example.triggers.example"], + } + ], + } + ] + + rendered = _render_operator_content(tags=None, header_separator="=") + + assert "Example" in rendered + assert ":Triggers: :mod:`airflow.providers.example.triggers.example`." in rendered + assert ":Provider: :provider:`apache-airflow-providers-example`" in rendered