mcpField
N
notion-sdk

notion-sdk

github.com/terrylica生产力1132 次安装今天更新
代码仓库

关于 notion-sdk

notion-sdk 是通过官方 Python notion-client SDK 自动化操作 Notion 的技能,提供创建页面、添加内容块和查询数据库的脚本,并支持令牌验证与重试处理。

主要功能

  1. 01创建页面和数据库条目
  2. 02追加格式化内容块
  3. 03查询、筛选和排序数据库
  4. 04验证集成令牌
  5. 05重试限流和服务器错误请求

适用场景

  1. 01通过 Python 工作流创建 Notion 页面
  2. 02向页面添加结构化内容
  3. 03检索筛选后的数据库记录
  4. 04处理暂时性 API 错误

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/terrylica/cc-skills --skill notion-sdk

安装后在 Claude Code 中输入/notion-sdk确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
block-types.md
evolution-log.md
pagination.md
property-types.md
rich-text.md
scripts/
add_blocks.py
create_page.py
notion_wrapper.py
query_database.py
tests/
test_block_builders.py
test_client.py
test_filter_builders.py
test_integration.py
test_property_builders.py

详细介绍

Notion SDK 技能

使用官方 notion-client Python SDK 以编程方式控制 Notion。当前版本请参阅 PyPI。

自我演进的技能:此技能会在使用过程中不断改进。如果说明有误、参数发生变化,或需要使用变通方案,请立即修复此文件,不要拖延。仅针对真实且可复现的问题进行更新。

何时使用此技能

在以下情况下使用此技能:

  • 通过 API 在 Notion 中创建页面或数据库
  • 以编程方式查询 Notion 数据库
  • 向 Notion 页面添加块(文本、代码、标题)
  • 使用 Python 自动化 Notion 工作流
  • 将外部数据源与 Notion 集成

预检:收集令牌

执行任何 Notion API 操作前,先收集集成令牌:

AskUserQuestion(questions=[{
    "question": "Please provide your Notion Integration Token (starts with ntn_ or secret_)",
    "header": "Notion Token",
    "options": [
        {"label": "I have a token ready", "description": "Token from notion.so/my-integrations"},
        {"label": "Need to create one", "description": "Go to notion.so/my-integrations → New integration"}
    ],
    "multiSelect": false
}])

用户提供令牌后:

  1. 验证格式(必须以 ntn_ 或 secret_ 开头)
  2. 使用 scripts/notion_wrapper.py 中的 validate_token() 进行测试
  3. 提醒用户:必须将每个页面/数据库共享给该集成

快速入门

1. 在数据库中创建页面
from notion_client import Client
from scripts.create_page import (
    create_database_page,
    title_property,
    status_property,
    date_property,
)

client = Client(auth="ntn_...")
page = create_database_page(
    client,
    data_source_id="abc123...",  # Database ID
    properties={
        "Name": title_property("My New Task"),
        "Status": status_property("In Progress"),
        "Due Date": date_property("2025-12-31"),
    }
)
print(f"Created: {page['url']}")
2. 添加内容块
from scripts.add_blocks import (
    append_blocks,
    heading,
    paragraph,
    bullet,
    code_block,
    callout,
)

blocks = [
    heading("Overview", level=2),
    paragraph("This page was created via the Notion API."),
    callout("Remember to share the page with your integration!", emoji="⚠️"),
    heading("Tasks", level=3),
    bullet("First task"),
    bullet("Second task"),
    code_block("print('Hello, Notion!')", language="python"),
]
append_blocks(client, page["id"], blocks)
3. 查询数据库
from scripts.query_database import (
    query_data_source,
    checkbox_filter,
    status_filter,
    and_filter,
    sort_by_property,
)

# Find incomplete high-priority items
results = query_data_source(
    client,
    data_source_id="abc123...",
    filter_obj=and_filter(
        checkbox_filter("Done", False),
        status_filter("Priority", "High")
    ),
    sorts=[sort_by_property("Due Date", "ascending")]
)
for page in results:
    title = page["properties"]["Name"]["title"][0]["plain_text"]
    print(f"- {title}")

可用脚本

脚本用途
notion_wrapper.py客户端设置、令牌验证、重试封装
create_page.py创建页面、属性构建器
add_blocks.py追加块、块类型构建器
query_database.py查询、筛选、排序、搜索

参考资料

重要限制

速率限制
  • 平均每秒 3 次请求(短时间内可容忍突发请求)
  • 使用 api_call_with_retry() 自动处理速率限制
  • 429 响应包含 Retry-After 标头
身份验证模型
  • 必须进行 页面级共享(而非整个工作区共享)
  • 用户必须将集成明确添加到每个页面/数据库:
    • 页面 → ... 菜单 → 连接 → 添加连接 → 选择集成
API 版本(v2.6.0+)
  • 多数据源数据库使用 data_source_id,而非 database_id
  • 简单数据库仍可使用旧版 database_id
  • 脚本会自动处理这两种模式
不支持的操作
  • 修改工作区设置
  • 管理用户权限
  • 创建/管理模板
  • 访问账单/订阅

