Module slack_sdk.models

Classes for constructing Slack-specific data structure

Expand source code
"""Classes for constructing Slack-specific data structure"""

import logging
from typing import Union, Dict, Any, Sequence, List

from .basic_objects import BaseObject
from .basic_objects import EnumValidator
from .basic_objects import JsonObject
from .basic_objects import JsonValidator


# NOTE: used only for legacy components - don't use this for Block Kit
def extract_json(
    item_or_items: Union[JsonObject, Sequence[JsonObject]], *format_args
) -> Union[Dict[Any, Any], List[Dict[Any, Any]]]:  # type: ignore
    """
    Given a sequence (or single item), attempt to call the to_dict() method on each
    item and return a plain list. If item is not the expected type, return it
    unmodified, in case it's already a plain dict or some other user created class.

    Args:
      item_or_items: item(s) to go through
      format_args: Any formatting specifiers to pass into the object's to_dict
            method
    """
    try:
        return [  # type: ignore
            elem.to_dict(*format_args) if isinstance(elem, JsonObject) else elem for elem in item_or_items
        ]
    except TypeError:  # not iterable, so try returning it as a single item
        return (  # type: ignore
            item_or_items.to_dict(*format_args) if isinstance(item_or_items, JsonObject) else item_or_items
        )


def show_unknown_key_warning(name: Union[str, object], others: dict):
    if "type" in others:
        others.pop("type")
    if len(others) > 0:
        keys = ", ".join(others.keys())
        logger = logging.getLogger(__name__)
        if isinstance(name, object):
            name = name.__class__.__name__
        logger.debug(
            f"!!! {name}'s constructor args ({keys}) were ignored."
            f"If they should be supported by this library, report this issue to the project :bow: "
            f"https://github.com/slackapi/python-slack-sdk/issues"
        )


__all__ = [
    "BaseObject",
    "EnumValidator",
    "JsonObject",
    "JsonValidator",
    "extract_json",
    "show_unknown_key_warning",
]

Sub-modules

slack_sdk.models.attachments
slack_sdk.models.basic_objects
slack_sdk.models.blocks

Block Kit data model objects …

slack_sdk.models.dialoags
slack_sdk.models.dialogs
slack_sdk.models.messages
slack_sdk.models.metadata
slack_sdk.models.views

Functions

def extract_json(item_or_items: Union[JsonObject, Sequence[JsonObject]], *format_args) ‑> Union[Dict[Any, Any], List[Dict[Any, Any]]]

Given a sequence (or single item), attempt to call the to_dict() method on each item and return a plain list. If item is not the expected type, return it unmodified, in case it's already a plain dict or some other user created class.

Args

item_or_items
item(s) to go through
format_args
Any formatting specifiers to pass into the object's to_dict method
Expand source code
def extract_json(
    item_or_items: Union[JsonObject, Sequence[JsonObject]], *format_args
) -> Union[Dict[Any, Any], List[Dict[Any, Any]]]:  # type: ignore
    """
    Given a sequence (or single item), attempt to call the to_dict() method on each
    item and return a plain list. If item is not the expected type, return it
    unmodified, in case it's already a plain dict or some other user created class.

    Args:
      item_or_items: item(s) to go through
      format_args: Any formatting specifiers to pass into the object's to_dict
            method
    """
    try:
        return [  # type: ignore
            elem.to_dict(*format_args) if isinstance(elem, JsonObject) else elem for elem in item_or_items
        ]
    except TypeError:  # not iterable, so try returning it as a single item
        return (  # type: ignore
            item_or_items.to_dict(*format_args) if isinstance(item_or_items, JsonObject) else item_or_items
        )
def show_unknown_key_warning(name: Union[str, object], others: dict)
Expand source code
def show_unknown_key_warning(name: Union[str, object], others: dict):
    if "type" in others:
        others.pop("type")
    if len(others) > 0:
        keys = ", ".join(others.keys())
        logger = logging.getLogger(__name__)
        if isinstance(name, object):
            name = name.__class__.__name__
        logger.debug(
            f"!!! {name}'s constructor args ({keys}) were ignored."
            f"If they should be supported by this library, report this issue to the project :bow: "
            f"https://github.com/slackapi/python-slack-sdk/issues"
        )

Classes

class BaseObject

The base class for all model objects in this module

Expand source code
class BaseObject:
    """The base class for all model objects in this module"""

    def __str__(self):
        return f"<slack_sdk.{self.__class__.__name__}>"

Subclasses

class EnumValidator (attribute: str, enum: Iterable[str])

Decorate a method on a class to mark it as a JSON validator. Validation functions should return true if valid, false if not.

Args

message
Message to be attached to the thrown SlackObjectFormationError
Expand source code
class EnumValidator(JsonValidator):
    def __init__(self, attribute: str, enum: Iterable[str]):
        super().__init__(f"{attribute} attribute must be one of the following values: " f"{', '.join(enum)}")

Ancestors

class JsonObject

The base class for JSON serializable class objects

