Module slack_sdk.models.blocks.blocks

Expand source code
import copy
import logging
import warnings
from typing import Dict, Sequence, Optional, Set, Union, Any, List

from slack_sdk.models import show_unknown_key_warning
from slack_sdk.models.basic_objects import (
    JsonObject,
    JsonValidator,
)
from .basic_components import MarkdownTextObject
from .basic_components import PlainTextObject
from .basic_components import TextObject
from .block_elements import BlockElement
from .block_elements import InputInteractiveElement
from .block_elements import InteractiveElement


# -------------------------------------------------
# Base Classes
# -------------------------------------------------


class Block(JsonObject):
    """Blocks are a series of components that can be combined
    to create visually rich and compellingly interactive messages.
    https://api.slack.com/reference/block-kit/blocks
    """

    attributes = {"block_id", "type"}
    block_id_max_length = 255
    logger = logging.getLogger(__name__)

    def _subtype_warning(self):  # skipcq: PYL-R0201
        warnings.warn(
            "subtype is deprecated since slackclient 2.6.0, use type instead",
            DeprecationWarning,
        )

    @property
    def subtype(self) -> Optional[str]:
        return self.type

    def __init__(
        self,
        *,
        type: Optional[str] = None,  # skipcq: PYL-W0622
        subtype: Optional[str] = None,  # deprecated
        block_id: Optional[str] = None,
    ):
        if subtype:
            self._subtype_warning()
        self.type = type if type else subtype
        self.block_id = block_id
        self.color = None

    @JsonValidator(f"block_id cannot exceed {block_id_max_length} characters")
    def _validate_block_id_length(self):
        return self.block_id is None or len(self.block_id) <= self.block_id_max_length

    @classmethod
    def parse(cls, block: Union[dict, "Block"]) -> Optional["Block"]:
        if block is None:  # skipcq: PYL-R1705
            return None
        elif isinstance(block, Block):
            return block
        else:
            if "type" in block:
                type = block["type"]  # skipcq: PYL-W0622
                if type == SectionBlock.type:  # skipcq: PYL-R1705
                    return SectionBlock(**block)
                elif type == DividerBlock.type:
                    return DividerBlock(**block)
                elif type == ImageBlock.type:
                    return ImageBlock(**block)
                elif type == ActionsBlock.type:
                    return ActionsBlock(**block)
                elif type == ContextBlock.type:
                    return ContextBlock(**block)
                elif type == InputBlock.type:
                    return InputBlock(**block)
                elif type == FileBlock.type:
                    return FileBlock(**block)
                elif type == CallBlock.type:
                    return CallBlock(**block)
                elif type == HeaderBlock.type:
                    return HeaderBlock(**block)
                else:
                    cls.logger.warning(f"Unknown block detected and skipped ({block})")
                    return None
            else:
                cls.logger.warning(f"Unknown block detected and skipped ({block})")
                return None

    @classmethod
    def parse_all(
        cls, blocks: Optional[Sequence[Union[dict, "Block"]]]
    ) -> List["Block"]:
        return [cls.parse(b) for b in blocks or []]


# -------------------------------------------------
# Block Classes
# -------------------------------------------------


