From f0c16079c0d5b08ed658fbf6aebc64bc771e90e8 Mon Sep 17 00:00:00 2001 From: Bowrna Date: Wed, 23 Oct 2024 13:27:39 +0530 Subject: [PATCH 1/2] adding support for snippet type in slack api --- .../src/airflow/providers/slack/hooks/slack.py | 8 +++++--- .../airflow/providers/slack/operators/slack.py | 5 +++++ providers/tests/slack/hooks/test_slack.py | 14 ++++++++++---- providers/tests/slack/operators/test_slack.py | 15 +++++++++++++-- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/providers/src/airflow/providers/slack/hooks/slack.py b/providers/src/airflow/providers/slack/hooks/slack.py index f0193a437e30d..3c696230131c1 100644 --- a/providers/src/airflow/providers/slack/hooks/slack.py +++ b/providers/src/airflow/providers/slack/hooks/slack.py @@ -203,6 +203,7 @@ def send_file( filetype: str | None = None, initial_comment: str | None = None, title: str | None = None, + **kwargs, ) -> SlackResponse: """ Create or upload an existing file. @@ -295,7 +296,8 @@ def send_file_v1_to_v2( filename: str | None = None, initial_comment: str | None = None, title: str | None = None, - filetype: str | None = None, + snippet_type: str | None = None, + **kwargs, ) -> list[SlackResponse]: """ Smooth transition between ``send_file`` and ``send_file_v2`` methods. @@ -308,7 +310,7 @@ def send_file_v1_to_v2( :param filename: Displayed filename. :param initial_comment: The message text introducing the file in specified ``channels``. :param title: Title of the file. - :param filetype: A file type identifier. + :param snippet_type: Syntax type for the content being uploaded. """ if not exactly_one(file, content): raise ValueError("Either `file` or `content` must be provided, not both.") @@ -318,7 +320,7 @@ def send_file_v1_to_v2( else: file_uploads = {"content": content, "filename": filename} - file_uploads.update({"title": title, "snippet_type": filetype}) + file_uploads.update({"title": title, "snippet_type": snippet_type}) if channels: if isinstance(channels, str): diff --git a/providers/src/airflow/providers/slack/operators/slack.py b/providers/src/airflow/providers/slack/operators/slack.py index 64be693af67e4..88644726e27a6 100644 --- a/providers/src/airflow/providers/slack/operators/slack.py +++ b/providers/src/airflow/providers/slack/operators/slack.py @@ -209,6 +209,7 @@ class SlackAPIFileOperator(SlackAPIOperator): :param filetype: slack filetype. (templated) See: https://api.slack.com/types/file#file_types :param content: file content. (templated) :param title: title of file. (templated) + :param snippet_type: Syntax type for the snippet being uploaded.(templated) :param method_version: The version of the method of Slack SDK Client to be used, either "v1" or "v2". """ @@ -219,6 +220,7 @@ class SlackAPIFileOperator(SlackAPIOperator): "filetype", "content", "title", + "snippet_type", ) ui_color = "#44BEDF" @@ -232,6 +234,7 @@ def __init__( title: str | None = None, method_version: Literal["v1", "v2"] = "v2", channel: str | Sequence[str] | None | ArgNotSet = NOTSET, + snippet_type: str | None = None, **kwargs, ) -> None: if channel is not NOTSET: @@ -253,6 +256,7 @@ def __init__( self.content = content self.title = title self.method_version = method_version + self.snippet_type = snippet_type @property def _method_resolver(self): @@ -269,4 +273,5 @@ def execute(self, context: Context): content=self.content, initial_comment=self.initial_comment, title=self.title, + snippet_type=self.snippet_type, ) diff --git a/providers/tests/slack/hooks/test_slack.py b/providers/tests/slack/hooks/test_slack.py index 35dfa5200b7fa..10e5a094e9d8f 100644 --- a/providers/tests/slack/hooks/test_slack.py +++ b/providers/tests/slack/hooks/test_slack.py @@ -533,7 +533,10 @@ def test_send_file_v2_channel_name(self, mocked_client, caplog): @pytest.mark.parametrize("filename", [None, "foo.bar"]) @pytest.mark.parametrize("channel", [None, "#random"]) @pytest.mark.parametrize("filetype", [None, "auto"]) - def test_send_file_v1_to_v2_content(self, initial_comment, title, filename, channel, filetype): + @pytest.mark.parametrize("snippet_type", [None, "text"]) + def test_send_file_v1_to_v2_content( + self, initial_comment, title, filename, channel, filetype, snippet_type + ): hook = SlackHook(slack_conn_id=SLACK_API_DEFAULT_CONN_ID) with mock.patch.object(SlackHook, "send_file_v2") as mocked_send_file_v2: hook.send_file_v1_to_v2( @@ -543,6 +546,7 @@ def test_send_file_v1_to_v2_content(self, initial_comment, title, filename, chan initial_comment=initial_comment, title=title, filetype=filetype, + snippet_type=snippet_type, ) mocked_send_file_v2.assert_called_once_with( channel_id=channel, @@ -550,7 +554,7 @@ def test_send_file_v1_to_v2_content(self, initial_comment, title, filename, chan "content": '{"foo": "bar"}', "filename": filename, "title": title, - "snippet_type": filetype, + "snippet_type": snippet_type, }, initial_comment=initial_comment, ) @@ -560,7 +564,8 @@ def test_send_file_v1_to_v2_content(self, initial_comment, title, filename, chan @pytest.mark.parametrize("filename", [None, "foo.bar"]) @pytest.mark.parametrize("channel", [None, "#random"]) @pytest.mark.parametrize("filetype", [None, "auto"]) - def test_send_file_v1_to_v2_file(self, initial_comment, title, filename, channel, filetype): + @pytest.mark.parametrize("snippet_type", [None, "text"]) + def test_send_file_v1_to_v2_file(self, initial_comment, title, filename, channel, filetype, snippet_type): hook = SlackHook(slack_conn_id=SLACK_API_DEFAULT_CONN_ID) with mock.patch.object(SlackHook, "send_file_v2") as mocked_send_file_v2: hook.send_file_v1_to_v2( @@ -570,6 +575,7 @@ def test_send_file_v1_to_v2_file(self, initial_comment, title, filename, channel initial_comment=initial_comment, title=title, filetype=filetype, + snippet_type=snippet_type, ) mocked_send_file_v2.assert_called_once_with( channel_id=channel, @@ -577,7 +583,7 @@ def test_send_file_v1_to_v2_file(self, initial_comment, title, filename, channel "file": "/foo/bar/spam.egg", "filename": filename or "spam.egg", "title": title, - "snippet_type": filetype, + "snippet_type": snippet_type, }, initial_comment=initial_comment, ) diff --git a/providers/tests/slack/operators/test_slack.py b/providers/tests/slack/operators/test_slack.py index f3b02839a3e55..9ce4ac661ef1d 100644 --- a/providers/tests/slack/operators/test_slack.py +++ b/providers/tests/slack/operators/test_slack.py @@ -201,6 +201,7 @@ def setup_method(self): self.test_content = "This is a test text file!" self.test_api_params = {"key": "value"} self.expected_method = "files.upload" + self.test_snippet_type = "text" def __construct_operator(self, test_slack_conn_id, test_api_params=None): return SlackAPIFileOperator( @@ -212,6 +213,7 @@ def __construct_operator(self, test_slack_conn_id, test_api_params=None): filetype=self.test_filetype, content=self.test_content, api_params=test_api_params, + snippet_type=self.test_snippet_type, ) def test_init_with_valid_params(self): @@ -226,6 +228,7 @@ def test_init_with_valid_params(self): assert slack_api_post_operator.filename == self.filename assert slack_api_post_operator.filetype == self.test_filetype assert slack_api_post_operator.content == self.test_content + assert slack_api_post_operator.snippet_type == self.test_snippet_type assert not hasattr(slack_api_post_operator, "token") @pytest.mark.parametrize("initial_comment", [None, "foo-bar"]) @@ -237,7 +240,10 @@ def test_init_with_valid_params(self): pytest.param("v2", "send_file_v1_to_v2", id="v2"), ], ) - def test_api_call_params_with_content_args(self, initial_comment, title, method_version, method_name): + @pytest.mark.parametrize("snippet_type", [None, "text"]) + def test_api_call_params_with_content_args( + self, initial_comment, title, method_version, method_name, snippet_type + ): op = SlackAPIFileOperator( task_id="slack", slack_conn_id=SLACK_API_TEST_CONNECTION_ID, @@ -246,6 +252,7 @@ def test_api_call_params_with_content_args(self, initial_comment, title, method_ initial_comment=initial_comment, title=title, method_version=method_version, + snippet_type=snippet_type, ) with mock.patch(f"airflow.providers.slack.operators.slack.SlackHook.{method_name}") as mock_send_file: op.execute({}) @@ -256,6 +263,7 @@ def test_api_call_params_with_content_args(self, initial_comment, title, method_ filetype=None, initial_comment=initial_comment, title=title, + snippet_type=snippet_type, ) @pytest.mark.parametrize("initial_comment", [None, "foo-bar"]) @@ -267,7 +275,8 @@ def test_api_call_params_with_content_args(self, initial_comment, title, method_ pytest.param("v2", "send_file_v1_to_v2", id="v2"), ], ) - def test_api_call_params_with_file_args(self, initial_comment, title, method_version, method_name): + @pytest.mark.parametrize("snippet_type", [None, "text"]) + def test_api_call_params_with_file_args(self, initial_comment, title, method_version, method_name, snippet_type): op = SlackAPIFileOperator( task_id="slack", slack_conn_id=SLACK_API_TEST_CONNECTION_ID, @@ -276,6 +285,7 @@ def test_api_call_params_with_file_args(self, initial_comment, title, method_ver initial_comment=initial_comment, title=title, method_version=method_version, + snippet_type=snippet_type, ) with mock.patch(f"airflow.providers.slack.operators.slack.SlackHook.{method_name}") as mock_send_file: op.execute({}) @@ -286,6 +296,7 @@ def test_api_call_params_with_file_args(self, initial_comment, title, method_ver filetype=None, initial_comment=initial_comment, title=title, + snippet_type=snippet_type, ) def test_channel_deprecated(self): From 6c32441996ecb972df2598a031af7252b811d6c1 Mon Sep 17 00:00:00 2001 From: Bowrna Date: Thu, 24 Oct 2024 14:11:43 +0530 Subject: [PATCH 2/2] static fix --- providers/tests/slack/operators/test_slack.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/providers/tests/slack/operators/test_slack.py b/providers/tests/slack/operators/test_slack.py index 9ce4ac661ef1d..7f2d316387b2a 100644 --- a/providers/tests/slack/operators/test_slack.py +++ b/providers/tests/slack/operators/test_slack.py @@ -276,7 +276,9 @@ def test_api_call_params_with_content_args( ], ) @pytest.mark.parametrize("snippet_type", [None, "text"]) - def test_api_call_params_with_file_args(self, initial_comment, title, method_version, method_name, snippet_type): + def test_api_call_params_with_file_args( + self, initial_comment, title, method_version, method_name, snippet_type + ): op = SlackAPIFileOperator( task_id="slack", slack_conn_id=SLACK_API_TEST_CONNECTION_ID,