From 1ebd166a51c29fa25b927a2d6c8196d84a8ea986 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 14 May 2026 17:50:22 -0700 Subject: [PATCH 1/5] feat: add highlight_type to files.completeUploadExternal and files_upload_v2 Co-Authored-By: Claude --- slack_sdk/web/async_client.py | 4 +++- slack_sdk/web/client.py | 4 +++- slack_sdk/web/internal_utils.py | 1 + slack_sdk/web/legacy_client.py | 4 +++- tests/slack_sdk/web/test_internal_utils.py | 7 +++++++ 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/slack_sdk/web/async_client.py b/slack_sdk/web/async_client.py index 97ab3855b..87db1774c 100644 --- a/slack_sdk/web/async_client.py +++ b/slack_sdk/web/async_client.py @@ -4037,6 +4037,7 @@ async def files_upload_v2( title: Optional[str] = None, alt_txt: Optional[str] = None, snippet_type: Optional[str] = None, + highlight_type: Optional[str] = None, # To upload multiple files at a time file_uploads: Optional[List[Dict[str, Any]]] = None, channel: Optional[str] = None, @@ -4081,6 +4082,7 @@ async def files_upload_v2( "title": title, "alt_txt": alt_txt, "snippet_type": snippet_type, + "highlight_type": highlight_type, } ) files.append(f) @@ -4118,7 +4120,7 @@ async def files_upload_v2( # step3: files.completeUploadExternal with all the sets of (file_id + title) completion = await self.files_completeUploadExternal( - files=[{"id": f["file_id"], "title": f["title"]} for f in files], + files=[{"id": f["file_id"], "title": f["title"], "highlight_type": f.get("highlight_type")} for f in files], channel_id=channel, channels=channels, initial_comment=initial_comment, diff --git a/slack_sdk/web/client.py b/slack_sdk/web/client.py index 5339db491..f0eba239e 100644 --- a/slack_sdk/web/client.py +++ b/slack_sdk/web/client.py @@ -4027,6 +4027,7 @@ def files_upload_v2( title: Optional[str] = None, alt_txt: Optional[str] = None, snippet_type: Optional[str] = None, + highlight_type: Optional[str] = None, # To upload multiple files at a time file_uploads: Optional[List[Dict[str, Any]]] = None, channel: Optional[str] = None, @@ -4071,6 +4072,7 @@ def files_upload_v2( "title": title, "alt_txt": alt_txt, "snippet_type": snippet_type, + "highlight_type": highlight_type, } ) files.append(f) @@ -4108,7 +4110,7 @@ def files_upload_v2( # step3: files.completeUploadExternal with all the sets of (file_id + title) completion = self.files_completeUploadExternal( - files=[{"id": f["file_id"], "title": f["title"]} for f in files], + files=[{"id": f["file_id"], "title": f["title"], "highlight_type": f.get("highlight_type")} for f in files], channel_id=channel, channels=channels, initial_comment=initial_comment, diff --git a/slack_sdk/web/internal_utils.py b/slack_sdk/web/internal_utils.py index ad23f87f8..8dc78a840 100644 --- a/slack_sdk/web/internal_utils.py +++ b/slack_sdk/web/internal_utils.py @@ -379,6 +379,7 @@ def _to_v2_file_upload_item(upload_file: Dict[str, Any]) -> Dict[str, Optional[A "title": title, "alt_txt": upload_file.get("alt_txt"), "snippet_type": upload_file.get("snippet_type"), + "highlight_type": upload_file.get("highlight_type"), } diff --git a/slack_sdk/web/legacy_client.py b/slack_sdk/web/legacy_client.py index db785bbbc..7f9e1ad66 100644 --- a/slack_sdk/web/legacy_client.py +++ b/slack_sdk/web/legacy_client.py @@ -3962,6 +3962,7 @@ def files_upload_v2( title: Optional[str] = None, alt_txt: Optional[str] = None, snippet_type: Optional[str] = None, + highlight_type: Optional[str] = None, # To upload multiple files at a time file_uploads: Optional[List[Dict[str, Any]]] = None, channel: Optional[str] = None, @@ -4006,6 +4007,7 @@ def files_upload_v2( "title": title, "alt_txt": alt_txt, "snippet_type": snippet_type, + "highlight_type": highlight_type, } ) files.append(f) @@ -4043,7 +4045,7 @@ def files_upload_v2( # step3: files.completeUploadExternal with all the sets of (file_id + title) completion = self.files_completeUploadExternal( - files=[{"id": f["file_id"], "title": f["title"]} for f in files], + files=[{"id": f["file_id"], "title": f["title"], "highlight_type": f.get("highlight_type")} for f in files], channel_id=channel, channels=channels, initial_comment=initial_comment, diff --git a/tests/slack_sdk/web/test_internal_utils.py b/tests/slack_sdk/web/test_internal_utils.py index 3e44f0c9c..e8456b471 100644 --- a/tests/slack_sdk/web/test_internal_utils.py +++ b/tests/slack_sdk/web/test_internal_utils.py @@ -133,6 +133,13 @@ def test_files_upload_v2_issue_1356(self): file_io_item = _to_v2_file_upload_item({"file": file_io, "filename": "foo.txt"}) assert file_io_item.get("filename") == "foo.txt" + def test_to_v2_file_upload_item_passes_through_highlight_type(self): + item = _to_v2_file_upload_item({"content": "test", "filename": "image.png", "highlight_type": "png"}) + assert item.get("highlight_type") == "png" + + item_without = _to_v2_file_upload_item({"content": "test", "filename": "image.png"}) + assert item_without.get("highlight_type") is None + def test_to_v2_file_upload_item_can_accept_file_as_path(self): filepath = "tests/slack_sdk/web/test_internal_utils.py" upload_item_str = _to_v2_file_upload_item({"file": filepath}) From 6d1f1de99998e96ebf0cb7a42e69ff89175ba0e3 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 14 May 2026 19:00:10 -0700 Subject: [PATCH 2/5] fix: resolve mypy type error for highlight_type in files dict Co-Authored-By: Claude --- slack_sdk/web/async_client.py | 8 +++++++- slack_sdk/web/client.py | 8 +++++++- slack_sdk/web/legacy_client.py | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/slack_sdk/web/async_client.py b/slack_sdk/web/async_client.py index 87db1774c..0af839254 100644 --- a/slack_sdk/web/async_client.py +++ b/slack_sdk/web/async_client.py @@ -4119,8 +4119,14 @@ async def files_upload_v2( raise e.SlackRequestError(message) # step3: files.completeUploadExternal with all the sets of (file_id + title) + complete_files = [] + for f in files: + file_entry: Dict[str, str] = {"id": f["file_id"], "title": f["title"]} + if f.get("highlight_type") is not None: + file_entry["highlight_type"] = f["highlight_type"] + complete_files.append(file_entry) completion = await self.files_completeUploadExternal( - files=[{"id": f["file_id"], "title": f["title"], "highlight_type": f.get("highlight_type")} for f in files], + files=complete_files, channel_id=channel, channels=channels, initial_comment=initial_comment, diff --git a/slack_sdk/web/client.py b/slack_sdk/web/client.py index f0eba239e..6b848a61b 100644 --- a/slack_sdk/web/client.py +++ b/slack_sdk/web/client.py @@ -4109,8 +4109,14 @@ def files_upload_v2( raise e.SlackRequestError(message) # step3: files.completeUploadExternal with all the sets of (file_id + title) + complete_files = [] + for f in files: + file_entry: Dict[str, str] = {"id": f["file_id"], "title": f["title"]} + if f.get("highlight_type") is not None: + file_entry["highlight_type"] = f["highlight_type"] + complete_files.append(file_entry) completion = self.files_completeUploadExternal( - files=[{"id": f["file_id"], "title": f["title"], "highlight_type": f.get("highlight_type")} for f in files], + files=complete_files, channel_id=channel, channels=channels, initial_comment=initial_comment, diff --git a/slack_sdk/web/legacy_client.py b/slack_sdk/web/legacy_client.py index 7f9e1ad66..0277571e7 100644 --- a/slack_sdk/web/legacy_client.py +++ b/slack_sdk/web/legacy_client.py @@ -4044,8 +4044,14 @@ def files_upload_v2( raise e.SlackRequestError(message) # step3: files.completeUploadExternal with all the sets of (file_id + title) + complete_files = [] + for f in files: + file_entry: Dict[str, str] = {"id": f["file_id"], "title": f["title"]} + if f.get("highlight_type") is not None: + file_entry["highlight_type"] = f["highlight_type"] + complete_files.append(file_entry) completion = self.files_completeUploadExternal( - files=[{"id": f["file_id"], "title": f["title"], "highlight_type": f.get("highlight_type")} for f in files], + files=complete_files, channel_id=channel, channels=channels, initial_comment=initial_comment, From 8530e6b46529706f157d4b6a1fe4e8f4d98d4b8f Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 14 May 2026 21:13:24 -0700 Subject: [PATCH 3/5] refactor: simplify highlight_type passthrough by widening type annotation Rely on the existing None-stripping logic in files_completeUploadExternal instead of conditionally building the dict. Co-Authored-By: Claude --- slack_sdk/web/async_client.py | 10 ++-------- slack_sdk/web/client.py | 10 ++-------- slack_sdk/web/legacy_client.py | 10 ++-------- 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/slack_sdk/web/async_client.py b/slack_sdk/web/async_client.py index 0af839254..ef14e903f 100644 --- a/slack_sdk/web/async_client.py +++ b/slack_sdk/web/async_client.py @@ -4119,14 +4119,8 @@ async def files_upload_v2( raise e.SlackRequestError(message) # step3: files.completeUploadExternal with all the sets of (file_id + title) - complete_files = [] - for f in files: - file_entry: Dict[str, str] = {"id": f["file_id"], "title": f["title"]} - if f.get("highlight_type") is not None: - file_entry["highlight_type"] = f["highlight_type"] - complete_files.append(file_entry) completion = await self.files_completeUploadExternal( - files=complete_files, + files=[{"id": f["file_id"], "title": f["title"], "highlight_type": f.get("highlight_type")} for f in files], channel_id=channel, channels=channels, initial_comment=initial_comment, @@ -4162,7 +4156,7 @@ async def files_getUploadURLExternal( async def files_completeUploadExternal( self, *, - files: List[Dict[str, str]], + files: List[Dict[str, Optional[str]]], channel_id: Optional[str] = None, channels: Optional[List[str]] = None, initial_comment: Optional[str] = None, diff --git a/slack_sdk/web/client.py b/slack_sdk/web/client.py index 6b848a61b..4419404b1 100644 --- a/slack_sdk/web/client.py +++ b/slack_sdk/web/client.py @@ -4109,14 +4109,8 @@ def files_upload_v2( raise e.SlackRequestError(message) # step3: files.completeUploadExternal with all the sets of (file_id + title) - complete_files = [] - for f in files: - file_entry: Dict[str, str] = {"id": f["file_id"], "title": f["title"]} - if f.get("highlight_type") is not None: - file_entry["highlight_type"] = f["highlight_type"] - complete_files.append(file_entry) completion = self.files_completeUploadExternal( - files=complete_files, + files=[{"id": f["file_id"], "title": f["title"], "highlight_type": f.get("highlight_type")} for f in files], channel_id=channel, channels=channels, initial_comment=initial_comment, @@ -4152,7 +4146,7 @@ def files_getUploadURLExternal( def files_completeUploadExternal( self, *, - files: List[Dict[str, str]], + files: List[Dict[str, Optional[str]]], channel_id: Optional[str] = None, channels: Optional[List[str]] = None, initial_comment: Optional[str] = None, diff --git a/slack_sdk/web/legacy_client.py b/slack_sdk/web/legacy_client.py index 0277571e7..f6264af3e 100644 --- a/slack_sdk/web/legacy_client.py +++ b/slack_sdk/web/legacy_client.py @@ -4044,14 +4044,8 @@ def files_upload_v2( raise e.SlackRequestError(message) # step3: files.completeUploadExternal with all the sets of (file_id + title) - complete_files = [] - for f in files: - file_entry: Dict[str, str] = {"id": f["file_id"], "title": f["title"]} - if f.get("highlight_type") is not None: - file_entry["highlight_type"] = f["highlight_type"] - complete_files.append(file_entry) completion = self.files_completeUploadExternal( - files=complete_files, + files=[{"id": f["file_id"], "title": f["title"], "highlight_type": f.get("highlight_type")} for f in files], channel_id=channel, channels=channels, initial_comment=initial_comment, @@ -4087,7 +4081,7 @@ def files_getUploadURLExternal( def files_completeUploadExternal( self, *, - files: List[Dict[str, str]], + files: List[Dict[str, Optional[str]]], channel_id: Optional[str] = None, channels: Optional[List[str]] = None, initial_comment: Optional[str] = None, From 0dd61f6813f54088d87a67fcf98f2eae4b31a1be Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 14 May 2026 21:15:26 -0700 Subject: [PATCH 4/5] style: reorder highlight_type before snippet_type in file upload item Co-Authored-By: Claude --- slack_sdk/web/internal_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slack_sdk/web/internal_utils.py b/slack_sdk/web/internal_utils.py index 8dc78a840..cb48d9fa9 100644 --- a/slack_sdk/web/internal_utils.py +++ b/slack_sdk/web/internal_utils.py @@ -378,8 +378,8 @@ def _to_v2_file_upload_item(upload_file: Dict[str, Any]) -> Dict[str, Optional[A "length": len(data), "title": title, "alt_txt": upload_file.get("alt_txt"), - "snippet_type": upload_file.get("snippet_type"), "highlight_type": upload_file.get("highlight_type"), + "snippet_type": upload_file.get("snippet_type"), } From 0d23d2f4653c09d9c7d7e5fe9d7ef80a357d5394 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Thu, 14 May 2026 21:16:34 -0700 Subject: [PATCH 5/5] style: reorder highlight_type before snippet_type in client methods Co-Authored-By: Claude --- slack_sdk/web/async_client.py | 4 ++-- slack_sdk/web/client.py | 4 ++-- slack_sdk/web/legacy_client.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/slack_sdk/web/async_client.py b/slack_sdk/web/async_client.py index ef14e903f..79293d8b9 100644 --- a/slack_sdk/web/async_client.py +++ b/slack_sdk/web/async_client.py @@ -4036,8 +4036,8 @@ async def files_upload_v2( content: Optional[Union[str, bytes]] = None, title: Optional[str] = None, alt_txt: Optional[str] = None, - snippet_type: Optional[str] = None, highlight_type: Optional[str] = None, + snippet_type: Optional[str] = None, # To upload multiple files at a time file_uploads: Optional[List[Dict[str, Any]]] = None, channel: Optional[str] = None, @@ -4081,8 +4081,8 @@ async def files_upload_v2( "content": content, "title": title, "alt_txt": alt_txt, - "snippet_type": snippet_type, "highlight_type": highlight_type, + "snippet_type": snippet_type, } ) files.append(f) diff --git a/slack_sdk/web/client.py b/slack_sdk/web/client.py index 4419404b1..4c597c2df 100644 --- a/slack_sdk/web/client.py +++ b/slack_sdk/web/client.py @@ -4026,8 +4026,8 @@ def files_upload_v2( content: Optional[Union[str, bytes]] = None, title: Optional[str] = None, alt_txt: Optional[str] = None, - snippet_type: Optional[str] = None, highlight_type: Optional[str] = None, + snippet_type: Optional[str] = None, # To upload multiple files at a time file_uploads: Optional[List[Dict[str, Any]]] = None, channel: Optional[str] = None, @@ -4071,8 +4071,8 @@ def files_upload_v2( "content": content, "title": title, "alt_txt": alt_txt, - "snippet_type": snippet_type, "highlight_type": highlight_type, + "snippet_type": snippet_type, } ) files.append(f) diff --git a/slack_sdk/web/legacy_client.py b/slack_sdk/web/legacy_client.py index f6264af3e..afc4e4f64 100644 --- a/slack_sdk/web/legacy_client.py +++ b/slack_sdk/web/legacy_client.py @@ -3961,8 +3961,8 @@ def files_upload_v2( content: Optional[Union[str, bytes]] = None, title: Optional[str] = None, alt_txt: Optional[str] = None, - snippet_type: Optional[str] = None, highlight_type: Optional[str] = None, + snippet_type: Optional[str] = None, # To upload multiple files at a time file_uploads: Optional[List[Dict[str, Any]]] = None, channel: Optional[str] = None, @@ -4006,8 +4006,8 @@ def files_upload_v2( "content": content, "title": title, "alt_txt": alt_txt, - "snippet_type": snippet_type, "highlight_type": highlight_type, + "snippet_type": snippet_type, } ) files.append(f)