class SectionBlock(Block):
    type = "section"
    fields_max_length = 10
    text_max_length = 3000

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"text", "fields", "accessory"})

    def __init__(
        self,
        *,
        block_id: Optional[str] = None,
        text: Union[str, dict, TextObject] = None,
        fields: Sequence[Union[str, dict, TextObject]] = None,
        accessory: Optional[Union[dict, BlockElement]] = None,
        **others: dict,
    ):
        """A section is one of the most flexible blocks available.
        https://api.slack.com/reference/block-kit/blocks#section
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.text = TextObject.parse(text)
        field_objects = []
        for f in fields or []:
            if isinstance(f, str):
                field_objects.append(MarkdownTextObject.from_str(f))
            elif isinstance(f, TextObject):
                field_objects.append(f)
            elif isinstance(f, dict) and "type" in f:
                d = copy.copy(f)
                t = d.pop("type")
                if t == MarkdownTextObject.type:
                    field_objects.append(MarkdownTextObject(**d))
                else:
                    field_objects.append(PlainTextObject(**d))
            else:
                self.logger.warning(f"Unsupported filed detected and skipped {f}")
        self.fields = field_objects
        self.accessory = BlockElement.parse(accessory)

    @JsonValidator("text or fields attribute must be specified")
    def _validate_text_or_fields_populated(self):
        return self.text is not None or self.fields

    @JsonValidator(f"fields attribute cannot exceed {fields_max_length} items")
    def _validate_fields_length(self):
        return self.fields is None or len(self.fields) <= self.fields_max_length

    @JsonValidator(f"text attribute cannot exceed {text_max_length} characters")
    def _validate_alt_text_length(self):
        return self.text is None or len(self.text.text) <= self.text_max_length


class DividerBlock(Block):
    type = "divider"

    def __init__(
        self,
        *,
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """A content divider, like an <hr>, to split up different blocks inside of a message.
        https://api.slack.com/reference/block-kit/blocks#divider
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)


