跳转至

cards

feishu.cards

Card

飞书卡片 JSON 2.0 的链式构造器。

链式调用各方法逐步拼装卡片,再用 feishu.cards.builder.Card.to_dict 或其别名 build 生成最终的 {"schema": "2.0", ...} 字典。未设置过 configheader 时, 它们不会出现在输出中。

飞书文档

卡片 JSON 2.0 结构

示例:

Python Console Session
1
2
3
4
5
6
7
>>> d = Card().header("Report", template="blue").markdown("**hi**").to_dict()
>>> d["schema"], d["header"]["template"]
('2.0', 'blue')
>>> d["body"]["elements"]
[{'tag': 'markdown', 'content': '**hi**'}]
>>> Card().to_dict()
{'schema': '2.0', 'body': {'elements': []}}
源代码位于: feishu/cards/builder.py
Python
class Card:
    r"""
    飞书卡片 JSON 2.0 的链式构造器。

    链式调用各方法逐步拼装卡片,再用 [feishu.cards.builder.Card.to_dict][] 或其别名
    `build` 生成最终的 `{"schema": "2.0", ...}` 字典。未设置过 `config` 与 `header` 时,
    它们不会出现在输出中。

    飞书文档:
        [卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)

    Examples:
        >>> d = Card().header("Report", template="blue").markdown("**hi**").to_dict()
        >>> d["schema"], d["header"]["template"]
        ('2.0', 'blue')
        >>> d["body"]["elements"]
        [{'tag': 'markdown', 'content': '**hi**'}]
        >>> Card().to_dict()
        {'schema': '2.0', 'body': {'elements': []}}
    """

    def __init__(self) -> None:
        self._header: dict[str, Any] | None = None
        self._config: dict[str, Any] = {}
        self._elements: list[dict[str, Any]] = []

    # ------------------------------------------------------------------
    # Header / config
    # ------------------------------------------------------------------

    def header(
        self,
        title: str,
        *,
        subtitle: str | None = None,
        template: str = "blue",
        icon: dict[str, Any] | None = None,
        tags: list[dict[str, Any]] | None = None,
    ) -> Card:
        r"""
        设置卡片标题栏,并返回自身以便链式调用。

        Args:
            title: 标题文案。
            subtitle: 副标题文案。
            template: 标题栏颜色主题,会经 [feishu.cards.validation.validate_template][] 校验。
            icon: 标题栏图标配置。
            tags: 标题栏右侧的文本标签列表(对应 `text_tag_list`)。

        Returns:
            当前 [feishu.cards.builder.Card][] 实例。

        飞书文档:
            [标题组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/title)

        Examples:
            >>> hdr = Card().header("Title", subtitle="sub", template="green").to_dict()["header"]
            >>> hdr["title"], hdr["template"]
            ({'tag': 'plain_text', 'content': 'Title'}, 'green')
            >>> hdr["subtitle"]
            {'tag': 'plain_text', 'content': 'sub'}
        """
        hdr: dict[str, Any] = {
            "title": elements._plain_text(title),
            "template": validate_template(template),
        }
        if subtitle is not None:
            hdr["subtitle"] = elements._plain_text(subtitle)
        if icon is not None:
            hdr["icon"] = icon
        if tags is not None:
            hdr["text_tag_list"] = tags
        self._header = hdr
        return self

    def config(self, **opts: Any) -> Card:
        r"""
        将关键字参数合并进卡片的全局配置(如 `streaming_mode`、`width_mode` 等),并返回自身。

        Args:
            **opts: 待合并进卡片 `config` 的配置项。

        Returns:
            当前 [feishu.cards.builder.Card][] 实例。

        飞书文档:
            [卡片全局配置](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)

        Examples:
            >>> Card().config(width_mode="fill").to_dict()["config"]
            {'width_mode': 'fill'}
        """
        self._config.update(opts)
        return self

    # ------------------------------------------------------------------
    # Element appenders — all delegate to elements.* (Task 3)
    # ------------------------------------------------------------------

    def markdown(
        self,
        content: str,
        *,
        text_align: str | None = None,
        text_size: str | None = None,
        escape: bool = False,
        element_id: str | None = None,
    ) -> Card:
        r"""
        追加一个 markdown 元素(委托给 [feishu.cards.elements.md][]),并返回自身。

        Args:
            content: markdown 文本内容。
            text_align: 文本对齐方式,如 `left`、`center`、`right`。
            text_size: 文本字号,如 `normal`、`heading`。
            escape: 是否先对 `content` 转义控制字符。
            element_id: 元素的自定义 ID,会经 [feishu.cards.validation.validate_element_id][] 校验。

        Returns:
            当前 [feishu.cards.builder.Card][] 实例。

        Examples:
            >>> Card().markdown("**bold**", text_align="center").to_dict()["body"]["elements"][0]
            {'tag': 'markdown', 'content': '**bold**', 'text_align': 'center'}
        """
        self._elements.append(
            elements.md(
                content,
                text_align=text_align,
                text_size=text_size,
                escape=escape,
                element_id=element_id,
            )
        )
        return self

    def text(self, content: str) -> Card:
        r"""
        追加纯文本(不转义)的便捷方法,等价于 [feishu.cards.builder.Card.markdown][]。

        Args:
            content: 文本内容。

        Returns:
            当前 [feishu.cards.builder.Card][] 实例。

        Examples:
            >>> Card().text("plain").to_dict()["body"]["elements"][0]
            {'tag': 'markdown', 'content': 'plain'}
        """
        return self.markdown(content)

    def divider(self) -> Card:
        r"""
        追加一条分割线元素(委托给 [feishu.cards.elements.hr][]),并返回自身。

        Returns:
            当前 [feishu.cards.builder.Card][] 实例。

        Examples:
            >>> Card().divider().to_dict()["body"]["elements"][0]
            {'tag': 'hr'}
        """
        self._elements.append(elements.hr())
        return self

    def image(self, img_key: str, alt: str, **opts: Any) -> Card:
        r"""
        追加一个图片元素(委托给 [feishu.cards.elements.img][]),并返回自身。

        Args:
            img_key: 图片的 key,通过上传图片接口获取。
            alt: 图片的悬浮提示文案(无障碍替代文本)。
            **opts: 其余原样透传给图片元素的字段,如 `scale_type`、`element_id` 等。

        Returns:
            当前 [feishu.cards.builder.Card][] 实例。

        Examples:
            >>> Card().image("img_1", "alt").to_dict()["body"]["elements"][0]["tag"]
            'img'
        """
        self._elements.append(elements.img(img_key, alt, **opts))
        return self

    def button(
        self,
        text: str,
        *,
        value: dict[str, Any] | None = None,
        url: str | None = None,
        type: str = "default",  # noqa: A002 - matches Feishu field name
        confirm: dict[str, Any] | None = None,
        icon: dict[str, Any] | None = None,
        element_id: str | None = None,
    ) -> Card:
        r"""
        追加一个按钮元素(委托给 [feishu.cards.elements.button][]),并返回自身。

        Args:
            text: 按钮文案。
            value: 点击回调时回传的业务数据,生成 `callback` 行为。
            url: 点击时跳转的链接,生成 `open_url` 行为。
            type: 按钮样式类型,如 `default`、`primary`、`danger`。
            confirm: 点击前的二次确认弹窗配置。
            icon: 按钮图标配置。
            element_id: 元素的自定义 ID,会经 [feishu.cards.validation.validate_element_id][] 校验。

        Returns:
            当前 [feishu.cards.builder.Card][] 实例。

        Examples:
            >>> Card().button("Go", value={"x": 1}).to_dict()["body"]["elements"][0]["behaviors"]
            [{'type': 'callback', 'value': {'x': 1}}]
        """
        self._elements.append(
            elements.button(
                text,
                value=value,
                url=url,
                type=type,
                confirm=confirm,
                icon=icon,
                element_id=element_id,
            )
        )
        return self

    def columns(
        self,
        *cols: ColumnSet | dict[str, Any],
        flex_mode: str = "none",
        horizontal_spacing: str | int | None = None,
        **opts: Any,
    ) -> Card:
        r"""
        追加一个分栏(column_set)元素,并返回自身。

        当仅传入单个 [feishu.cards.builder.ColumnSet][] 时,直接调用其
        [feishu.cards.builder.ColumnSet.to_dict][] 追加;此时以该 `ColumnSet` 自身的
        `flex_mode`/间距为准,调用方传入的关键字参数不会生效(此优先级为有意设计)。

        否则(零个、两个及以上参数,或单个非 `ColumnSet` 参数),每个参数都必须是原始的
        列字典(`{"tag": "column", ...}`)。它们会被包裹进经 [feishu.cards.elements.column_set][]
        构造的同一个分栏中,此时调用方的 `flex_mode`、`horizontal_spacing` 及额外的 `**opts`
        均会生效。在该路径上传入 `ColumnSet` 实例会抛出 `TypeError`,以避免静默生成结构错误的嵌套分栏。

        Args:
            *cols: 单个 [feishu.cards.builder.ColumnSet][],或一组原始列字典。
            flex_mode: 列在窄屏下的自适应方式(仅在原始列字典路径生效)。
            horizontal_spacing: 列间水平间距(仅在原始列字典路径生效)。
            **opts: 其余原样透传给分栏字典的字段(仅在原始列字典路径生效)。

        Returns:
            当前 [feishu.cards.builder.Card][] 实例。

        Raises:
            TypeError: 在原始列字典路径上传入了 [feishu.cards.builder.ColumnSet][] 实例时抛出。

        飞书文档:
            [多列布局组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/column-set)

        Examples:
            >>> col = {"tag": "column", "width": "auto", "elements": []}
            >>> Card().columns(col, col, flex_mode="stretch").to_dict()["body"]["elements"][0]["flex_mode"]
            'stretch'
        """
        if len(cols) == 1 and isinstance(cols[0], ColumnSet):
            self._elements.append(cols[0].to_dict())
            return self
        for c in cols:
            if isinstance(c, ColumnSet):
                raise TypeError(
                    "columns() accepts a single ColumnSet, or raw column dicts; "
                    "to add multiple column_sets, call .columns()/.column_set() once per column_set"
                )
        self._elements.append(
            elements.column_set(
                cast(list[dict[str, Any]], list(cols)),
                flex_mode=flex_mode,
                horizontal_spacing=horizontal_spacing,
                **opts,
            )
        )
        return self

    def column_set(self) -> ColumnSet:
        r"""
        返回一个绑定到本卡片的全新 [feishu.cards.builder.ColumnSet][] 子构造器。

        在返回对象上链式调用 [feishu.cards.builder.ColumnSet.column][] 逐列添加内容,
        再调用 [feishu.cards.builder.ColumnSet.end][] 将分栏追加回本卡片并取回本卡片。

        Returns:
            绑定到本卡片的 [feishu.cards.builder.ColumnSet][] 实例。

        Examples:
            >>> card = Card()
            >>> card.column_set().column({"tag": "markdown", "content": "a"}).end() is card
            True
            >>> card.to_dict()["body"]["elements"][0]["tag"]
            'column_set'
        """
        return ColumnSet(parent=self)

    def add(self, raw: dict[str, Any]) -> Card:
        r"""
        逃生通道:原样追加任意元素字典,并返回自身。

        Args:
            raw: 待追加的原始元素字典。

        Returns:
            当前 [feishu.cards.builder.Card][] 实例。

        Examples:
            >>> Card().add({"tag": "custom_thing", "k": 1}).to_dict()["body"]["elements"]
            [{'tag': 'custom_thing', 'k': 1}]
        """
        self._elements.append(raw)
        return self

    # ------------------------------------------------------------------
    # Serialisation
    # ------------------------------------------------------------------

    def to_dict(self) -> dict[str, Any]:
        r"""
        生成卡片 2.0 的骨架字典。

        包含的键:

        - `"schema": "2.0"`:始终存在。
        - `"config": {...}`:仅在至少设置过一项配置时出现。
        - `"header": {...}`:仅在调用过 [feishu.cards.builder.Card.header][] 时出现。
        - `"body": {"elements": [...]}`:始终存在(元素列表可能为空)。

        别名 `build` 与本方法等价。

        Returns:
            卡片 2.0 的字典表示。

        飞书文档:
            [卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)

        Examples:
            >>> Card().to_dict()
            {'schema': '2.0', 'body': {'elements': []}}
            >>> c = Card().text("hi")
            >>> c.build() == c.to_dict()
            True
        """
        out: dict[str, Any] = {"schema": "2.0"}
        if self._config:
            out["config"] = dict(self._config)
        if self._header is not None:
            out["header"] = self._header
        out["body"] = {"elements": list(self._elements)}
        return out

    build = to_dict

