-
Notifications
You must be signed in to change notification settings - Fork 848
Description
In WebClient.chat_unfurl, the user_auth_blocks parameter is typed as Optional[Union[str, Sequence[Union[Dict, Block]]]] = None. However, it doesn't actually accept Sequence[Block]. It seems that internal_utils._parse_web_class_objects() is called to parse Attachment/Block/Metadata objects into dicts, but only for hardcoded classes (why not recursively on JsonObject?) passed to 3 specific parameters.
In other cases, parameters are typed dict, and you can't tell if you can use a Block object inside it, without diving into the source code and realizing that there's only a handful of cases where the SDK calls to_dict() for you. For example, it isn't possible to use Block objects in WebClient.chat_unfurl's unfurls parameter, since it expects a dict in the form of {"url": {"blocks": [dict1, dict2, ...]}, ...} and does not accept {"url": {"blocks": [Block1, Block2, ...]}, ...}. Same thing for SocketModeResponse's response payload.
Reproducible in:
The Slack SDK version
slack-sdk==3.19.3
Python runtime version
Python 3.10.8
OS info
ProductName: macOS
ProductVersion: 12.6.1
BuildVersion: 21G217
Darwin Kernel Version 21.6.0: Thu Sep 29 20:13:56 PDT 2022; root:xnu-8020.240.7~1/RELEASE_ARM64_T6000
Steps to reproduce:
from slack_sdk.models.blocks.blocks import DividerBlock
from slack_sdk.web.client import WebClient
# works
WebClient("SLACK_BOT_TOKEN").chat_unfurl(channel="CHANNEL", ts="TS", unfurls={}, user_auth_blocks=[{"type": "divider"}, {"type": "divider"}])
# TypeError: Object of type DividerBlock is not JSON serializable
WebClient("SLACK_BOT_TOKEN").chat_unfurl(channel="CHANNEL", ts="TS", unfurls={}, user_auth_blocks=[DividerBlock(), DividerBlock()])
# works
blocks = [DividerBlock(), DividerBlock()]
WebClient("SLACK_BOT_TOKEN").chat_unfurl(channel="CHANNEL", ts="TS", unfurls={}, user_auth_blocks=[block.to_dict() for block in blocks])Actual result:
>>> WebClient("SLACK_BOT_TOKEN").chat_unfurl(channel="CHANNEL", ts="TS", unfurls={}, user_auth_blocks=[DividerBlock(), DividerBlock()])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/jsu/fuck/lib/python3.10/site-packages/slack_sdk/web/client.py", line 2150, in chat_unfurl
return self.api_call("chat.unfurl", json=kwargs)
File "/Users/jsu/fuck/lib/python3.10/site-packages/slack_sdk/web/base_client.py", line 156, in api_call
return self._sync_send(api_url=api_url, req_args=req_args)
File "/Users/jsu/fuck/lib/python3.10/site-packages/slack_sdk/web/base_client.py", line 187, in _sync_send
return self._urllib_api_call(
File "/Users/jsu/fuck/lib/python3.10/site-packages/slack_sdk/web/base_client.py", line 294, in _urllib_api_call
response = self._perform_urllib_http_request(url=url, args=request_args)
File "/Users/jsu/fuck/lib/python3.10/site-packages/slack_sdk/web/base_client.py", line 339, in _perform_urllib_http_request
body = json.dumps(args["json"])
File "/opt/homebrew/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/opt/homebrew/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/opt/homebrew/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/opt/homebrew/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type DividerBlock is not JSON serializable