class ImageBlock(Block):
    type = "image"

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"alt_text", "image_url", "title"})

    image_url_max_length = 3000
    alt_text_max_length = 2000
    title_max_length = 2000

    def __init__(
        self,
        *,
        image_url: str,
        alt_text: str,
        title: Optional[Union[str, dict, TextObject]] = None,
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """A simple image block, designed to make those cat photos really pop.
        https://api.slack.com/reference/block-kit/blocks#image
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.image_url = image_url
        self.alt_text = alt_text
        self.title = TextObject.parse(title)

    @JsonValidator(
        f"image_url attribute cannot exceed {image_url_max_length} characters"
    )
    def _validate_image_url_length(self):
        return len(self.image_url) <= self.image_url_max_length

    @JsonValidator(f"alt_text attribute cannot exceed {alt_text_max_length} characters")
    def _validate_alt_text_length(self):
        return len(self.alt_text) <= self.alt_text_max_length

    @JsonValidator(f"title attribute cannot exceed {title_max_length} characters")
    def _validate_title_length(self):
        return (
            self.title is None
            or self.title.text is None
            or len(self.title.text) <= self.title_max_length
        )


class ActionsBlock(Block):
    type = "actions"
    elements_max_length = 5

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"elements"})

    def __init__(
        self,
        *,
        elements: Sequence[Union[dict, InteractiveElement]],
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """A block that is used to hold interactive elements.
        https://api.slack.com/reference/block-kit/blocks#actions
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.elements = BlockElement.parse_all(elements)

    @JsonValidator(f"elements attribute cannot exceed {elements_max_length} elements")
    def _validate_elements_length(self):
        return self.elements is None or len(self.elements) <= self.elements_max_length


class ContextBlock(Block):
    type = "context"
    elements_max_length = 10

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"elements"})

    def __init__(
        self,
        *,
        elements: Sequence[Union[dict, ImageBlock, TextObject]],
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """Displays message context, which can include both images and text.
        https://api.slack.com/reference/block-kit/blocks#context
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.elements = BlockElement.parse_all(elements)

    @JsonValidator(f"elements attribute cannot exceed {elements_max_length} elements")
    def _validate_elements_length(self):
        return self.elements is None or len(self.elements) <= self.elements_max_length


class InputBlock(Block):
    type = "input"
    label_max_length = 2000
    hint_max_length = 2000

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union(
            {"label", "hint", "element", "optional", "dispatch_action"}
        )

    def __init__(
        self,
        *,
        label: Union[str, dict, PlainTextObject],
        element: Union[str, dict, InputInteractiveElement],
        block_id: Optional[str] = None,
        hint: Optional[Union[str, dict, PlainTextObject]] = None,
        dispatch_action: Optional[bool] = None,
        optional: Optional[bool] = None,
        **others: dict,
    ):
        """A block that collects information from users - it can hold a plain-text input element,
        a select menu element, a multi-select menu element, or a datepicker.
        https://api.slack.com/reference/block-kit/blocks#input
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.label = TextObject.parse(label, default_type=PlainTextObject.type)
        self.element = BlockElement.parse(element)
        self.hint = TextObject.parse(hint, default_type=PlainTextObject.type)
        self.dispatch_action = dispatch_action
        self.optional = optional

    @JsonValidator(f"label attribute cannot exceed {label_max_length} characters")
    def _validate_label_length(self):
        return (
            self.label is None
            or self.label.text is None
            or len(self.label.text) <= self.label_max_length
        )

    @JsonValidator(f"hint attribute cannot exceed {hint_max_length} characters")
    def _validate_hint_length(self):
        return (
            self.hint is None
            or self.hint.text is None
            or len(self.hint.text) <= self.label_max_length
        )

    @JsonValidator(
        (
            "element attribute must be a string, select element, multi-select element, "
            "or a datepicker. (Sub-classes of InputInteractiveElement)"
        )
    )
    def _validate_element_type(self):
        return self.element is None or isinstance(
            self.element, (str, InputInteractiveElement)
        )


class FileBlock(Block):
    type = "file"

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"external_id", "source"})

    def __init__(
        self,
        *,
        external_id: str,
        source: str = "remote",
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """Displays a remote file.
        https://api.slack.com/reference/block-kit/blocks#file
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.external_id = external_id
        self.source = source


class CallBlock(Block):
    type = "call"

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"call_id", "api_decoration_available", "call"})

    def __init__(
        self,
        *,
        call_id: str,
        api_decoration_available: Optional[bool] = None,
        call: Optional[Dict[str, Dict[str, Any]]] = None,
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """Displays a call information
        https://api.slack.com/reference/block-kit/blocks#call
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.call_id = call_id
        self.api_decoration_available = api_decoration_available
        self.call = call


class HeaderBlock(Block):
    type = "header"
    text_max_length = 150

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"text"})

    def __init__(
        self,
        *,
        block_id: Optional[str] = None,
        text: Union[str, dict, TextObject] = None,
        **others: dict,
    ):
        """A header is a plain-text block that displays in a larger, bold font.
        https://api.slack.com/reference/block-kit/blocks#header
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.text = TextObject.parse(text, default_type=PlainTextObject.type)

    @JsonValidator("text attribute must be specified")
    def _validate_text(self):
        return self.text is not None

    @JsonValidator(f"text attribute cannot exceed {text_max_length} characters")
    def _validate_alt_text_length(self):
        return self.text is None or len(self.text.text) <= self.text_max_length

Classes

class ActionsBlock (*, elements: Sequence[Union[dict, InteractiveElement]], block_id: Optional[str] = None, **others: dict)

Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://api.slack.com/reference/block-kit/blocks

A block that is used to hold interactive elements. https://api.slack.com/reference/block-kit/blocks#actions

Expand source code
class ActionsBlock(Block):
    type = "actions"
    elements_max_length = 5

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"elements"})

    def __init__(
        self,
        *,
        elements: Sequence[Union[dict, InteractiveElement]],
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """A block that is used to hold interactive elements.
        https://api.slack.com/reference/block-kit/blocks#actions
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.elements = BlockElement.parse_all(elements)

    @JsonValidator(f"elements attribute cannot exceed {elements_max_length} elements")
    def _validate_elements_length(self):
        return self.elements is None or len(self.elements) <= self.elements_max_length

Ancestors

Class variables

var elements_max_length
var type

Instance variables

var attributes : Set[str]

set() -> new empty set object set(iterable) -> new set object

Build an unordered collection of unique elements.

Expand source code
@property
def attributes(self) -> Set[str]:
    return super().attributes.union({"elements"})

Inherited members

class Block (*, type: Optional[str] = None, subtype: Optional[str] = None, block_id: Optional[str] = None)

Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://api.slack.com/reference/block-kit/blocks