header

Python
header(title: str, *, subtitle: str | None = None, template: str = 'blue', icon: dict[str, Any] | None = None, tags: list[dict[str, Any]] | None = None) -> Card

设置卡片标题栏,并返回自身以便链式调用。

参数:

名称 类型 描述 默认
title
str

标题文案。

必需
subtitle
str | None

副标题文案。

None
template
str

标题栏颜色主题,会经 feishu.cards.validation.validate_template 校验。

'blue'
icon
dict[str, Any] | None

标题栏图标配置。

None
tags
list[dict[str, Any]] | None

标题栏右侧的文本标签列表(对应 text_tag_list)。

None

返回:

类型 描述
Card

当前 feishu.cards.builder.Card 实例。

飞书文档

标题组件

示例:

Python Console Session
1
2
3
4
5
>>> hdr = Card().header("Title", subtitle="sub", template="green").to_dict()["header"]
>>> hdr["title"], hdr["template"]
({'tag': 'plain_text', 'content': 'Title'}, 'green')
>>> hdr["subtitle"]
{'tag': 'plain_text', 'content': 'sub'}
源代码位于: feishu/cards/builder.py
Python
def header(
    self,
    title: str,
    *,
    subtitle: str | None = None,
    template: str = "blue",
    icon: dict[str, Any] | None = None,
    tags: list[dict[str, Any]] | None = None,
) -> Card:
    r"""
    设置卡片标题栏,并返回自身以便链式调用。

    Args:
        title: 标题文案。
        subtitle: 副标题文案。
        template: 标题栏颜色主题,会经 [feishu.cards.validation.validate_template][] 校验。
        icon: 标题栏图标配置。
        tags: 标题栏右侧的文本标签列表(对应 `text_tag_list`)。

    Returns:
        当前 [feishu.cards.builder.Card][] 实例。

    飞书文档:
        [标题组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/title)

    Examples:
        >>> hdr = Card().header("Title", subtitle="sub", template="green").to_dict()["header"]
        >>> hdr["title"], hdr["template"]
        ({'tag': 'plain_text', 'content': 'Title'}, 'green')
        >>> hdr["subtitle"]
        {'tag': 'plain_text', 'content': 'sub'}
    """
    hdr: dict[str, Any] = {
        "title": elements._plain_text(title),
        "template": validate_template(template),
    }
    if subtitle is not None:
        hdr["subtitle"] = elements._plain_text(subtitle)
    if icon is not None:
        hdr["icon"] = icon
    if tags is not None:
        hdr["text_tag_list"] = tags
    self._header = hdr
    return self

config

Python
config(**opts: Any) -> Card

将关键字参数合并进卡片的全局配置(如 streaming_modewidth_mode 等),并返回自身。

参数:

名称 类型 描述 默认
**opts
Any

待合并进卡片 config 的配置项。

{}

返回:

类型 描述
Card

当前 feishu.cards.builder.Card 实例。

飞书文档

卡片全局配置

示例:

Python Console Session
>>> Card().config(width_mode="fill").to_dict()["config"]
{'width_mode': 'fill'}
源代码位于: feishu/cards/builder.py
Python
def config(self, **opts: Any) -> Card:
    r"""
    将关键字参数合并进卡片的全局配置(如 `streaming_mode`、`width_mode` 等),并返回自身。

    Args:
        **opts: 待合并进卡片 `config` 的配置项。

    Returns:
        当前 [feishu.cards.builder.Card][] 实例。

    飞书文档:
        [卡片全局配置](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)

    Examples:
        >>> Card().config(width_mode="fill").to_dict()["config"]
        {'width_mode': 'fill'}
    """
    self._config.update(opts)
    return self

markdown

Python
markdown(content: str, *, text_align: str | None = None, text_size: str | None = None, escape: bool = False, element_id: str | None = None) -> Card

追加一个 markdown 元素(委托给 feishu.cards.elements.md),并返回自身。

参数:

名称 类型 描述 默认
content
str

markdown 文本内容。

必需
text_align
str | None

文本对齐方式,如 leftcenterright

None
text_size
str | None

文本字号,如 normalheading

None
escape
bool

是否先对 content 转义控制字符。

False
element_id
str | None

元素的自定义 ID,会经 feishu.cards.validation.validate_element_id 校验。

None

返回:

类型 描述
Card

当前 feishu.cards.builder.Card 实例。

示例:

Python Console Session
>>> Card().markdown("**bold**", text_align="center").to_dict()["body"]["elements"][0]
{'tag': 'markdown', 'content': '**bold**', 'text_align': 'center'}
源代码位于: feishu/cards/builder.py
Python
def markdown(
    self,
    content: str,
    *,
    text_align: str | None = None,
    text_size: str | None = None,
    escape: bool = False,
    element_id: str | None = None,
) -> Card:
    r"""
    追加一个 markdown 元素(委托给 [feishu.cards.elements.md][]),并返回自身。

    Args:
        content: markdown 文本内容。
        text_align: 文本对齐方式,如 `left`、`center`、`right`。
        text_size: 文本字号,如 `normal`、`heading`。
        escape: 是否先对 `content` 转义控制字符。
        element_id: 元素的自定义 ID,会经 [feishu.cards.validation.validate_element_id][] 校验。

    Returns:
        当前 [feishu.cards.builder.Card][] 实例。

    Examples:
        >>> Card().markdown("**bold**", text_align="center").to_dict()["body"]["elements"][0]
        {'tag': 'markdown', 'content': '**bold**', 'text_align': 'center'}
    """
    self._elements.append(
        elements.md(
            content,
            text_align=text_align,
            text_size=text_size,
            escape=escape,
            element_id=element_id,
        )
    )
    return self

text

Python
text(content: str) -> Card

追加纯文本(不转义)的便捷方法,等价于 feishu.cards.builder.Card.markdown

参数:

名称 类型 描述 默认
content
str

文本内容。

必需

返回:

类型 描述
Card

当前 feishu.cards.builder.Card 实例。

示例:

Python Console Session
>>> Card().text("plain").to_dict()["body"]["elements"][0]
{'tag': 'markdown', 'content': 'plain'}
源代码位于: feishu/cards/builder.py
Python
def text(self, content: str) -> Card:
    r"""
    追加纯文本(不转义)的便捷方法,等价于 [feishu.cards.builder.Card.markdown][]。

    Args:
        content: 文本内容。

    Returns:
        当前 [feishu.cards.builder.Card][] 实例。

    Examples:
        >>> Card().text("plain").to_dict()["body"]["elements"][0]
        {'tag': 'markdown', 'content': 'plain'}
    """
    return self.markdown(content)

divider

Python
divider() -> Card

追加一条分割线元素(委托给 feishu.cards.elements.hr),并返回自身。

返回:

类型 描述
Card

当前 feishu.cards.builder.Card 实例。

示例:

Python Console Session
>>> Card().divider().to_dict()["body"]["elements"][0]
{'tag': 'hr'}
源代码位于: feishu/cards/builder.py
Python
def divider(self) -> Card:
    r"""
    追加一条分割线元素(委托给 [feishu.cards.elements.hr][]),并返回自身。

    Returns:
        当前 [feishu.cards.builder.Card][] 实例。

    Examples:
        >>> Card().divider().to_dict()["body"]["elements"][0]
        {'tag': 'hr'}
    """
    self._elements.append(elements.hr())
    return self

image

Python
image(img_key: str, alt: str, **opts: Any) -> Card

追加一个图片元素(委托给 feishu.cards.elements.img),并返回自身。

参数:

名称 类型 描述 默认
img_key
str

图片的 key,通过上传图片接口获取。

必需
alt
str

图片的悬浮提示文案(无障碍替代文本)。

必需
**opts
Any

其余原样透传给图片元素的字段,如 scale_typeelement_id 等。

{}

返回:

类型 描述
Card

当前 feishu.cards.builder.Card 实例。

示例:

Python Console Session
>>> Card().image("img_1", "alt").to_dict()["body"]["elements"][0]["tag"]
'img'
源代码位于: feishu/cards/builder.py
Python
def image(self, img_key: str, alt: str, **opts: Any) -> Card:
    r"""
    追加一个图片元素(委托给 [feishu.cards.elements.img][]),并返回自身。

    Args:
        img_key: 图片的 key,通过上传图片接口获取。
        alt: 图片的悬浮提示文案(无障碍替代文本)。
        **opts: 其余原样透传给图片元素的字段,如 `scale_type`、`element_id` 等。

    Returns:
        当前 [feishu.cards.builder.Card][] 实例。

    Examples:
        >>> Card().image("img_1", "alt").to_dict()["body"]["elements"][0]["tag"]
        'img'
    """
    self._elements.append(elements.img(img_key, alt, **opts))
    return self

button

Python
button(text: str, *, value: dict[str, Any] | None = None, url: str | None = None, type: str = 'default', confirm: dict[str, Any] | None = None, icon: dict[str, Any] | None = None, element_id: str | None = None) -> Card

追加一个按钮元素(委托给 feishu.cards.elements.button),并返回自身。

参数:

名称 类型 描述 默认
text
str

按钮文案。

必需
value
dict[str, Any] | None

点击回调时回传的业务数据,生成 callback 行为。

None
url
str | None

点击时跳转的链接,生成 open_url 行为。

None
type
str

按钮样式类型,如 defaultprimarydanger

'default'
confirm
dict[str, Any] | None

点击前的二次确认弹窗配置。

None
icon
dict[str, Any] | None

按钮图标配置。

None
element_id
str | None

元素的自定义 ID,会经 feishu.cards.validation.validate_element_id 校验。

None

返回:

类型 描述
Card

当前 feishu.cards.builder.Card 实例。

示例:

Python Console Session
>>> Card().button("Go", value={"x": 1}).to_dict()["body"]["elements"][0]["behaviors"]
[{'type': 'callback', 'value': {'x': 1}}]
源代码位于: feishu/cards/builder.py
Python
def button(
    self,
    text: str,
    *,
    value: dict[str, Any] | None = None,
    url: str | None = None,
    type: str = "default",  # noqa: A002 - matches Feishu field name
    confirm: dict[str, Any] | None = None,
    icon: dict[str, Any] | None = None,
    element_id: str | None = None,
) -> Card:
    r"""
    追加一个按钮元素(委托给 [feishu.cards.elements.button][]),并返回自身。

    Args:
        text: 按钮文案。
        value: 点击回调时回传的业务数据,生成 `callback` 行为。
        url: 点击时跳转的链接,生成 `open_url` 行为。
        type: 按钮样式类型,如 `default`、`primary`、`danger`。
        confirm: 点击前的二次确认弹窗配置。
        icon: 按钮图标配置。
        element_id: 元素的自定义 ID,会经 [feishu.cards.validation.validate_element_id][] 校验。

    Returns:
        当前 [feishu.cards.builder.Card][] 实例。

    Examples:
        >>> Card().button("Go", value={"x": 1}).to_dict()["body"]["elements"][0]["behaviors"]
        [{'type': 'callback', 'value': {'x': 1}}]
    """
    self._elements.append(
        elements.button(
            text,
            value=value,
            url=url,
            type=type,
            confirm=confirm,
            icon=icon,
            element_id=element_id,
        )
    )
    return self

columns

Python
columns(*cols: ColumnSet | dict[str, Any], flex_mode: str = 'none', horizontal_spacing: str | int | None = None, **opts: Any) -> Card

追加一个分栏(column_set)元素,并返回自身。

当仅传入单个 feishu.cards.builder.ColumnSet 时,直接调用其 feishu.cards.builder.ColumnSet.to_dict 追加;此时以该 ColumnSet 自身的 flex_mode/间距为准,调用方传入的关键字参数不会生效(此优先级为有意设计)。

否则(零个、两个及以上参数,或单个非 ColumnSet 参数),每个参数都必须是原始的 列字典({"tag": "column", ...})。它们会被包裹进经 feishu.cards.elements.column_set 构造的同一个分栏中,此时调用方的 flex_modehorizontal_spacing 及额外的 **opts 均会生效。在该路径上传入 ColumnSet 实例会抛出 TypeError,以避免静默生成结构错误的嵌套分栏。

参数:

名称 类型 描述 默认
*cols
ColumnSet | dict[str, Any]

单个 feishu.cards.builder.ColumnSet,或一组原始列字典。

()
flex_mode
str

列在窄屏下的自适应方式(仅在原始列字典路径生效)。

'none'
horizontal_spacing
str | int | None

列间水平间距(仅在原始列字典路径生效)。

None
**opts
Any

其余原样透传给分栏字典的字段(仅在原始列字典路径生效)。

{}

返回:

类型 描述
Card

当前 feishu.cards.builder.Card 实例。

引发:

类型 描述
TypeError

在原始列字典路径上传入了 feishu.cards.builder.ColumnSet 实例时抛出。

飞书文档

多列布局组件

示例:

Python Console Session
1
2
3
>>> col = {"tag": "column", "width": "auto", "elements": []}
>>> Card().columns(col, col, flex_mode="stretch").to_dict()["body"]["elements"][0]["flex_mode"]
'stretch'
源代码位于: feishu/cards/builder.py
Python
def columns(
    self,
    *cols: ColumnSet | dict[str, Any],
    flex_mode: str = "none",
    horizontal_spacing: str | int | None = None,
    **opts: Any,
) -> Card:
    r"""
    追加一个分栏(column_set)元素,并返回自身。

    当仅传入单个 [feishu.cards.builder.ColumnSet][] 时,直接调用其
    [feishu.cards.builder.ColumnSet.to_dict][] 追加;此时以该 `ColumnSet` 自身的
    `flex_mode`/间距为准,调用方传入的关键字参数不会生效(此优先级为有意设计)。

    否则(零个、两个及以上参数,或单个非 `ColumnSet` 参数),每个参数都必须是原始的
    列字典(`{"tag": "column", ...}`)。它们会被包裹进经 [feishu.cards.elements.column_set][]
    构造的同一个分栏中,此时调用方的 `flex_mode`、`horizontal_spacing` 及额外的 `**opts`
    均会生效。在该路径上传入 `ColumnSet` 实例会抛出 `TypeError`,以避免静默生成结构错误的嵌套分栏。

    Args:
        *cols: 单个 [feishu.cards.builder.ColumnSet][],或一组原始列字典。
        flex_mode: 列在窄屏下的自适应方式(仅在原始列字典路径生效)。
        horizontal_spacing: 列间水平间距(仅在原始列字典路径生效)。
        **opts: 其余原样透传给分栏字典的字段(仅在原始列字典路径生效)。

    Returns:
        当前 [feishu.cards.builder.Card][] 实例。

    Raises:
        TypeError: 在原始列字典路径上传入了 [feishu.cards.builder.ColumnSet][] 实例时抛出。

    飞书文档:
        [多列布局组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/column-set)

    Examples:
        >>> col = {"tag": "column", "width": "auto", "elements": []}
        >>> Card().columns(col, col, flex_mode="stretch").to_dict()["body"]["elements"][0]["flex_mode"]
        'stretch'
    """
    if len(cols) == 1 and isinstance(cols[0], ColumnSet):
        self._elements.append(cols[0].to_dict())
        return self
    for c in cols:
        if isinstance(c, ColumnSet):
            raise TypeError(
                "columns() accepts a single ColumnSet, or raw column dicts; "
                "to add multiple column_sets, call .columns()/.column_set() once per column_set"
            )
    self._elements.append(
        elements.column_set(
            cast(list[dict[str, Any]], list(cols)),
            flex_mode=flex_mode,
            horizontal_spacing=horizontal_spacing,
            **opts,
        )
    )
    return self

column_set

Python
column_set() -> ColumnSet

返回一个绑定到本卡片的全新 feishu.cards.builder.ColumnSet 子构造器。

在返回对象上链式调用 feishu.cards.builder.ColumnSet.column 逐列添加内容, 再调用 feishu.cards.builder.ColumnSet.end 将分栏追加回本卡片并取回本卡片。

返回:

类型 描述
ColumnSet

绑定到本卡片的 feishu.cards.builder.ColumnSet 实例。

示例:

Python Console Session
1
2
3
4
5
>>> card = Card()
>>> card.column_set().column({"tag": "markdown", "content": "a"}).end() is card
True
>>> card.to_dict()["body"]["elements"][0]["tag"]
'column_set'
源代码位于: feishu/cards/builder.py
Python
def column_set(self) -> ColumnSet:
    r"""
    返回一个绑定到本卡片的全新 [feishu.cards.builder.ColumnSet][] 子构造器。

    在返回对象上链式调用 [feishu.cards.builder.ColumnSet.column][] 逐列添加内容,
    再调用 [feishu.cards.builder.ColumnSet.end][] 将分栏追加回本卡片并取回本卡片。

    Returns:
        绑定到本卡片的 [feishu.cards.builder.ColumnSet][] 实例。

    Examples:
        >>> card = Card()
        >>> card.column_set().column({"tag": "markdown", "content": "a"}).end() is card
        True
        >>> card.to_dict()["body"]["elements"][0]["tag"]
        'column_set'
    """
    return ColumnSet(parent=self)

add

Python
add(raw: dict[str, Any]) -> Card

逃生通道:原样追加任意元素字典,并返回自身。

参数:

名称 类型 描述 默认
raw
dict[str, Any]

待追加的原始元素字典。

必需

返回:

类型 描述
Card

当前 feishu.cards.builder.Card 实例。

示例:

Python Console Session
>>> Card().add({"tag": "custom_thing", "k": 1}).to_dict()["body"]["elements"]
[{'tag': 'custom_thing', 'k': 1}]
源代码位于: feishu/cards/builder.py
Python
def add(self, raw: dict[str, Any]) -> Card:
    r"""
    逃生通道:原样追加任意元素字典,并返回自身。

    Args:
        raw: 待追加的原始元素字典。

    Returns:
        当前 [feishu.cards.builder.Card][] 实例。

    Examples:
        >>> Card().add({"tag": "custom_thing", "k": 1}).to_dict()["body"]["elements"]
        [{'tag': 'custom_thing', 'k': 1}]
    """
    self._elements.append(raw)
    return self

to_dict

Python
to_dict() -> dict[str, Any]

生成卡片 2.0 的骨架字典。

包含的键:

  • "schema": "2.0":始终存在。
  • "config": {...}:仅在至少设置过一项配置时出现。
  • "header": {...}:仅在调用过 feishu.cards.builder.Card.header 时出现。
  • "body": {"elements": [...]}:始终存在(元素列表可能为空)。

别名 build 与本方法等价。

返回:

类型 描述
dict[str, Any]

卡片 2.0 的字典表示。

飞书文档

卡片 JSON 2.0 结构

示例:

Python Console Session
1
2
3
4
5
>>> Card().to_dict()
{'schema': '2.0', 'body': {'elements': []}}
>>> c = Card().text("hi")
>>> c.build() == c.to_dict()
True
源代码位于: feishu/cards/builder.py
Python
def to_dict(self) -> dict[str, Any]:
    r"""
    生成卡片 2.0 的骨架字典。

    包含的键:

    - `"schema": "2.0"`:始终存在。
    - `"config": {...}`:仅在至少设置过一项配置时出现。
    - `"header": {...}`:仅在调用过 [feishu.cards.builder.Card.header][] 时出现。
    - `"body": {"elements": [...]}`:始终存在(元素列表可能为空)。

    别名 `build` 与本方法等价。

    Returns:
        卡片 2.0 的字典表示。

    飞书文档:
        [卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)

    Examples:
        >>> Card().to_dict()
        {'schema': '2.0', 'body': {'elements': []}}
        >>> c = Card().text("hi")
        >>> c.build() == c.to_dict()
        True
    """
    out: dict[str, Any] = {"schema": "2.0"}
    if self._config:
        out["config"] = dict(self._config)
    if self._header is not None:
        out["header"] = self._header
    out["body"] = {"elements": list(self._elements)}
    return out

ColumnSet

卡片 2.0 分栏(column_set)元素的子构造器。

通过链式调用 .column(...) 逐列添加内容,再用 feishu.cards.builder.ColumnSet.to_dict 生成元素字典;若绑定了父级 feishu.cards.builder.Card,可用 feishu.cards.builder.ColumnSet.end 将其追加回父卡片。

飞书文档

多列布局组件

示例:

Python Console Session
1
2
3
4
5
6
>>> cs = ColumnSet(flex_mode="stretch").column({"tag": "markdown", "content": "a"}, weight=1)
>>> d = cs.to_dict()
>>> d["tag"], d["flex_mode"]
('column_set', 'stretch')
>>> d["columns"][0]
{'tag': 'column', 'width': 'auto', 'elements': [{'tag': 'markdown', 'content': 'a'}], 'weight': 1}
源代码位于: feishu/cards/builder.py
Python
class ColumnSet:
    r"""
    卡片 2.0 分栏(column_set)元素的子构造器。

    通过链式调用 `.column(...)` 逐列添加内容,再用 [feishu.cards.builder.ColumnSet.to_dict][]
    生成元素字典;若绑定了父级 [feishu.cards.builder.Card][],可用
    [feishu.cards.builder.ColumnSet.end][] 将其追加回父卡片。

    飞书文档:
        [多列布局组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/column-set)

    Examples:
        >>> cs = ColumnSet(flex_mode="stretch").column({"tag": "markdown", "content": "a"}, weight=1)
        >>> d = cs.to_dict()
        >>> d["tag"], d["flex_mode"]
        ('column_set', 'stretch')
        >>> d["columns"][0]
        {'tag': 'column', 'width': 'auto', 'elements': [{'tag': 'markdown', 'content': 'a'}], 'weight': 1}
    """

    def __init__(
        self,
        *,
        flex_mode: str = "none",
        horizontal_spacing: str | int | None = None,
        parent: Card | None = None,
        **opts: Any,
    ):
        self._flex_mode = flex_mode
        self._horizontal_spacing = horizontal_spacing
        self._parent = parent
        self._opts = opts
        self._columns: list[dict[str, Any]] = []

    def column(
        self,
        *els: dict[str, Any],
        width: str = "auto",
        weight: int | None = None,
        vertical_align: str | None = None,
        **opts: Any,
    ) -> ColumnSet:
        r"""
        追加一列,列内含给定的元素及配置,并返回自身以便链式调用。

        Args:
            *els: 该列内的元素字典。
            width: 列宽,如 `auto`、`weighted`。
            weight: 当 `width="weighted"` 时该列所占权重。
            vertical_align: 列内元素的垂直对齐方式,如 `top`、`center`、`bottom`。
            **opts: 其余原样透传给该列字典的字段。

        Returns:
            当前 [feishu.cards.builder.ColumnSet][] 实例。

        Examples:
            >>> cs = ColumnSet().column({"tag": "markdown", "content": "x"}, width="weighted", weight=2)
            >>> cs.to_dict()["columns"][0]["weight"]
            2
        """
        col: dict[str, Any] = {"tag": "column", "width": width, "elements": list(els)}
        if weight is not None:
            col["weight"] = weight
        if vertical_align is not None:
            col["vertical_align"] = vertical_align
        col.update(opts)
        self._columns.append(col)
        return self

    def to_dict(self) -> dict[str, Any]:
        r"""
        生成分栏元素字典,委托给 [feishu.cards.elements.column_set][] 实现。

        Returns:
            分栏(column_set)元素的字典表示。

        Examples:
            >>> ColumnSet(flex_mode="stretch").to_dict()
            {'tag': 'column_set', 'flex_mode': 'stretch', 'columns': []}
        """
        return elements.column_set(
            self._columns,
            flex_mode=self._flex_mode,
            horizontal_spacing=self._horizontal_spacing,
            **self._opts,
        )

    def end(self) -> Card:
        r"""
        将本分栏追加到绑定的父级 [feishu.cards.builder.Card][],并返回该父卡片。

        Returns:
            绑定的父级 [feishu.cards.builder.Card][] 实例。

        Raises:
            ValueError: 当本 `ColumnSet` 未绑定父卡片(独立构造)时抛出。

        Examples:
            >>> card = Card()
            >>> card.column_set().column({"tag": "markdown", "content": "a"}).end() is card
            True
        """
        if self._parent is None:
            raise ValueError("ColumnSet.end() requires a parent Card; use Card.column_set()")
        self._parent.add(self.to_dict())
        return self._parent

column

Python
column(*els: dict[str, Any], width: str = 'auto', weight: int | None = None, vertical_align: str | None = None, **opts: Any) -> ColumnSet

追加一列,列内含给定的元素及配置,并返回自身以便链式调用。

参数:

名称 类型 描述 默认
*els
dict[str, Any]

该列内的元素字典。

()
width
str

列宽,如 autoweighted

'auto'
weight
int | None

width="weighted" 时该列所占权重。

None
vertical_align
str | None

列内元素的垂直对齐方式,如 topcenterbottom

None
**opts
Any

其余原样透传给该列字典的字段。

{}

返回:

类型 描述
ColumnSet

示例:

Python Console Session
1
2
3
>>> cs = ColumnSet().column({"tag": "markdown", "content": "x"}, width="weighted", weight=2)
>>> cs.to_dict()["columns"][0]["weight"]
2
源代码位于: feishu/cards/builder.py
Python
def column(
    self,
    *els: dict[str, Any],
    width: str = "auto",
    weight: int | None = None,
    vertical_align: str | None = None,
    **opts: Any,
) -> ColumnSet:
    r"""
    追加一列,列内含给定的元素及配置,并返回自身以便链式调用。

    Args:
        *els: 该列内的元素字典。
        width: 列宽,如 `auto`、`weighted`。
        weight: 当 `width="weighted"` 时该列所占权重。
        vertical_align: 列内元素的垂直对齐方式,如 `top`、`center`、`bottom`。
        **opts: 其余原样透传给该列字典的字段。

    Returns:
        当前 [feishu.cards.builder.ColumnSet][] 实例。

    Examples:
        >>> cs = ColumnSet().column({"tag": "markdown", "content": "x"}, width="weighted", weight=2)
        >>> cs.to_dict()["columns"][0]["weight"]
        2
    """
    col: dict[str, Any] = {"tag": "column", "width": width, "elements": list(els)}
    if weight is not None:
        col["weight"] = weight
    if vertical_align is not None:
        col["vertical_align"] = vertical_align
    col.update(opts)
    self._columns.append(col)
    return self

to_dict

Python
to_dict() -> dict[str, Any]

生成分栏元素字典,委托给 feishu.cards.elements.column_set 实现。

返回:

类型 描述
dict[str, Any]

分栏(column_set)元素的字典表示。

示例:

Python Console Session
>>> ColumnSet(flex_mode="stretch").to_dict()
{'tag': 'column_set', 'flex_mode': 'stretch', 'columns': []}
源代码位于: feishu/cards/builder.py
Python
def to_dict(self) -> dict[str, Any]:
    r"""
    生成分栏元素字典,委托给 [feishu.cards.elements.column_set][] 实现。

    Returns:
        分栏(column_set)元素的字典表示。

    Examples:
        >>> ColumnSet(flex_mode="stretch").to_dict()
        {'tag': 'column_set', 'flex_mode': 'stretch', 'columns': []}
    """
    return elements.column_set(
        self._columns,
        flex_mode=self._flex_mode,
        horizontal_spacing=self._horizontal_spacing,
        **self._opts,
    )

end

Python
end() -> Card

将本分栏追加到绑定的父级 feishu.cards.builder.Card,并返回该父卡片。

返回:

类型 描述
Card

绑定的父级 feishu.cards.builder.Card 实例。

引发:

类型 描述
ValueError

当本 ColumnSet 未绑定父卡片(独立构造)时抛出。

示例:

Python Console Session
1
2
3
>>> card = Card()
>>> card.column_set().column({"tag": "markdown", "content": "a"}).end() is card
True
源代码位于: feishu/cards/builder.py
Python
def end(self) -> Card:
    r"""
    将本分栏追加到绑定的父级 [feishu.cards.builder.Card][],并返回该父卡片。

    Returns:
        绑定的父级 [feishu.cards.builder.Card][] 实例。

    Raises:
        ValueError: 当本 `ColumnSet` 未绑定父卡片(独立构造)时抛出。

    Examples:
        >>> card = Card()
        >>> card.column_set().column({"tag": "markdown", "content": "a"}).end() is card
        True
    """
    if self._parent is None:
        raise ValueError("ColumnSet.end() requires a parent Card; use Card.column_set()")
    self._parent.add(self.to_dict())
    return self._parent

CardAction

card.action.trigger 事件的类型化只读视图。

将卡片交互回调事件包装为带类型属性的对象,便于读取触发者、回传值、表单值以及 更新卡片所需的 token 等字段。可接收完整事件载荷、已解包的事件节点,或暴露 .body 映射的事件对象。通常通过 feishu.cards.callback.parse_action 构造。

飞书文档

卡片回传交互

示例:

Python Console Session
>>> event = {
...     "event": {
...         "operator": {"open_id": "ou_1", "user_id": "u1", "union_id": "on_1"},
...         "token": "c-update-token",
...         "action": {"value": {"decision": "approve"}, "tag": "button", "name": "approve"},
...         "context": {"open_message_id": "om_1", "open_chat_id": "oc_1"},
...     }
... }
>>> action = CardAction(event)
>>> action.value
{'decision': 'approve'}
>>> action.open_id, action.message_id, action.token
('ou_1', 'om_1', 'c-update-token')
源代码位于: feishu/cards/callback.py
Python
class CardAction:
    r"""
    `card.action.trigger` 事件的类型化只读视图。

    将卡片交互回调事件包装为带类型属性的对象,便于读取触发者、回传值、表单值以及
    更新卡片所需的 `token` 等字段。可接收完整事件载荷、已解包的事件节点,或暴露
    `.body` 映射的事件对象。通常通过 [feishu.cards.callback.parse_action][] 构造。

    飞书文档:
        [卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)

    Examples:
        >>> event = {
        ...     "event": {
        ...         "operator": {"open_id": "ou_1", "user_id": "u1", "union_id": "on_1"},
        ...         "token": "c-update-token",
        ...         "action": {"value": {"decision": "approve"}, "tag": "button", "name": "approve"},
        ...         "context": {"open_message_id": "om_1", "open_chat_id": "oc_1"},
        ...     }
        ... }
        >>> action = CardAction(event)
        >>> action.value
        {'decision': 'approve'}
        >>> action.open_id, action.message_id, action.token
        ('ou_1', 'om_1', 'c-update-token')
    """

    __slots__ = ("_node", "_action", "_operator", "_context", "raw")

    def __init__(self, event: Any) -> None:
        self.raw = event
        self._node = _node_from(event)
        action = self._node.get("action")
        self._action: Mapping[str, Any] = action if isinstance(action, Mapping) else {}
        operator = self._node.get("operator")
        self._operator: Mapping[str, Any] = operator if isinstance(operator, Mapping) else {}
        context = self._node.get("context")
        self._context: Mapping[str, Any] = context if isinstance(context, Mapping) else {}

    @property
    def value(self) -> dict[str, Any]:
        r"""按钮等组件回传的业务数据;缺失时返回空字典。"""
        v = self._action.get("value")
        return dict(v) if isinstance(v, Mapping) else {}

    @property
    def operator(self) -> dict[str, Any]:
        r"""触发者的 ID 集合,仅含存在的 `open_id`、`user_id`、`union_id` 字段。"""
        out: dict[str, Any] = {}
        for key in ("open_id", "user_id", "union_id"):
            if key in self._operator:
                out[key] = self._operator[key]
        return out

    @property
    def open_id(self) -> str | None:
        r"""触发者的 `open_id`;缺失时返回 `None`。"""
        return self._operator.get("open_id")

    @property
    def user_id(self) -> str | None:
        r"""触发者的 `user_id`;缺失时返回 `None`。"""
        return self._operator.get("user_id")

    @property
    def union_id(self) -> str | None:
        r"""触发者的 `union_id`;缺失时返回 `None`。"""
        return self._operator.get("union_id")

    @property
    def token(self) -> str | None:
        r"""
        更新卡片所需的凭证(有效期 30 分钟、最多更新 2 次),并非 Webhook 校验 token。

        飞书文档:
            [延时更新卡片](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication/delay-update-card)
        """
        return self._node.get("token")

    @property
    def message_id(self) -> str | None:
        r"""承载该卡片的消息 ID(`open_message_id`);缺失时返回 `None`。"""
        return self._context.get("open_message_id")

    @property
    def chat_id(self) -> str | None:
        r"""承载该卡片的会话 ID(`open_chat_id`);缺失时返回 `None`。"""
        return self._context.get("open_chat_id")

    @property
    def tag(self) -> str | None:
        r"""触发交互的组件标签,如 `button`;缺失时返回 `None`。"""
        return self._action.get("tag")

    @property
    def name(self) -> str | None:
        r"""触发交互的组件名称;缺失时返回 `None`。"""
        return self._action.get("name")

    @property
    def form_value(self) -> dict[str, Any]:
        r"""表单容器提交时回传的各字段取值;缺失时返回空字典。"""
        fv = self._action.get("form_value")
        return dict(fv) if isinstance(fv, Mapping) else {}

value property

Python
value: dict[str, Any]

按钮等组件回传的业务数据;缺失时返回空字典。

operator property

Python
operator: dict[str, Any]

触发者的 ID 集合,仅含存在的 open_iduser_idunion_id 字段。

open_id property

Python
open_id: str | None

触发者的 open_id;缺失时返回 None

user_id property

Python
user_id: str | None

触发者的 user_id;缺失时返回 None

union_id property

Python
union_id: str | None

触发者的 union_id;缺失时返回 None

token property

Python
token: str | None

更新卡片所需的凭证(有效期 30 分钟、最多更新 2 次),并非 Webhook 校验 token。

飞书文档

延时更新卡片

message_id property

Python
message_id: str | None

承载该卡片的消息 ID(open_message_id);缺失时返回 None

chat_id property

Python
chat_id: str | None

承载该卡片的会话 ID(open_chat_id);缺失时返回 None

tag property

Python
tag: str | None

触发交互的组件标签,如 button;缺失时返回 None

name property

Python
name: str | None

触发交互的组件名称;缺失时返回 None

form_value property

Python
form_value: dict[str, Any]

表单容器提交时回传的各字段取值;缺失时返回空字典。

parse_action

Python
parse_action(event: Any) -> CardAction

card.action.trigger 事件解析为类型化的 feishu.cards.callback.CardAction 视图。

参数:

名称 类型 描述 默认

event

Any

卡片交互回调事件,可为完整事件载荷、已解包的事件节点,或暴露 .body 映射的事件对象。

必需

返回:

类型 描述
CardAction

包装该事件的 feishu.cards.callback.CardAction 实例。

引发:

类型 描述
TypeError

当无法从 event 中提取卡片交互节点时抛出。

飞书文档

卡片回传交互

示例:

Python Console Session
1
2
3
4
5
>>> action = parse_action({"event": {"action": {"value": {"decision": "approve"}}}})
>>> action.value
{'decision': 'approve'}
>>> parse_action({"event": {"action": {}}}).tag is None
True
源代码位于: feishu/cards/callback.py
Python
def parse_action(event: Any) -> CardAction:
    r"""
    将 `card.action.trigger` 事件解析为类型化的 [feishu.cards.callback.CardAction][] 视图。

    Args:
        event: 卡片交互回调事件,可为完整事件载荷、已解包的事件节点,或暴露 `.body` 映射的事件对象。

    Returns:
        包装该事件的 [feishu.cards.callback.CardAction][] 实例。

    Raises:
        TypeError: 当无法从 `event` 中提取卡片交互节点时抛出。

    飞书文档:
        [卡片回传交互](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-callback-communication)

    Examples:
        >>> action = parse_action({"event": {"action": {"value": {"decision": "approve"}}}})
        >>> action.value
        {'decision': 'approve'}
        >>> parse_action({"event": {"action": {}}}).tag is None
        True
    """
    return CardAction(event)

button

Python
button(text: str, *, value: dict[str, Any] | None = None, url: str | None = None, type: str = 'default', confirm: dict[str, Any] | None = None, icon: dict[str, Any] | None = None, element_id: str | None = None) -> dict[str, Any]

构造卡片 2.0 的按钮元素。

value 会生成 callback 交互行为,url 会生成 open_url 交互行为,二者可同时存在。 回调触发的 card.action.trigger 事件可用 feishu.cards.callback.parse_action 解析。

参数:

名称 类型 描述 默认

text

str

按钮文案。

必需

value

dict[str, Any] | None

点击回调时回传的业务数据,生成 callback 行为。

None

url

str | None

点击时跳转的链接,生成 open_url 行为。

None

type

str

按钮样式类型,如 defaultprimarydanger

'default'

confirm

dict[str, Any] | None

点击前的二次确认弹窗配置。

None

icon

dict[str, Any] | None

按钮图标配置。

None

element_id

str | None

元素的自定义 ID,会经 feishu.cards.validation.validate_element_id 校验。

None

返回:

类型 描述
dict[str, Any]

按钮元素的字典表示。

飞书文档

按钮组件

示例:

Python Console Session
1
2
3
4
5
6
>>> button("Click", value={"k": "v"})["behaviors"]
[{'type': 'callback', 'value': {'k': 'v'}}]
>>> button("Open", url="https://x.com", type="primary")["behaviors"]
[{'type': 'open_url', 'default_url': 'https://x.com'}]
>>> button("Both", value={"a": 1}, url="https://x.com")["behaviors"]
[{'type': 'callback', 'value': {'a': 1}}, {'type': 'open_url', 'default_url': 'https://x.com'}]
源代码位于: feishu/cards/elements.py
Python
def button(
    text: str,
    *,
    value: dict[str, Any] | None = None,
    url: str | None = None,
    type: str = "default",  # noqa: A002 - matches Feishu's field name
    confirm: dict[str, Any] | None = None,
    icon: dict[str, Any] | None = None,
    element_id: str | None = None,
) -> dict[str, Any]:
    r"""
    构造卡片 2.0 的按钮元素。

    `value` 会生成 `callback` 交互行为,`url` 会生成 `open_url` 交互行为,二者可同时存在。
    回调触发的 `card.action.trigger` 事件可用 [feishu.cards.callback.parse_action][] 解析。

    Args:
        text: 按钮文案。
        value: 点击回调时回传的业务数据,生成 `callback` 行为。
        url: 点击时跳转的链接,生成 `open_url` 行为。
        type: 按钮样式类型,如 `default`、`primary`、`danger`。
        confirm: 点击前的二次确认弹窗配置。
        icon: 按钮图标配置。
        element_id: 元素的自定义 ID,会经 [feishu.cards.validation.validate_element_id][] 校验。

    Returns:
        按钮元素的字典表示。

    飞书文档:
        [按钮组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/interactive-components/button)

    Examples:
        >>> button("Click", value={"k": "v"})["behaviors"]
        [{'type': 'callback', 'value': {'k': 'v'}}]
        >>> button("Open", url="https://x.com", type="primary")["behaviors"]
        [{'type': 'open_url', 'default_url': 'https://x.com'}]
        >>> button("Both", value={"a": 1}, url="https://x.com")["behaviors"]
        [{'type': 'callback', 'value': {'a': 1}}, {'type': 'open_url', 'default_url': 'https://x.com'}]
    """
    el: dict[str, Any] = {"tag": "button", "text": _plain_text(text), "type": type}
    behaviors: list[dict[str, Any]] = []
    if value is not None:
        behaviors.append({"type": "callback", "value": value})
    if url is not None:
        behaviors.append({"type": "open_url", "default_url": url})
    if behaviors:
        el["behaviors"] = behaviors
    if confirm is not None:
        el["confirm"] = confirm
    if icon is not None:
        el["icon"] = icon
    if element_id is not None:
        el["element_id"] = validate_element_id(element_id)
    return el