API 行为模式

通过集成测试发现的见解(请查阅测试引用以进行验证)。

速率限制与重试逻辑

api_call_with_retry() 会自动处理暂时性故障:

错误类型行为等待策略
429 速率受限重试遵循 Retry-After 标头(默认 1s)
500 服务器错误重试指数退避:1s、2s、4s
身份验证/验证立即失败不重试

引用:test_client.py::TestRetryLogic(第 146-193 行)

写入后读取一致性

新建的块可能无法立即查询。请至少延迟 0.5s:

append_blocks(client, page_id, blocks)
time.sleep(0.5)  # Eventual consistency delay
children = client.blocks.children.list(page_id)

引用:test_integration.py::TestBlockAppend::test_retrieve_appended_blocks(第 298 行)

v2.6.0 API 迁移
旧模式新模式(v2.6.0+)
client.databases.query()client.data_sources.query()
filter: {"value": "database"}filter: {"value": "data_source"}

引用:test_integration.py::TestDatabaseQuery(第 110 行)

仅归档删除

无法通过 API 永久删除页面——只能将其归档(移至回收站):

client.pages.update(page_id, archived=True)  # Trash, not delete

引用:test_integration.py 清理 fixture(第 72-76 行)

边界情况与验证

属性构建器的边界情况
输入行为有效?
空字符串 ""创建空内容是
空数组 []清空多选项/关联是
数字类型的 None清空属性值是
零 0有效数字(不会被视为假值)是
负数 -42有效数字是
Unicode/表情符号完整保留是

引用:test_property_builders.py::TestPropertyBuildersEdgeCases(第 302-341 行)

输入验证责任

构建器有意保持宽松——验证在 API 层进行:

属性构建器接受API 验证
日期任意字符串仅限 ISO 8601
URL任意字符串有效的 URL 格式
复选框真值需要布尔值

最佳实践:在构建属性之前,在应用程序中进行验证。

引用:test_property_builders.py::TestPropertyBuildersInvalidInputs(第 347-376 行)

令牌验证
  • 区分大小写:只有小写的 ntn_ 和 secret_ 有效
  • API 调用前会进行格式检查(避免不必要的请求)
  • 空令牌或仅含空白字符的令牌会立即被拒绝

引用:test_client.py::TestClientEdgeCases(第 196-224 行)

查询与筛选模式

复合筛选器组合
# Empty compound (matches all)
and_filter()  # {"and": []}

# Deep nesting supported
and_filter(
    or_filter(filter_a, filter_b),
    and_filter(filter_c, filter_d)
)

引用:test_filter_builders.py::TestFilterEdgeCases(第 323-360 行)

筛选器限制

筛选器不会排除 NULL 属性——请在 Python 中检查:

if row["properties"]["Rating"]["number"] is not None:
    # Process non-null values

引用:test_integration.py::TestDatabaseQuery::test_query_database_with_filter(第 120-135 行)

分页不变量
条件has_morenext_cursor
还有更多结果True存在且非 None
没有更多结果False可能不存在/为 None

使用 next_cursor 前,始终检查 has_more。

引用:test_integration.py::TestDatabaseQuery::test_query_database_with_pagination(第 137-151 行)

错误处理

from notion_client import APIResponseError, APIErrorCode

try:
    result = client.pages.create(...)
except APIResponseError as e:
    if e.code == APIErrorCode.ObjectNotFound:
        print("Page/database not found or not shared with integration")
    elif e.code == APIErrorCode.Unauthorized:
        print("Token invalid or expired")
    elif e.code == APIErrorCode.RateLimited:
        print(f"Rate limited. Retry after {e.additional_data.get('retry_after')}s")
    else:
        raise

安装

uv pip install notion-client  # v2.6+ required for data_source support

或者使用 PEP 723 内联依赖项(脚本中包含这些依赖项)。


故障排除

问题原因解决方案
未找到对象页面未与集成共享共享页面:... 菜单 → 连接 → 添加集成
未授权令牌无效或已过期在 notion.so/my-integrations 生成新令牌
触发速率限制(429)请求过多使用 api_call_with_retry() 自动处理
查询结果为空筛选条件未匹配任何内容检查筛选语法和属性名称
创建后未找到区块最终一致性延迟写入后、读取前延迟 0.5s
属性类型无效使用了错误的构建器检查数据库架构中的属性类型
令牌格式不被接受前缀错误(区分大小写)令牌必须以 ntn_ 或 secret_(小写)开头
数据源 ID 无法使用API 版本过旧将 notion-client 升级到最新版本

执行后反思

此技能完成后,请在结束前检查:

  1. 命令是否成功? — 如果没有,请修正导致失败的指令或错误表。
  2. 参数或输出是否发生变化? — 如果底层工具的接口有所变动,请更新用法示例和参数表,使其与之匹配。
  3. 是否需要变通处理? — 如果你不得不临时变通(使用不同的标志、执行额外步骤),请更新此 SKILL.md,以便下次调用时无需重复同样的变通处理。

仅在问题真实且可复现时进行更新,不要更新推测性问题。

评论

支持 Markdown