Skip to content

Commit 750d97c

Browse files
authored
Fix #1428 Add rich_text classes to slack_sdk.models module (#1431)
1 parent 3e2d7e8 commit 750d97c

File tree

4 files changed

+574
-1
lines changed

4 files changed

+574
-1
lines changed

slack_sdk/models/blocks/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@
4343
from .block_elements import StaticSelectElement
4444
from .block_elements import UserMultiSelectElement
4545
from .block_elements import UserSelectElement
46+
from .block_elements import RichTextElement
47+
from .block_elements import RichTextElementParts
48+
from .block_elements import RichTextListElement
49+
from .block_elements import RichTextPreformattedElement
50+
from .block_elements import RichTextQuoteElement
51+
from .block_elements import RichTextSectionElement
4652
from .blocks import ActionsBlock
4753
from .blocks import Block
4854
from .blocks import CallBlock
@@ -54,6 +60,7 @@
5460
from .blocks import InputBlock
5561
from .blocks import SectionBlock
5662
from .blocks import VideoBlock
63+
from .blocks import RichTextBlock
5764

5865
__all__ = [
5966
"ButtonStyles",
@@ -93,6 +100,12 @@
93100
"StaticSelectElement",
94101
"UserMultiSelectElement",
95102
"UserSelectElement",
103+
"RichTextElement",
104+
"RichTextElementParts",
105+
"RichTextListElement",
106+
"RichTextPreformattedElement",
107+
"RichTextQuoteElement",
108+
"RichTextSectionElement",
96109
"ActionsBlock",
97110
"Block",
98111
"CallBlock",
@@ -104,4 +117,5 @@
104117
"InputBlock",
105118
"SectionBlock",
106119
"VideoBlock",
120+
"RichTextBlock",
107121
]