column_set

Python
column_set(columns: list[dict[str, Any]], *, flex_mode: str = 'none', horizontal_spacing: str | int | None = None, element_id: str | None = None, **opts: Any) -> dict[str, Any]

构造卡片 2.0 的分栏(column_set)元素。

参数:

名称 类型 描述 默认

columns

list[dict[str, Any]]

分栏列表,每一项为一个 column 字典。

必需

flex_mode

str

列在窄屏下的自适应方式,如 nonestretchflowbisecttrisect

'none'

horizontal_spacing

str | int | None

列间水平间距;为整数时会经 feishu.cards.validation.clamp_spacing 裁剪到 [-99, 99]

None

element_id

str | None

元素的自定义 ID,会经 feishu.cards.validation.validate_element_id 校验。

None

**opts

Any

其余原样透传给元素字典的字段。

{}

返回:

类型 描述
dict[str, Any]

分栏元素的字典表示。

飞书文档

多列布局组件

示例:

Python Console Session
1
2
3
4
>>> column_set([{"tag": "column", "elements": []}], flex_mode="stretch")
{'tag': 'column_set', 'flex_mode': 'stretch', 'columns': [{'tag': 'column', 'elements': []}]}
>>> column_set([], horizontal_spacing=200)["horizontal_spacing"]
99
源代码位于: feishu/cards/elements.py
Python
def column_set(
    columns: list[dict[str, Any]],
    *,
    flex_mode: str = "none",
    horizontal_spacing: str | int | None = None,
    element_id: str | None = None,
    **opts: Any,
) -> dict[str, Any]:
    r"""
    构造卡片 2.0 的分栏(column_set)元素。

    Args:
        columns: 分栏列表,每一项为一个 `column` 字典。
        flex_mode: 列在窄屏下的自适应方式,如 `none`、`stretch`、`flow`、`bisect`、`trisect`。
        horizontal_spacing: 列间水平间距;为整数时会经 [feishu.cards.validation.clamp_spacing][] 裁剪到 `[-99, 99]`。
        element_id: 元素的自定义 ID,会经 [feishu.cards.validation.validate_element_id][] 校验。
        **opts: 其余原样透传给元素字典的字段。

    Returns:
        分栏元素的字典表示。

    飞书文档:
        [多列布局组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/containers/column-set)

    Examples:
        >>> column_set([{"tag": "column", "elements": []}], flex_mode="stretch")
        {'tag': 'column_set', 'flex_mode': 'stretch', 'columns': [{'tag': 'column', 'elements': []}]}
        >>> column_set([], horizontal_spacing=200)["horizontal_spacing"]
        99
    """
    el: dict[str, Any] = {"tag": "column_set", "flex_mode": flex_mode, "columns": columns}
    if horizontal_spacing is not None:
        if isinstance(horizontal_spacing, int) and not isinstance(horizontal_spacing, bool):
            horizontal_spacing = clamp_spacing(horizontal_spacing)
        el["horizontal_spacing"] = horizontal_spacing
    if element_id is not None:
        el["element_id"] = validate_element_id(element_id)
    el.update(opts)
    return el

hr

Python
hr() -> dict[str, Any]

构造卡片 2.0 的分割线元素。

返回:

类型 描述
dict[str, Any]

分割线元素的字典表示。

飞书文档

分割线组件

示例:

Python Console Session
>>> hr()
{'tag': 'hr'}
源代码位于: feishu/cards/elements.py
Python
def hr() -> dict[str, Any]:
    r"""
    构造卡片 2.0 的分割线元素。

    Returns:
        分割线元素的字典表示。

    飞书文档:
        [分割线组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/divider)

    Examples:
        >>> hr()
        {'tag': 'hr'}
    """
    return {"tag": "hr"}

img

Python
img(img_key: str, alt: str, *, element_id: str | None = None, **opts: Any) -> dict[str, Any]

构造卡片 2.0 的图片元素。

参数:

名称 类型 描述 默认

img_key

str

图片的 key,通过上传图片接口获取。

必需

alt

str

图片的悬浮提示文案(无障碍替代文本)。

必需

element_id

str | None

元素的自定义 ID,会经 feishu.cards.validation.validate_element_id 校验。

None

**opts

Any

其余原样透传给元素字典的字段,如 scale_typesize 等。

{}

返回:

类型 描述
dict[str, Any]

图片元素的字典表示。

飞书文档

图片组件

示例:

Python Console Session
1
2
3
4
5
>>> el = img("img_v2_abc", "a cat", scale_type="crop_center")
>>> el["tag"], el["img_key"], el["scale_type"]
('img', 'img_v2_abc', 'crop_center')
>>> el["alt"]
{'tag': 'plain_text', 'content': 'a cat'}
源代码位于: feishu/cards/elements.py
Python
def img(img_key: str, alt: str, *, element_id: str | None = None, **opts: Any) -> dict[str, Any]:
    r"""
    构造卡片 2.0 的图片元素。

    Args:
        img_key: 图片的 key,通过上传图片接口获取。
        alt: 图片的悬浮提示文案(无障碍替代文本)。
        element_id: 元素的自定义 ID,会经 [feishu.cards.validation.validate_element_id][] 校验。
        **opts: 其余原样透传给元素字典的字段,如 `scale_type`、`size` 等。

    Returns:
        图片元素的字典表示。

    飞书文档:
        [图片组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/image)

    Examples:
        >>> el = img("img_v2_abc", "a cat", scale_type="crop_center")
        >>> el["tag"], el["img_key"], el["scale_type"]
        ('img', 'img_v2_abc', 'crop_center')
        >>> el["alt"]
        {'tag': 'plain_text', 'content': 'a cat'}
    """
    el: dict[str, Any] = {"tag": "img", "img_key": img_key, "alt": _plain_text(alt)}
    if element_id is not None:
        el["element_id"] = validate_element_id(element_id)
    el.update(opts)
    return el

md

Python
md(content: str, *, text_align: str | None = None, text_size: str | None = None, escape: bool = False, element_id: str | None = None) -> dict[str, Any]

构造卡片 2.0 的 markdown 元素(tag 为 markdown,而非旧版的 div)。

参数:

名称 类型 描述 默认

content

str

markdown 文本内容。

必需

text_align

str | None

文本对齐方式,如 leftcenterright

None

text_size

str | None

文本字号,如 normalheading

None

escape

bool

是否先对 content 调用 feishu.cards.markdown.escape_markdown 转义控制字符。

False

element_id

str | None

元素的自定义 ID,会经 feishu.cards.validation.validate_element_id 校验。

None

返回:

类型 描述
dict[str, Any]

markdown 元素的字典表示。

飞书文档

富文本组件

示例:

Python Console Session
1
2
3
4
5
6
>>> md("hello")
{'tag': 'markdown', 'content': 'hello'}
>>> md("a*b", escape=True)["content"]
'a*b'
>>> md("h", text_align="center", element_id="md")
{'tag': 'markdown', 'content': 'h', 'text_align': 'center', 'element_id': 'md'}
源代码位于: feishu/cards/elements.py
Python
def md(
    content: str,
    *,
    text_align: str | None = None,
    text_size: str | None = None,
    escape: bool = False,
    element_id: str | None = None,
) -> dict[str, Any]:
    r"""
    构造卡片 2.0 的 markdown 元素(tag 为 `markdown`,而非旧版的 `div`)。

    Args:
        content: markdown 文本内容。
        text_align: 文本对齐方式,如 `left`、`center`、`right`。
        text_size: 文本字号,如 `normal`、`heading`。
        escape: 是否先对 `content` 调用 [feishu.cards.markdown.escape_markdown][] 转义控制字符。
        element_id: 元素的自定义 ID,会经 [feishu.cards.validation.validate_element_id][] 校验。

    Returns:
        markdown 元素的字典表示。

    飞书文档:
        [富文本组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text)

    Examples:
        >>> md("hello")
        {'tag': 'markdown', 'content': 'hello'}
        >>> md("a*b", escape=True)["content"]
        'a*b'
        >>> md("h", text_align="center", element_id="md")
        {'tag': 'markdown', 'content': 'h', 'text_align': 'center', 'element_id': 'md'}
    """
    if escape:
        content = escape_markdown(content)
    el: dict[str, Any] = {"tag": "markdown", "content": content}
    if text_align is not None:
        el["text_align"] = text_align
    if text_size is not None:
        el["text_size"] = text_size
    if element_id is not None:
        el["element_id"] = validate_element_id(element_id)
    return el

