Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding support for snippet type in slack api #43305

Merged
merged 2 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions providers/src/airflow/providers/slack/hooks/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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.")
Expand All @@ -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):
Expand Down
5 changes: 5 additions & 0 deletions providers/src/airflow/providers/slack/operators/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -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".
"""

Expand All @@ -219,6 +220,7 @@ class SlackAPIFileOperator(SlackAPIOperator):
"filetype",
"content",
"title",
"snippet_type",
)
ui_color = "#44BEDF"

Expand All @@ -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:
Expand All @@ -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):
Expand All @@ -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,
)
14 changes: 10 additions & 4 deletions providers/tests/slack/hooks/test_slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -543,14 +546,15 @@ 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,
file_uploads={
"content": '{"foo": "bar"}',
"filename": filename,
"title": title,
"snippet_type": filetype,
"snippet_type": snippet_type,
},
initial_comment=initial_comment,
)
Expand All @@ -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(
Expand All @@ -570,14 +575,15 @@ 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,
file_uploads={
"file": "/foo/bar/spam.egg",
"filename": filename or "spam.egg",
"title": title,
"snippet_type": filetype,
"snippet_type": snippet_type,
},
initial_comment=initial_comment,
)
Expand Down
17 changes: 15 additions & 2 deletions providers/tests/slack/operators/test_slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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):
Expand All @@ -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"])
Expand All @@ -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,
Expand All @@ -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({})
Expand All @@ -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"])
Expand All @@ -267,7 +275,10 @@ 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,
Expand All @@ -276,6 +287,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({})
Expand All @@ -286,6 +298,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):
Expand Down