Expand source code
class Block(JsonObject):
    """Blocks are a series of components that can be combined
    to create visually rich and compellingly interactive messages.
    https://api.slack.com/reference/block-kit/blocks
    """

    attributes = {"block_id", "type"}
    block_id_max_length = 255
    logger = logging.getLogger(__name__)

    def _subtype_warning(self):  # skipcq: PYL-R0201
        warnings.warn(
            "subtype is deprecated since slackclient 2.6.0, use type instead",
            DeprecationWarning,
        )

    @property
    def subtype(self) -> Optional[str]:
        return self.type

    def __init__(
        self,
        *,
        type: Optional[str] = None,  # skipcq: PYL-W0622
        subtype: Optional[str] = None,  # deprecated
        block_id: Optional[str] = None,
    ):
        if subtype:
            self._subtype_warning()
        self.type = type if type else subtype
        self.block_id = block_id
        self.color = None

    @JsonValidator(f"block_id cannot exceed {block_id_max_length} characters")
    def _validate_block_id_length(self):
        return self.block_id is None or len(self.block_id) <= self.block_id_max_length

    @classmethod
    def parse(cls, block: Union[dict, "Block"]) -> Optional["Block"]:
        if block is None:  # skipcq: PYL-R1705
            return None
        elif isinstance(block, Block):
            return block
        else:
            if "type" in block:
                type = block["type"]  # skipcq: PYL-W0622
                if type == SectionBlock.type:  # skipcq: PYL-R1705
                    return SectionBlock(**block)
                elif type == DividerBlock.type:
                    return DividerBlock(**block)
                elif type == ImageBlock.type:
                    return ImageBlock(**block)
                elif type == ActionsBlock.type:
                    return ActionsBlock(**block)
                elif type == ContextBlock.type:
                    return ContextBlock(**block)
                elif type == InputBlock.type:
                    return InputBlock(**block)
                elif type == FileBlock.type:
                    return FileBlock(**block)
                elif type == CallBlock.type:
                    return CallBlock(**block)
                elif type == HeaderBlock.type:
                    return HeaderBlock(**block)
                else:
                    cls.logger.warning(f"Unknown block detected and skipped ({block})")
                    return None
            else:
                cls.logger.warning(f"Unknown block detected and skipped ({block})")
                return None

    @classmethod
    def parse_all(
        cls, blocks: Optional[Sequence[Union[dict, "Block"]]]
    ) -> List["Block"]:
        return [cls.parse(b) for b in blocks or []]

Ancestors

Subclasses

Class variables

var block_id_max_length
var logger

Static methods

def parse(block: Union[dict, ForwardRef('Block')]) ‑> Optional[Block]
Expand source code
@classmethod
def parse(cls, block: Union[dict, "Block"]) -> Optional["Block"]:
    if block is None:  # skipcq: PYL-R1705
        return None
    elif isinstance(block, Block):
        return block
    else:
        if "type" in block:
            type = block["type"]  # skipcq: PYL-W0622
            if type == SectionBlock.type:  # skipcq: PYL-R1705
                return SectionBlock(**block)
            elif type == DividerBlock.type:
                return DividerBlock(**block)
            elif type == ImageBlock.type:
                return ImageBlock(**block)
            elif type == ActionsBlock.type:
                return ActionsBlock(**block)
            elif type == ContextBlock.type:
                return ContextBlock(**block)
            elif type == InputBlock.type:
                return InputBlock(**block)
            elif type == FileBlock.type:
                return FileBlock(**block)
            elif type == CallBlock.type:
                return CallBlock(**block)
            elif type == HeaderBlock.type:
                return HeaderBlock(**block)
            else:
                cls.logger.warning(f"Unknown block detected and skipped ({block})")
                return None
        else:
            cls.logger.warning(f"Unknown block detected and skipped ({block})")
            return None
def parse_all(blocks: Optional[Sequence[Union[dict, ForwardRef('Block')]]]) ‑> List[Block]
Expand source code
@classmethod
def parse_all(
    cls, blocks: Optional[Sequence[Union[dict, "Block"]]]
) -> List["Block"]:
    return [cls.parse(b) for b in blocks or []]

Instance variables

var subtype : Optional[str]
Expand source code
@property
def subtype(self) -> Optional[str]:
    return self.type

Inherited members