alert_card

Python
alert_card(content: str, title: str, template: str = 'red', buttons: list[dict[str, Any]] | None = None) -> dict[str, Any]

构造含标题栏、markdown 正文,以及可选按钮的告警卡片。

参数:

名称 类型 描述 默认

content

str

markdown 正文内容。

必需

title

str

标题栏文案。

必需

template

str

标题栏颜色主题,默认 red,会经 feishu.cards.validation.validate_template 校验。

'red'

buttons

list[dict[str, Any]] | None

预先构造好的按钮元素列表(如由 feishu.cards.elements.button 生成),依次追加到正文之后。

None

返回:

类型 描述
dict[str, Any]

卡片 2.0 的字典表示。

飞书文档

卡片 JSON 2.0 结构

示例:

Python Console Session
1
2
3
4
5
6
>>> from feishu.cards.elements import button
>>> d = alert_card("Heads up", title="Alert", buttons=[button("OK", value={"d": "y"})])
>>> d["header"]["template"]
'red'
>>> [e["tag"] for e in d["body"]["elements"]]
['markdown', 'button']
源代码位于: feishu/cards/factories.py
Python
def alert_card(
    content: str,
    title: str,
    template: str = "red",
    buttons: list[dict[str, Any]] | None = None,
) -> dict[str, Any]:
    r"""
    构造含标题栏、markdown 正文,以及可选按钮的告警卡片。

    Args:
        content: markdown 正文内容。
        title: 标题栏文案。
        template: 标题栏颜色主题,默认 `red`,会经 [feishu.cards.validation.validate_template][] 校验。
        buttons: 预先构造好的按钮元素列表(如由 [feishu.cards.elements.button][] 生成),依次追加到正文之后。

    Returns:
        卡片 2.0 的字典表示。

    飞书文档:
        [卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)

    Examples:
        >>> from feishu.cards.elements import button
        >>> d = alert_card("Heads up", title="Alert", buttons=[button("OK", value={"d": "y"})])
        >>> d["header"]["template"]
        'red'
        >>> [e["tag"] for e in d["body"]["elements"]]
        ['markdown', 'button']
    """
    card = Card().header(title, template=template).markdown(content)
    for btn in buttons or []:
        card.add(btn)
    return card.to_dict()

table_card

Python
table_card(headers: list[str], rows: list[list[Any]], title: str | None = None) -> dict[str, Any]

将表头与数据行渲染为 GFM markdown 表格,置于单个 markdown 元素中。

采用稳妥的 markdown 表格实现,而非卡片 2.0 原生 table 组件。单元格中的竖线 | 会被转义,换行符会折叠为空格,以免破坏表格结构。

参数:

名称 类型 描述 默认

headers

list[str]

表头文案列表。

必需

rows

list[list[Any]]

数据行列表,每一行的单元格数必须与 headers 等长。

必需

title

str | None

标题栏文案;为 None 时不生成标题栏。

None

返回:

类型 描述
dict[str, Any]

卡片 2.0 的字典表示。

引发:

类型 描述
ValueError

当某一行的单元格数与 headers 长度不一致时抛出。

飞书文档

富文本组件

示例:

Python Console Session
>>> d = table_card(["Name", "Age"], [["Alice", 30], ["Bob", 25]])
>>> print(d["body"]["elements"][0]["content"])
| Name | Age |
| --- | --- |
| Alice | 30 |
| Bob | 25 |
>>> table_card(["A", "B"], [["only-one"]])
Traceback (most recent call last):
...
ValueError: table_card row 0 has 1 cells, expected 2
源代码位于: feishu/cards/factories.py
Python
def table_card(
    headers: list[str],
    rows: list[list[Any]],
    title: str | None = None,
) -> dict[str, Any]:
    r"""
    将表头与数据行渲染为 GFM markdown 表格,置于单个 markdown 元素中。

    采用稳妥的 markdown 表格实现,而非卡片 2.0 原生 `table` 组件。单元格中的竖线 `|`
    会被转义,换行符会折叠为空格,以免破坏表格结构。

    Args:
        headers: 表头文案列表。
        rows: 数据行列表,每一行的单元格数必须与 `headers` 等长。
        title: 标题栏文案;为 `None` 时不生成标题栏。

    Returns:
        卡片 2.0 的字典表示。

    Raises:
        ValueError: 当某一行的单元格数与 `headers` 长度不一致时抛出。

    飞书文档:
        [富文本组件](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text)

    Examples:
        >>> d = table_card(["Name", "Age"], [["Alice", 30], ["Bob", 25]])
        >>> print(d["body"]["elements"][0]["content"])
        | Name | Age |
        | --- | --- |
        | Alice | 30 |
        | Bob | 25 |
        >>> table_card(["A", "B"], [["only-one"]])
        Traceback (most recent call last):
        ...
        ValueError: table_card row 0 has 1 cells, expected 2
    """
    card = Card()
    if title is not None:
        card.header(title)
    card.markdown(_gfm_table(headers, rows))
    return card.to_dict()

text_card

Python
text_card(content: str, title: str | None = None, template: str = 'blue') -> dict[str, Any]

构造仅含一个 markdown 元素的卡片,并在提供 title 时附带标题栏。

参数:

名称 类型 描述 默认

content

str

markdown 正文内容。

必需

title

str | None

标题栏文案;为 None 时不生成标题栏。

None

template

str

标题栏颜色主题,会经 feishu.cards.validation.validate_template 校验。

'blue'

返回:

类型 描述
dict[str, Any]

卡片 2.0 的字典表示。

飞书文档

卡片 JSON 2.0 结构

示例:

Python Console Session
1
2
3
4
5
6
7
>>> d = text_card("hello", title="Greeting", template="green")
>>> d["header"]["title"], d["header"]["template"]
({'tag': 'plain_text', 'content': 'Greeting'}, 'green')
>>> d["body"]["elements"]
[{'tag': 'markdown', 'content': 'hello'}]
>>> "header" in text_card("hello")
False
源代码位于: feishu/cards/factories.py
Python
def text_card(content: str, title: str | None = None, template: str = "blue") -> dict[str, Any]:
    r"""
    构造仅含一个 markdown 元素的卡片,并在提供 `title` 时附带标题栏。

    Args:
        content: markdown 正文内容。
        title: 标题栏文案;为 `None` 时不生成标题栏。
        template: 标题栏颜色主题,会经 [feishu.cards.validation.validate_template][] 校验。

    Returns:
        卡片 2.0 的字典表示。

    飞书文档:
        [卡片 JSON 2.0 结构](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-structure)

    Examples:
        >>> d = text_card("hello", title="Greeting", template="green")
        >>> d["header"]["title"], d["header"]["template"]
        ({'tag': 'plain_text', 'content': 'Greeting'}, 'green')
        >>> d["body"]["elements"]
        [{'tag': 'markdown', 'content': 'hello'}]
        >>> "header" in text_card("hello")
        False
    """
    card = Card()
    if title is not None:
        card.header(title, template=template)
    card.markdown(content)
    return card.to_dict()

escape_markdown

Python
escape_markdown(text: str) -> str

将 lark-markdown 控制字符转义为对应的 HTML 实体。

用于将任意用户或大模型生成的文本安全地嵌入卡片 2.0 的 markdown 元素中, 使其中的控制字符不会破坏渲染效果。

参数:

名称 类型 描述 默认

text

str

待转义的原始文本。

必需

返回:

类型 描述
str

所有控制字符均被替换为 HTML 实体后的文本。

飞书文档

Markdown标签

示例:

Python Console Session
1
2
3
4
5
6
>>> escape_markdown("a*b_c")
'a*b_c'
>>> escape_markdown("~")
'∼'
>>> escape_markdown("hello world 123")
'hello world 123'
源代码位于: feishu/cards/markdown.py
Python
def escape_markdown(text: str) -> str:
    r"""
    将 lark-markdown 控制字符转义为对应的 HTML 实体。

    用于将任意用户或大模型生成的文本安全地嵌入卡片 2.0 的 `markdown` 元素中,
    使其中的控制字符不会破坏渲染效果。

    Args:
        text: 待转义的原始文本。

    Returns:
        所有控制字符均被替换为 HTML 实体后的文本。

    飞书文档:
        [Markdown标签](https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-json-v2-components/content-components/rich-text)

    Examples:
        >>> escape_markdown("a*b_c")
        'a*b_c'
        >>> escape_markdown("~")
        '∼'
        >>> escape_markdown("hello world 123")
        'hello world 123'
    """
    return text.translate(_TRANSLATION)