This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 2605912870 add CLI notification commands to providers (#33116)
2605912870 is described below
commit 260591287052a9d6fe37e323e4a3cdb7be818e76
Author: Albert Olweny <[email protected]>
AuthorDate: Sun Aug 6 18:01:56 2023 +0300
add CLI notification commands to providers (#33116)
---------
Co-authored-by: res <okirialbert>
---
airflow/cli/cli_config.py | 6 ++++++
airflow/cli/commands/provider_command.py | 12 ++++++++++++
airflow/providers_manager.py | 28 ++++++++++++++++++++++++++++
scripts/in_container/verify_providers.py | 15 +++++++++++++++
tests/always/test_providers_manager.py | 5 +++++
5 files changed, 66 insertions(+)
diff --git a/airflow/cli/cli_config.py b/airflow/cli/cli_config.py
index 52ed700db7..7569e2ff58 100644
--- a/airflow/cli/cli_config.py
+++ b/airflow/cli/cli_config.py
@@ -1800,6 +1800,12 @@ PROVIDERS_COMMANDS = (
func=lazy_load_command("airflow.cli.commands.provider_command.executors_list"),
args=(ARG_OUTPUT, ARG_VERBOSE),
),
+ ActionCommand(
+ name="notifications",
+ help="Get information about notifications provided",
+
func=lazy_load_command("airflow.cli.commands.provider_command.notifications_list"),
+ args=(ARG_OUTPUT, ARG_VERBOSE),
+ ),
ActionCommand(
name="configs",
help="Get information about provider configuration",
diff --git a/airflow/cli/commands/provider_command.py
b/airflow/cli/commands/provider_command.py
index a55032d9f2..e3a57af781 100644
--- a/airflow/cli/commands/provider_command.py
+++ b/airflow/cli/commands/provider_command.py
@@ -101,6 +101,18 @@ def triggers_list(args):
)
+@suppress_logs_and_warning
+@providers_configuration_loaded
+def notifications_list(args):
+ AirflowConsole().print_as(
+ data=ProvidersManager().notification,
+ output=args.output,
+ mapper=lambda x: {
+ "notification_class_name": x,
+ },
+ )
+
+
@suppress_logs_and_warning
@providers_configuration_loaded
def connection_form_widget_list(args):
diff --git a/airflow/providers_manager.py b/airflow/providers_manager.py
index bba64e316e..0aa8ff170e 100644
--- a/airflow/providers_manager.py
+++ b/airflow/providers_manager.py
@@ -218,6 +218,13 @@ class TriggerInfo(NamedTuple):
integration_name: str
+class NotificationInfo(NamedTuple):
+ """Notification class and provider it comes from."""
+
+ notification_class_name: str
+ package_name: str
+
+
class PluginInfo(NamedTuple):
"""Plugin class, name and provider it comes from."""
@@ -426,6 +433,7 @@ class ProvidersManager(LoggingMixin, metaclass=Singleton):
self._provider_configs: dict[str, dict[str, Any]] = {}
self._api_auth_backend_module_names: set[str] = set()
self._trigger_info_set: set[TriggerInfo] = set()
+ self._notification_info_set: set[NotificationInfo] = set()
self._provider_schema_validator =
_create_provider_info_schema_validator()
self._customized_form_fields_schema_validator = (
_create_customized_form_field_behaviours_schema_validator()
@@ -528,6 +536,12 @@ class ProvidersManager(LoggingMixin, metaclass=Singleton):
"""Lazy initialization of providers executors information."""
self.initialize_providers_list()
self._discover_executors()
+
+ @provider_info_cache("notifications")
+ def initialize_providers_notifications(self):
+ """Lazy initialization of providers notifications information."""
+ self.initialize_providers_list()
+ self._discover_notifications()
@provider_info_cache("config")
def initialize_providers_configuration(self):
@@ -1025,6 +1039,14 @@ class ProvidersManager(LoggingMixin,
metaclass=Singleton):
e,
)
+ def _discover_notifications(self) -> None:
+ """Retrieves all notifications defined in the providers."""
+ for provider_package, provider in self._provider_dict.items():
+ if provider.data.get("notifications"):
+ for notification_class_name in provider.data["notifications"]:
+ if _correctness_check(provider_package,
notification_class_name, provider):
+
self._notification_info_set.add(notification_class_name)
+
def _discover_extra_links(self) -> None:
"""Retrieves all extra links defined in the providers."""
for provider_package, provider in self._provider_dict.items():
@@ -1101,6 +1123,12 @@ class ProvidersManager(LoggingMixin,
metaclass=Singleton):
)
)
+ @property
+ def notification(self) -> list[NotificationInfo]:
+ """Returns information about available providers notifications
class."""
+ self.initialize_providers_notifications()
+ return sorted(self._notification_info_set)
+
@property
def trigger(self) -> list[TriggerInfo]:
"""Returns information about available providers trigger class."""
diff --git a/scripts/in_container/verify_providers.py
b/scripts/in_container/verify_providers.py
index 08193a62db..c332423f12 100755
--- a/scripts/in_container/verify_providers.py
+++ b/scripts/in_container/verify_providers.py
@@ -52,6 +52,7 @@ class EntityType(Enum):
Hooks = "Hooks"
Secrets = "Secrets"
Trigger = "Trigger"
+ Notification = "Notification"
class EntityTypeSummary(NamedTuple):
@@ -83,6 +84,7 @@ ENTITY_NAMES = {
EntityType.Hooks: "Hooks",
EntityType.Secrets: "Secrets",
EntityType.Trigger: "Trigger",
+ EntityType.Notification: "Notification",
}
TOTALS: dict[EntityType, int] = {
@@ -92,6 +94,7 @@ TOTALS: dict[EntityType, int] = {
EntityType.Transfers: 0,
EntityType.Secrets: 0,
EntityType.Trigger: 0,
+ EntityType.Notification: 0,
}
OPERATORS_PATTERN = r".*Operator$"
@@ -101,6 +104,7 @@ SECRETS_PATTERN = r".*Backend$"
TRANSFERS_PATTERN = r".*To[A-Z0-9].*Operator$"
WRONG_TRANSFERS_PATTERN = r".*Transfer$|.*TransferOperator$"
TRIGGER_PATTERN = r".*Trigger$"
+NOTIFICATION_PATTERN = r".*Notification$"
ALL_PATTERNS = {
OPERATORS_PATTERN,
@@ -110,6 +114,7 @@ ALL_PATTERNS = {
TRANSFERS_PATTERN,
WRONG_TRANSFERS_PATTERN,
TRIGGER_PATTERN,
+ NOTIFICATION_PATTERN,
}
EXPECTED_SUFFIXES: dict[EntityType, str] = {
@@ -119,6 +124,7 @@ EXPECTED_SUFFIXES: dict[EntityType, str] = {
EntityType.Secrets: "Backend",
EntityType.Transfers: "Operator",
EntityType.Trigger: "Trigger",
+ EntityType.Notification: "Notification",
}
@@ -462,6 +468,7 @@ def get_package_class_summary(
from airflow.secrets import BaseSecretsBackend
from airflow.sensors.base import BaseSensorOperator
from airflow.triggers.base import BaseTrigger
+ from airflow.notifications.basenotifier import BaseNotifier
all_verified_entities: dict[EntityType, VerifiedEntities] = {
EntityType.Operators: find_all_entities(
@@ -522,6 +529,14 @@ def get_package_class_summary(
expected_class_name_pattern=TRIGGER_PATTERN,
unexpected_class_name_patterns=ALL_PATTERNS - {TRIGGER_PATTERN},
),
+ EntityType.Notification: find_all_entities(
+ imported_classes=imported_classes,
+ base_package=full_package_name,
+ sub_package_pattern_match=r".*\.notifications\..*",
+ ancestor_match=BaseNotifier,
+ expected_class_name_pattern=NOTIFICATION_PATTERN,
+ unexpected_class_name_patterns=ALL_PATTERNS -
{NOTIFICATION_PATTERN},
+ ),
}
for entity in EntityType:
print_wrong_naming(entity,
all_verified_entities[entity].wrong_entities)
diff --git a/tests/always/test_providers_manager.py
b/tests/always/test_providers_manager.py
index 7e05d1cfb1..afeab528e1 100644
--- a/tests/always/test_providers_manager.py
+++ b/tests/always/test_providers_manager.py
@@ -379,6 +379,11 @@ class TestProviderManager:
trigger_class_names = list(provider_manager.trigger)
assert len(trigger_class_names) > 10
+ def test_notification(self):
+ provider_manager = ProvidersManager()
+ notification_class_names = list(provider_manager.notification)
+ assert len(notification_class_names) > 5
+
@patch("airflow.providers_manager.import_string")
def test_optional_feature_no_warning(self, mock_importlib_import_string):
with self._caplog.at_level(logging.WARNING):