class CallBlock (*, call_id: str, api_decoration_available: Optional[bool] = None, call: Optional[Dict[str, Dict[str, Any]]] = None, block_id: Optional[str] = None, **others: dict)

Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://api.slack.com/reference/block-kit/blocks

Displays a call information https://api.slack.com/reference/block-kit/blocks#call

Expand source code
class CallBlock(Block):
    type = "call"

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"call_id", "api_decoration_available", "call"})

    def __init__(
        self,
        *,
        call_id: str,
        api_decoration_available: Optional[bool] = None,
        call: Optional[Dict[str, Dict[str, Any]]] = None,
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """Displays a call information
        https://api.slack.com/reference/block-kit/blocks#call
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.call_id = call_id
        self.api_decoration_available = api_decoration_available
        self.call = call

Ancestors

Class variables

var type

Instance variables

var attributes : Set[str]

set() -> new empty set object set(iterable) -> new set object

Build an unordered collection of unique elements.

Expand source code
@property
def attributes(self) -> Set[str]:
    return super().attributes.union({"call_id", "api_decoration_available", "call"})

Inherited members

class ContextBlock (*, elements: Sequence[Union[dict, ImageBlockTextObject]], block_id: Optional[str] = None, **others: dict)

Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://api.slack.com/reference/block-kit/blocks

Displays message context, which can include both images and text. https://api.slack.com/reference/block-kit/blocks#context

Expand source code
class ContextBlock(Block):
    type = "context"
    elements_max_length = 10

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"elements"})

    def __init__(
        self,
        *,
        elements: Sequence[Union[dict, ImageBlock, TextObject]],
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """Displays message context, which can include both images and text.
        https://api.slack.com/reference/block-kit/blocks#context
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.elements = BlockElement.parse_all(elements)

    @JsonValidator(f"elements attribute cannot exceed {elements_max_length} elements")
    def _validate_elements_length(self):
        return self.elements is None or len(self.elements) <= self.elements_max_length

Ancestors

Class variables

var elements_max_length
var type

Instance variables

var attributes : Set[str]

set() -> new empty set object set(iterable) -> new set object

Build an unordered collection of unique elements.

Expand source code
@property
def attributes(self) -> Set[str]:
    return super().attributes.union({"elements"})

Inherited members

class DividerBlock (*, block_id: Optional[str] = None, **others: dict)

Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://api.slack.com/reference/block-kit/blocks

A content divider, like an


, to split up different blocks inside of a message. https://api.slack.com/reference/block-kit/blocks#divider

Expand source code
class DividerBlock(Block):
    type = "divider"

    def __init__(
        self,
        *,
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """A content divider, like an <hr>, to split up different blocks inside of a message.
        https://api.slack.com/reference/block-kit/blocks#divider
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

Ancestors

Class variables

var type

Inherited members

class FileBlock (*, external_id: str, source: str = 'remote', block_id: Optional[str] = None, **others: dict)

Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://api.slack.com/reference/block-kit/blocks

Displays a remote file. https://api.slack.com/reference/block-kit/blocks#file

Expand source code
class FileBlock(Block):
    type = "file"

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"external_id", "source"})

    def __init__(
        self,
        *,
        external_id: str,
        source: str = "remote",
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """Displays a remote file.
        https://api.slack.com/reference/block-kit/blocks#file
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.external_id = external_id
        self.source = source

Ancestors

Class variables

var type

Instance variables

var attributes : Set[str]

set() -> new empty set object set(iterable) -> new set object

Build an unordered collection of unique elements.

Expand source code
@property
def attributes(self) -> Set[str]:
    return super().attributes.union({"external_id", "source"})

Inherited members

class HeaderBlock (*, block_id: Optional[str] = None, text: Union[str, dict, TextObject] = None, **others: dict)

Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://api.slack.com/reference/block-kit/blocks

A header is a plain-text block that displays in a larger, bold font. https://api.slack.com/reference/block-kit/blocks#header

Expand source code
class HeaderBlock(Block):
    type = "header"
    text_max_length = 150

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"text"})

    def __init__(
        self,
        *,
        block_id: Optional[str] = None,
        text: Union[str, dict, TextObject] = None,
        **others: dict,
    ):
        """A header is a plain-text block that displays in a larger, bold font.
        https://api.slack.com/reference/block-kit/blocks#header
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.text = TextObject.parse(text, default_type=PlainTextObject.type)

    @JsonValidator("text attribute must be specified")
    def _validate_text(self):
        return self.text is not None

    @JsonValidator(f"text attribute cannot exceed {text_max_length} characters")
    def _validate_alt_text_length(self):
        return self.text is None or len(self.text.text) <= self.text_max_length

Ancestors

Class variables

var text_max_length
var type

Instance variables

var attributes : Set[str]

set() -> new empty set object set(iterable) -> new set object

Build an unordered collection of unique elements.

Expand source code
@property
def attributes(self) -> Set[str]:
    return super().attributes.union({"text"})

Inherited members

class ImageBlock (*, image_url: str, alt_text: str, title: Union[str, dict, TextObject, NoneType] = None, block_id: Optional[str] = None, **others: dict)

Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://api.slack.com/reference/block-kit/blocks

A simple image block, designed to make those cat photos really pop. https://api.slack.com/reference/block-kit/blocks#image

Expand source code
class ImageBlock(Block):
    type = "image"

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"alt_text", "image_url", "title"})

    image_url_max_length = 3000
    alt_text_max_length = 2000
    title_max_length = 2000

    def __init__(
        self,
        *,
        image_url: str,
        alt_text: str,
        title: Optional[Union[str, dict, TextObject]] = None,
        block_id: Optional[str] = None,
        **others: dict,
    ):
        """A simple image block, designed to make those cat photos really pop.
        https://api.slack.com/reference/block-kit/blocks#image
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.image_url = image_url
        self.alt_text = alt_text
        self.title = TextObject.parse(title)

    @JsonValidator(
        f"image_url attribute cannot exceed {image_url_max_length} characters"
    )
    def _validate_image_url_length(self):
        return len(self.image_url) <= self.image_url_max_length

    @JsonValidator(f"alt_text attribute cannot exceed {alt_text_max_length} characters")
    def _validate_alt_text_length(self):
        return len(self.alt_text) <= self.alt_text_max_length

    @JsonValidator(f"title attribute cannot exceed {title_max_length} characters")
    def _validate_title_length(self):
        return (
            self.title is None
            or self.title.text is None
            or len(self.title.text) <= self.title_max_length
        )

