Skip to content

Commit 70685d3

Browse files
Support pathlike objects in upload util (#1656)
* Support pathlike objects in upload util Also switch to inbuilt filename encode helper, since it accepts paths * Add an integration test --------- Co-authored-by: William Bergamin <wbergamin@slack-corp.com> Co-authored-by: William Bergamin <wbergamin@salesforce.com>
1 parent f1090b9 commit 70685d3

File tree

6 files changed

+28
-7
lines changed

6 files changed

+28
-7
lines changed

integration_tests/web/test_files_upload_v2.py

+13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import os
3+
from pathlib import Path
34
import unittest
45
from io import BytesIO
56

@@ -59,6 +60,18 @@ def test_uploading_bytes_io(self):
5960
self.assertIsNotNone(upload.get("files")[0].get("id"))
6061
self.assertIsNotNone(upload.get("files")[0].get("title"))
6162

63+
def test_uploading_text_files_path(self):
64+
client = self.sync_client
65+
file = __file__
66+
upload = client.files_upload_v2(
67+
channel=self.channel_id,
68+
file=Path(file),
69+
title="Test code",
70+
)
71+
self.assertIsNotNone(upload)
72+
self.assertIsNotNone(upload.get("files")[0].get("id"))
73+
self.assertIsNotNone(upload.get("files")[0].get("title"))
74+
6275
def test_uploading_multiple_files(self):
6376
client = self.sync_client
6477
file = __file__

slack_sdk/web/async_client.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3749,7 +3749,7 @@ async def files_upload_v2(
37493749
*,
37503750
# for sending a single file
37513751
filename: Optional[str] = None, # you can skip this only when sending along with content parameter
3752-
file: Optional[Union[str, bytes, IOBase]] = None,
3752+
file: Optional[Union[str, bytes, IOBase, os.PathLike]] = None,
37533753
content: Optional[Union[str, bytes]] = None,
37543754
title: Optional[str] = None,
37553755
alt_txt: Optional[str] = None,

slack_sdk/web/client.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3739,7 +3739,7 @@ def files_upload_v2(
37393739
*,
37403740
# for sending a single file
37413741
filename: Optional[str] = None, # you can skip this only when sending along with content parameter
3742-
file: Optional[Union[str, bytes, IOBase]] = None,
3742+
file: Optional[Union[str, bytes, IOBase, os.PathLike]] = None,
37433743
content: Optional[Union[str, bytes]] = None,
37443744
title: Optional[str] = None,
37453745
alt_txt: Optional[str] = None,

slack_sdk/web/internal_utils.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,8 @@ def _to_v2_file_upload_item(upload_file: Dict[str, Any]) -> Dict[str, Optional[A
317317
content = upload_file.get("content")
318318
data: Optional[bytes] = None
319319
if file is not None:
320-
if isinstance(file, str): # filepath
321-
with open(file.encode("utf-8", "ignore"), "rb") as readable:
320+
if isinstance(file, (str, os.PathLike)): # filepath
321+
with open(os.fsencode(file), "rb") as readable:
322322
data = readable.read()
323323
elif isinstance(file, bytes):
324324
data = file
@@ -339,8 +339,8 @@ def _to_v2_file_upload_item(upload_file: Dict[str, Any]) -> Dict[str, Optional[A
339339
filename = upload_file.get("filename")
340340
if filename is None:
341341
# use the local filename if filename is missing
342-
if isinstance(file, str):
343-
filename = file.split(os.path.sep)[-1]
342+
if isinstance(file, (str, os.PathLike)):
343+
filename = os.fspath(file).split(os.path.sep)[-1]
344344
else:
345345
filename = "Uploaded file"
346346

slack_sdk/web/legacy_client.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3751,7 +3751,7 @@ def files_upload_v2(
37513751
*,
37523752
# for sending a single file
37533753
filename: Optional[str] = None, # you can skip this only when sending along with content parameter
3754-
file: Optional[Union[str, bytes, IOBase]] = None,
3754+
file: Optional[Union[str, bytes, IOBase, os.PathLike]] = None,
37553755
content: Optional[Union[str, bytes]] = None,
37563756
title: Optional[str] = None,
37573757
alt_txt: Optional[str] = None,

tests/slack_sdk/web/test_internal_utils.py

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import unittest
33
from io import BytesIO
4+
from pathlib import Path
45
from typing import Dict, Sequence, Union
56

67
import pytest
@@ -101,6 +102,13 @@ def test_files_upload_v2_issue_1356(self):
101102
file_io_item = _to_v2_file_upload_item({"file": file_io, "filename": "foo.txt"})
102103
assert file_io_item.get("filename") == "foo.txt"
103104

105+
def test_to_v2_file_upload_item_can_accept_file_as_path(self):
106+
filepath = "tests/slack_sdk/web/test_internal_utils.py"
107+
upload_item_str = _to_v2_file_upload_item({"file": filepath})
108+
upload_item_path = _to_v2_file_upload_item({"file": Path(filepath)})
109+
assert upload_item_path == upload_item_str
110+
assert upload_item_str.get("filename") == "test_internal_utils.py"
111+
104112
def test_next_cursor_is_present(self):
105113
assert _next_cursor_is_present({"next_cursor": "next-page"}) is True
106114
assert _next_cursor_is_present({"next_cursor": ""}) is False

0 commit comments

Comments
 (0)