Skip to content

Commit cbbeb2b

Browse files
authored
feat(models): add markdown block (#1748)
1 parent ed1893d commit cbbeb2b

File tree

3 files changed

+79
-2
lines changed

3 files changed

+79
-2
lines changed

slack_sdk/models/blocks/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
from .blocks import HeaderBlock
5959
from .blocks import ImageBlock
6060
from .blocks import InputBlock
61+
from .blocks import MarkdownBlock
6162
from .blocks import SectionBlock
6263
from .blocks import VideoBlock
6364
from .blocks import RichTextBlock
@@ -115,6 +116,7 @@
115116
"HeaderBlock",
116117
"ImageBlock",
117118
"InputBlock",
119+
"MarkdownBlock",
118120
"SectionBlock",
119121
"VideoBlock",
120122
"RichTextBlock",

slack_sdk/models/blocks/blocks.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import copy
22
import logging
33
import warnings
4-
from typing import Dict, Sequence, Optional, Set, Union, Any, List
4+
from typing import Any, Dict, List, Optional, Sequence, Set, Union
55

66
from slack_sdk.models import show_unknown_key_warning
77
from slack_sdk.models.basic_objects import (
@@ -87,6 +87,8 @@ def parse(cls, block: Union[dict, "Block"]) -> Optional["Block"]:
8787
return CallBlock(**block)
8888
elif type == HeaderBlock.type:
8989
return HeaderBlock(**block)
90+
elif type == MarkdownBlock.type:
91+
return MarkdownBlock(**block)
9092
elif type == VideoBlock.type:
9193
return VideoBlock(**block)
9294
elif type == RichTextBlock.type:
@@ -523,6 +525,45 @@ def _validate_alt_text_length(self):
523525
return self.text is None or len(self.text.text) <= self.text_max_length
524526

525527

528+
class MarkdownBlock(Block):
529+
type = "markdown"
530+
text_max_length = 12000
531+
532+
@property
533+
def attributes(self) -> Set[str]: # type: ignore[override]
534+
return super().attributes.union({"text"})
535+
536+
def __init__(
537+
self,
538+
*,
539+
text: str,
540+
block_id: Optional[str] = None,
541+
**others: dict,
542+
):
543+
"""Displays formatted markdown.
544+
https://docs.slack.dev/reference/block-kit/blocks/markdown-block/
545+
546+
Args:
547+
block_id: A string acting as a unique identifier for a block. If not specified, one will be generated.
548+
Maximum length for this field is 255 characters.
549+
block_id should be unique for each message and each iteration of a message.
550+
If a message is updated, use a new block_id.
551+
text (required): The standard markdown-formatted text. Limit 12,000 characters max.
552+
"""
553+
super().__init__(type=self.type, block_id=block_id)
554+
show_unknown_key_warning(self, others)
555+
556+
self.text = text
557+
558+
@JsonValidator("text attribute must be specified")
559+
def _validate_text(self):
560+
return self.text != ""
561+
562+
@JsonValidator(f"text attribute cannot exceed {text_max_length} characters")
563+
def _validate_alt_text_length(self):
564+
return len(self.text) <= self.text_max_length
565+
566+
526567
class VideoBlock(Block):
527568
type = "video"
528569
title_max_length = 200

tests/slack_sdk/models/test_blocks.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
PlainTextObject,
2121
MarkdownTextObject,
2222
HeaderBlock,
23+
MarkdownBlock,
2324
VideoBlock,
2425
Option,
2526
RichTextBlock,
@@ -30,8 +31,8 @@
3031
RichTextElementParts,
3132
)
3233
from slack_sdk.models.blocks.basic_components import SlackFile
33-
from . import STRING_3001_CHARS
3434

35+
from . import STRING_3001_CHARS
3536

3637
# https://api.slack.com/reference/block-kit/blocks
3738

@@ -804,6 +805,39 @@ def test_text_length_151(self):
804805
HeaderBlock(**input).validate_json()
805806

806807

808+
# ----------------------------------------------
809+
# MarkdownBlock
810+
# ----------------------------------------------
811+
812+
813+
class MarkdownBlockTests(unittest.TestCase):
814+
def test_document(self):
815+
input = {
816+
"type": "markdown",
817+
"block_id": "introduction",
818+
"text": "**Welcome!**",
819+
}
820+
self.assertDictEqual(input, MarkdownBlock(**input).to_dict())
821+
self.assertDictEqual(input, Block.parse(input).to_dict())
822+
823+
def test_text_length_12000(self):
824+
input = {
825+
"type": "markdown",
826+
"block_id": "numbers",
827+
"text": "1234567890" * 1200,
828+
}
829+
MarkdownBlock(**input).validate_json()
830+
831+
def test_text_length_12001(self):
832+
input = {
833+
"type": "markdown",
834+
"block_id": "numbers",
835+
"text": "1234567890" * 1200 + "1",
836+
}
837+
with self.assertRaises(SlackObjectFormationError):
838+
MarkdownBlock(**input).validate_json()
839+
840+
807841
# ----------------------------------------------
808842
# Video
809843
# ----------------------------------------------

0 commit comments

Comments
 (0)