Ancestors

Class variables

var alt_text_max_length
var image_url_max_length
var title_max_length
var type

Instance variables

var attributes : Set[str]

set() -> new empty set object set(iterable) -> new set object

Build an unordered collection of unique elements.

Expand source code
@property
def attributes(self) -> Set[str]:
    return super().attributes.union({"alt_text", "image_url", "title"})

Inherited members

class InputBlock (*, label: Union[str, dict, PlainTextObject], element: Union[str, dict, InputInteractiveElement], block_id: Optional[str] = None, hint: Union[str, dict, PlainTextObject, NoneType] = None, dispatch_action: Optional[bool] = None, optional: Optional[bool] = None, **others: dict)

Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://api.slack.com/reference/block-kit/blocks

A block that collects information from users - it can hold a plain-text input element, a select menu element, a multi-select menu element, or a datepicker. https://api.slack.com/reference/block-kit/blocks#input

Expand source code
class InputBlock(Block):
    type = "input"
    label_max_length = 2000
    hint_max_length = 2000

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union(
            {"label", "hint", "element", "optional", "dispatch_action"}
        )

    def __init__(
        self,
        *,
        label: Union[str, dict, PlainTextObject],
        element: Union[str, dict, InputInteractiveElement],
        block_id: Optional[str] = None,
        hint: Optional[Union[str, dict, PlainTextObject]] = None,
        dispatch_action: Optional[bool] = None,
        optional: Optional[bool] = None,
        **others: dict,
    ):
        """A block that collects information from users - it can hold a plain-text input element,
        a select menu element, a multi-select menu element, or a datepicker.
        https://api.slack.com/reference/block-kit/blocks#input
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.label = TextObject.parse(label, default_type=PlainTextObject.type)
        self.element = BlockElement.parse(element)
        self.hint = TextObject.parse(hint, default_type=PlainTextObject.type)
        self.dispatch_action = dispatch_action
        self.optional = optional

    @JsonValidator(f"label attribute cannot exceed {label_max_length} characters")
    def _validate_label_length(self):
        return (
            self.label is None
            or self.label.text is None
            or len(self.label.text) <= self.label_max_length
        )

    @JsonValidator(f"hint attribute cannot exceed {hint_max_length} characters")
    def _validate_hint_length(self):
        return (
            self.hint is None
            or self.hint.text is None
            or len(self.hint.text) <= self.label_max_length
        )

    @JsonValidator(
        (
            "element attribute must be a string, select element, multi-select element, "
            "or a datepicker. (Sub-classes of InputInteractiveElement)"
        )
    )
    def _validate_element_type(self):
        return self.element is None or isinstance(
            self.element, (str, InputInteractiveElement)
        )

Ancestors

Class variables

var hint_max_length
var label_max_length
var type

Instance variables

var attributes : Set[str]

set() -> new empty set object set(iterable) -> new set object

Build an unordered collection of unique elements.

Expand source code
@property
def attributes(self) -> Set[str]:
    return super().attributes.union(
        {"label", "hint", "element", "optional", "dispatch_action"}
    )

Inherited members

class SectionBlock (*, block_id: Optional[str] = None, text: Union[str, dict, TextObject] = None, fields: Sequence[Union[str, dict, TextObject]] = None, accessory: Union[dict, BlockElement, NoneType] = None, **others: dict)

Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://api.slack.com/reference/block-kit/blocks

A section is one of the most flexible blocks available. https://api.slack.com/reference/block-kit/blocks#section

Expand source code
class SectionBlock(Block):
    type = "section"
    fields_max_length = 10
    text_max_length = 3000

    @property
    def attributes(self) -> Set[str]:
        return super().attributes.union({"text", "fields", "accessory"})

    def __init__(
        self,
        *,
        block_id: Optional[str] = None,
        text: Union[str, dict, TextObject] = None,
        fields: Sequence[Union[str, dict, TextObject]] = None,
        accessory: Optional[Union[dict, BlockElement]] = None,
        **others: dict,
    ):
        """A section is one of the most flexible blocks available.
        https://api.slack.com/reference/block-kit/blocks#section
        """
        super().__init__(type=self.type, block_id=block_id)
        show_unknown_key_warning(self, others)

        self.text = TextObject.parse(text)
        field_objects = []
        for f in fields or []:
            if isinstance(f, str):
                field_objects.append(MarkdownTextObject.from_str(f))
            elif isinstance(f, TextObject):
                field_objects.append(f)
            elif isinstance(f, dict) and "type" in f:
                d = copy.copy(f)
                t = d.pop("type")
                if t == MarkdownTextObject.type:
                    field_objects.append(MarkdownTextObject(**d))
                else:
                    field_objects.append(PlainTextObject(**d))
            else:
                self.logger.warning(f"Unsupported filed detected and skipped {f}")
        self.fields = field_objects
        self.accessory = BlockElement.parse(accessory)

    @JsonValidator("text or fields attribute must be specified")
    def _validate_text_or_fields_populated(self):
        return self.text is not None or self.fields

    @JsonValidator(f"fields attribute cannot exceed {fields_max_length} items")
    def _validate_fields_length(self):
        return self.fields is None or len(self.fields) <= self.fields_max_length

    @JsonValidator(f"text attribute cannot exceed {text_max_length} characters")
    def _validate_alt_text_length(self):
        return self.text is None or len(self.text.text) <= self.text_max_length

Ancestors

Class variables

var fields_max_length
var text_max_length
var type

Instance variables

var attributes : Set[str]

set() -> new empty set object set(iterable) -> new set object

Build an unordered collection of unique elements.

Expand source code
@property
def attributes(self) -> Set[str]:
    return super().attributes.union({"text", "fields", "accessory"})

Inherited members