Expand source code
class JsonObject(BaseObject, metaclass=ABCMeta):
    """The base class for JSON serializable class objects"""

    @property
    @abstractmethod
    def attributes(self) -> Set[str]:
        """Provide a set of attributes of this object that will make up its JSON structure"""
        return set()

    def validate_json(self) -> None:
        """
        Raises:
          SlackObjectFormationError if the object was not valid
        """
        for attribute in (func for func in dir(self) if not func.startswith("__")):
            method = getattr(self, attribute, None)
            if callable(method) and hasattr(method, "validator"):
                method()

    def get_non_null_attributes(self) -> dict:
        """
        Construct a dictionary out of non-null keys (from attributes property)
        present on this object
        """

        def to_dict_compatible(value: Union[dict, list, object, Tuple]) -> Union[dict, list, Any]:
            if isinstance(value, (list, Tuple)):  # skipcq: PYL-R1705
                return [to_dict_compatible(v) for v in value]
            else:
                to_dict = getattr(value, "to_dict", None)
                if to_dict and callable(to_dict):  # skipcq: PYL-R1705
                    return {k: to_dict_compatible(v) for k, v in value.to_dict().items()}  # type: ignore
                else:
                    return value

        def is_not_empty(self, key: str) -> bool:
            value = getattr(self, key, None)
            if value is None:
                return False
            has_len = getattr(value, "__len__", None) is not None
            if has_len:  # skipcq: PYL-R1705
                return len(value) > 0
            else:
                return value is not None

        return {
            key: to_dict_compatible(getattr(self, key, None)) for key in sorted(self.attributes) if is_not_empty(self, key)
        }

    def to_dict(self, *args) -> dict:
        """
        Extract this object as a JSON-compatible, Slack-API-valid dictionary

        Args:
          *args: Any specific formatting args (rare; generally not required)

        Raises:
          SlackObjectFormationError if the object was not valid
        """
        self.validate_json()
        return self.get_non_null_attributes()

    def __repr__(self):
        dict_value = self.get_non_null_attributes()
        if dict_value:  # skipcq: PYL-R1705
            return f"<slack_sdk.{self.__class__.__name__}: {dict_value}>"
        else:
            return self.__str__()

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, JsonObject):
            return False
        return self.to_dict() == other.to_dict()

Ancestors

Subclasses

Instance variables

var attributes : Set[str]

Provide a set of attributes of this object that will make up its JSON structure

Expand source code
@property
@abstractmethod
def attributes(self) -> Set[str]:
    """Provide a set of attributes of this object that will make up its JSON structure"""
    return set()

Methods

def get_non_null_attributes(self) ‑> dict

Construct a dictionary out of non-null keys (from attributes property) present on this object

Expand source code
def get_non_null_attributes(self) -> dict:
    """
    Construct a dictionary out of non-null keys (from attributes property)
    present on this object
    """

    def to_dict_compatible(value: Union[dict, list, object, Tuple]) -> Union[dict, list, Any]:
        if isinstance(value, (list, Tuple)):  # skipcq: PYL-R1705
            return [to_dict_compatible(v) for v in value]
        else:
            to_dict = getattr(value, "to_dict", None)
            if to_dict and callable(to_dict):  # skipcq: PYL-R1705
                return {k: to_dict_compatible(v) for k, v in value.to_dict().items()}  # type: ignore
            else:
                return value

    def is_not_empty(self, key: str) -> bool:
        value = getattr(self, key, None)
        if value is None:
            return False
        has_len = getattr(value, "__len__", None) is not None
        if has_len:  # skipcq: PYL-R1705
            return len(value) > 0
        else:
            return value is not None

    return {
        key: to_dict_compatible(getattr(self, key, None)) for key in sorted(self.attributes) if is_not_empty(self, key)
    }
def to_dict(self, *args) ‑> dict

Extract this object as a JSON-compatible, Slack-API-valid dictionary

Args

*args
Any specific formatting args (rare; generally not required)

Raises

SlackObjectFormationError if the object was not valid

Expand source code
def to_dict(self, *args) -> dict:
    """
    Extract this object as a JSON-compatible, Slack-API-valid dictionary

    Args:
      *args: Any specific formatting args (rare; generally not required)

    Raises:
      SlackObjectFormationError if the object was not valid
    """
    self.validate_json()
    return self.get_non_null_attributes()
def validate_json(self) ‑> None

Raises

SlackObjectFormationError if the object was not valid

Expand source code
def validate_json(self) -> None:
    """
    Raises:
      SlackObjectFormationError if the object was not valid
    """
    for attribute in (func for func in dir(self) if not func.startswith("__")):
        method = getattr(self, attribute, None)
        if callable(method) and hasattr(method, "validator"):
            method()
class JsonValidator (message: str)

Decorate a method on a class to mark it as a JSON validator. Validation functions should return true if valid, false if not.

Args

message
Message to be attached to the thrown SlackObjectFormationError
Expand source code
class JsonValidator:
    def __init__(self, message: str):
        """
        Decorate a method on a class to mark it as a JSON validator. Validation
            functions should return true if valid, false if not.

        Args:
            message: Message to be attached to the thrown SlackObjectFormationError
        """
        self.message = message

    def __call__(self, func: Callable) -> Callable[..., None]:
        @wraps(func)
        def wrapped_f(*args, **kwargs):
            if not func(*args, **kwargs):
                raise SlackObjectFormationError(self.message)

        wrapped_f.validator = True
        return wrapped_f

Subclasses