slack_sdk/models/blocks/block_elements.py

Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,3 +1834,309 @@ def __init__(
18341834
self.workflow = workflow
18351835
self.style = style
18361836
self.accessibility_label = accessibility_label
1837+
1838+
1839+
# -------------------------------------------------
1840+
# Rich text elements
1841+
# -------------------------------------------------
1842+
1843+
1844+
class RichTextElement(BlockElement):
1845+
pass
1846+
1847+
1848+
class RichTextListElement(RichTextElement):
1849+
type = "rich_text_list"
1850+
1851+
@property
1852+
def attributes(self) -> Set[str]:
1853+
return super().attributes.union({"elements", "style", "indent", "offset", "border"})
1854+
1855+
def __init__(
1856+
self,
1857+
*,
1858+
elements: Sequence[Union[dict, RichTextElement]],
1859+
style: Optional[str] = None, # bullet, ordered
1860+
indent: Optional[int] = None,
1861+
offset: Optional[int] = None,
1862+
border: Optional[int] = None,
1863+
**others: dict,
1864+
):
1865+
super().__init__(type=self.type)
1866+
show_unknown_key_warning(self, others)
1867+
self.elements = elements
1868+
self.style = style
1869+
self.indent = indent
1870+
self.offset = offset
1871+
self.border = border
1872+
1873+
1874+
class RichTextPreformattedElement(RichTextElement):
1875+
type = "rich_text_preformatted"
1876+
1877+
@property
1878+
def attributes(self) -> Set[str]:
1879+
return super().attributes.union({"elements", "border"})
1880+
1881+
def __init__(
1882+
self,
1883+
*,
1884+
elements: Sequence[Union[dict, RichTextElement]],
1885+
border: Optional[int] = None,
1886+
**others: dict,
1887+
):
1888+
super().__init__(type=self.type)
1889+
show_unknown_key_warning(self, others)
1890+
self.elements = elements
1891+
self.border = border
1892+
1893+
1894+
class RichTextQuoteElement(RichTextElement):
1895+
type = "rich_text_quote"
1896+
1897+
@property
1898+
def attributes(self) -> Set[str]:
1899+
return super().attributes.union({"elements"})
1900+
1901+
def __init__(
1902+
self,
1903+
*,
1904+
elements: Sequence[Union[dict, RichTextElement]],
1905+
**others: dict,
1906+
):
1907+
super().__init__(type=self.type)
1908+
show_unknown_key_warning(self, others)
1909+
self.elements = elements
1910+
1911+
1912+
class RichTextSectionElement(RichTextElement):
1913+
type = "rich_text_section"
1914+
1915+
@property
1916+
def attributes(self) -> Set[str]:
1917+
return super().attributes.union({"elements"})
1918+
1919+
def __init__(
1920+
self,
1921+
*,
1922+
elements: Sequence[Union[dict, RichTextElement]],
1923+
**others: dict,
1924+
):
1925+
super().__init__(type=self.type)
1926+
show_unknown_key_warning(self, others)
1927+
self.elements = elements
1928+
1929+
1930+
class RichTextElementParts:
1931+
class TextStyle:
1932+
def __init__(
1933+
self,
1934+
*,
1935+
bold: Optional[bool] = None,
1936+
italic: Optional[bool] = None,
1937+
strike: Optional[bool] = None,
1938+
code: Optional[bool] = None,
1939+
):
1940+
self.bold = bold
1941+
self.italic = italic
1942+
self.strike = strike
1943+
self.code = code
1944+
1945+
def to_dict(self, *args) -> dict:
1946+
result = {
1947+
"bold": self.bold,
1948+
"italic": self.italic,
1949+
"strike": self.strike,
1950+
"code": self.code,
1951+
}
1952+
return {k: v for k, v in result.items() if v is not None}
1953+
1954+
class Text(RichTextElement):
1955+
type = "text"
1956+
1957+
@property
1958+
def attributes(self) -> Set[str]:
1959+
return super().attributes.union({"text", "style"})
1960+
1961+
def __init__(
1962+
self,
1963+
*,
1964+
text: str,
1965+
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
1966+
**others: dict,
1967+
):
1968+
super().__init__(type=self.type)
1969+
show_unknown_key_warning(self, others)
1970+
self.text = text
1971+
self.style = style
1972+
1973+
class Channel(RichTextElement):
1974+
type = "channel"
1975+
1976+
@property
1977+
def attributes(self) -> Set[str]:
1978+
return super().attributes.union({"channel_id", "style"})
1979+
1980+
def __init__(
1981+
self,
1982+
*,
1983+
channel_id: str,
1984+
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
1985+
**others: dict,
1986+
):
1987+
super().__init__(type=self.type)
1988+
show_unknown_key_warning(self, others)
1989+
self.channel_id = channel_id
1990+
self.style = style
1991+
1992+
class User(RichTextElement):
1993+
type = "user"
1994+
1995+
@property
1996+
def attributes(self) -> Set[str]:
1997+
return super().attributes.union({"user_id", "style"})
1998+
1999+
def __init__(
2000+
self,
2001+
*,
2002+
user_id: str,
2003+
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
2004+
**others: dict,
2005+
):
2006+
super().__init__(type=self.type)
2007+
show_unknown_key_warning(self, others)
2008+
self.user_id = user_id
2009+
self.style = style
2010+
2011+
class Emoji(RichTextElement):
2012+
type = "emoji"
2013+
2014+
@property
2015+
def attributes(self) -> Set[str]:
2016+
return super().attributes.union({"name", "skin_tone", "unicode", "style"})
2017+
2018+
def __init__(
2019+
self,
2020+
*,
2021+
name: str,
2022+
skin_tone: Optional[int] = None,
2023+
unicode: Optional[str] = None,
2024+
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
2025+
**others: dict,
2026+
):
2027+
super().__init__(type=self.type)
2028+
show_unknown_key_warning(self, others)
2029+
self.name = name
2030+
self.skin_tone = skin_tone
2031+
self.unicode = unicode
2032+
self.style = style
2033+
2034+
class Link(RichTextElement):
2035+
type = "link"
2036+
2037+
@property
2038+
def attributes(self) -> Set[str]:
2039+
return super().attributes.union({"url", "text", "style"})
2040+
2041+
def __init__(
2042+
self,
2043+
*,
2044+
url: str,
2045+
text: Optional[str] = None,
2046+
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
2047+
**others: dict,
2048+
):
2049+
super().__init__(type=self.type)
2050+
show_unknown_key_warning(self, others)
2051+
self.url = url
2052+
self.text = text
2053+
self.style = style
2054+
2055+
class Team(RichTextElement):
2056+
type = "team"
2057+
2058+
@property
2059+
def attributes(self) -> Set[str]:
2060+
return super().attributes.union({"team_id", "style"})
2061+
2062+
def __init__(
2063+
self,
2064+
*,
2065+
team_id: str,
2066+
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
2067+
**others: dict,
2068+
):
2069+
super().__init__(type=self.type)
2070+
show_unknown_key_warning(self, others)
2071+
self.team_id = team_id
2072+
self.style = style
2073+
2074+
class UserGroup(RichTextElement):
2075+
type = "usergroup"
2076+
2077+
@property
2078+
def attributes(self) -> Set[str]:
2079+
return super().attributes.union({"usergroup_id", "style"})
2080+
2081+
def __init__(
2082+
self,
2083+
*,
2084+
usergroup_id: str,
2085+
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
2086+
**others: dict,
2087+
):
2088+
super().__init__(type=self.type)
2089+
show_unknown_key_warning(self, others)
2090+
self.usergroup_id = usergroup_id
2091+
self.style = style
2092+
2093+
class Date(RichTextElement):
2094+
type = "date"
2095+
2096+
@property
2097+
def attributes(self) -> Set[str]:
2098+
return super().attributes.union({"timestamp"})
2099+
2100+
def __init__(
2101+
self,
2102+
*,
2103+
timestamp: str,
2104+
**others: dict,
2105+
):
2106+
super().__init__(type=self.type)
2107+
show_unknown_key_warning(self, others)
2108+
self.timestamp = timestamp
2109+
2110+
class Broadcast(RichTextElement):
2111+
type = "broadcast"
2112+
2113+
@property
2114+
def attributes(self) -> Set[str]:
2115+
return super().attributes.union({"range"})
2116+
2117+
def __init__(
2118+
self,
2119+
*,
2120+
range: str, # channel, here, ..
2121+
**others: dict,
2122+
):
2123+
super().__init__(type=self.type)
2124+
show_unknown_key_warning(self, others)
2125+
self.range = range
2126+
2127+
class Color(RichTextElement):
2128+
type = "color"
2129+
2130+
@property
2131+
def attributes(self) -> Set[str]:
2132+
return super().attributes.union({"value"})
2133+
2134+
def __init__(
2135+
self,
2136+
*,
2137+
value: str,
2138+
**others: dict,
2139+
):
2140+
super().__init__(type=self.type)
2141+
show_unknown_key_warning(self, others)
2142+
self.value = value

slack_sdk/models/blocks/blocks.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from .basic_components import MarkdownTextObject
1212
from .basic_components import PlainTextObject
1313
from .basic_components import TextObject
14-
from .block_elements import BlockElement
14+
from .block_elements import BlockElement, RichTextElement
1515
from .block_elements import ImageElement
1616
from .block_elements import InputInteractiveElement
1717
from .block_elements import InteractiveElement
@@ -604,3 +604,34 @@ def _validate_title_length(self):
604604
@JsonValidator(f"author_name attribute cannot exceed {author_name_max_length} characters")
605605
def _validate_author_name_length(self):
606606
return self.author_name is None or len(self.author_name) < self.author_name_max_length
607+
608+
609+
class RichTextBlock(Block):
610+
type = "rich_text"
611+
612+
@property
613+
def attributes(self) -> Set[str]:
614+
return super().attributes.union({"elements"})
615+
616+
def __init__(
617+
self,
618+
*,
619+
elements: Sequence[Union[dict, RichTextElement]],
620+
block_id: Optional[str] = None,
621+
**others: dict,
622+
):
623+
"""A block that is used to hold interactive elements.
624+
https://api.slack.com/reference/block-kit/blocks#rich_text
625+
626+
Args:
627+
elements (required): An array of rich text objects -
628+
rich_text_section, rich_text_list, rich_text_quote, rich_text_preformatted
629+
block_id: A unique identifier for a block. If not specified, one will be generated.
630+
Maximum length for this field is 255 characters.
631+
block_id should be unique for each message or view and each iteration of a message or view.
632+
If a message or view is updated, use a new block_id.
633+
"""
634+
super().__init__(type=self.type, block_id=block_id)
635+
show_unknown_key_warning(self, others)
636+
637+
self.elements = BlockElement.parse_all(elements)

0 commit comments

Comments
 (0)