Skip to content

faithleysath/napcat-sdk

Repository files navigation

NapCat Logo

NapCat-SDK for Python

Type-SafeAsync-ReadyFramework-Free

PyPI License Python Version Typing

zread Ask DeepWiki Documentation QQ Group

Stop guessing parameter types. Let the IDE do the work.

告别查文档,享受 100% 类型覆盖 带来的极致补全体验。


✨ Features

  • 🔄 协议自动同步: 基于 OpenAPI 自动构建,与 NapCat 上游定义零时差同步。
  • 🧘 原生无框架: 拒绝框架"黑魔法",纯粹 Python 语法,零心智负担。
  • 💎 极致类型: 100% 类型覆盖,每一个参数都有定义,享受极致 IDE 补全。
  • 完全异步: 基于 websockets + asyncio 原生开发,无惧高并发。
  • 🔌 双模支持: 完美支持正向 (Client) 与反向 (Server) WebSocket 连接。
  • 🌐 远程 RPC: 内置透明网关,让外部应用跨语言调用 NapCat API。
  • 🤖 CLI 集成: 支持 MCP、Skills、CLI,让 AI 助手实时查询 SDK 文档。
  • 📦 依赖克制: 仅包含少量运行时依赖,核心基于 websocketsorjson

📦 Installation

uv add napcat-sdk
# or
pip install napcat-sdk

🚀 Quick Start

第一次接入时,先确保你已经准备好一个可用的 NapCat 实例。

  • NapCat 官网: https://napneko.github.io
  • 本 SDK 通过 OneBot WebSocket 与 NapCat 通信,最常见的是正向 WebSocket 地址 ws://127.0.0.1:3001
  • 如果你给 NapCat 配了 Token,后面的示例里也要带上同一个 Token

最短路径建议按这 3 步走:

  1. 在 NapCat 里开启 OneBot WebSocket,并确认你能拿到 ws://... 地址。
  2. 安装 SDK。
  3. 运行最小示例,先让 /ping -> pong 跑通。

如果你是在仓库里体验,可以直接运行:

export NAPCAT_WS_URL=ws://127.0.0.1:3001
# 如果你配置了鉴权,再取消下一行注释
# export NAPCAT_TOKEN=your-token

uv run python examples/01_forward_client.py

如果你是从 PyPI 安装、手边没有 examples/ 目录,也可以直接复制下面的 Quick Look 到你的脚本里运行。 如果你现在还没配置好 NapCat,建议先看 NapCat 文档完成 WebSocket 配置,再回来运行 SDK 示例。

🧪 示例

可运行的示例脚本都放在 examples/ 目录。建议先看 examples/README.md,再用 uv run python examples/<file>.py 运行对应示例。 第一次接入建议先跑 examples/01_forward_client.py,确认链路畅通后再看 examples/05_pattern_matching.py

📚 指南


🤖 CLI

CLI 是自举的:只要记住入口 uv run napcat-sdk(安装后也可以直接用 napcat-sdk),其余用法都可以从命令本身继续发现。

uv run napcat-sdk --help
uv run napcat-sdk tldr
uv run napcat-sdk doc agent
uv run napcat-sdk doc agent --full --with-code
uv run napcat-sdk mcp doc

它适合做三件事:管理本地实例、查询 SDK/API 文档、给 AI agent 一次性导出大上下文文档包。


📸 Quick Look

import asyncio
import os

from napcat import GroupMessageEvent, NapCatClient, PrivateMessageEvent, Text


def require_env(name: str) -> str:
    value = os.getenv(name)
    if not value:
        raise SystemExit(f"缺少必填环境变量:{name}")
    return value


async def main() -> None:
    client = NapCatClient(
        ws_url=require_env("NAPCAT_WS_URL"),
        token=os.getenv("NAPCAT_TOKEN"),
    )

    async for event in client:
        match event:
            case PrivateMessageEvent(sender=sender, message=[Text(text="/ping")]):
                print(f"[私聊] {sender.nickname}: /ping")
                await event.send_msg("pong")
            case GroupMessageEvent(
                group_id=gid,
                sender=sender,
                message=[Text(text="/ping")],
            ):
                print(f"[群:{gid}] {sender.nickname}: /ping")
                await event.reply("pong", at=True)
            case _:
                continue

if __name__ == "__main__":
    asyncio.run(main())

📖 Usage

NapCatClient 支持直接作为异步迭代器使用,并会在迭代开始/结束时自动管理连接生命周期。

🔌 反向 WebSocket 服务端 (Server Mode)

如果你配置 NapCat 主动连接你的程序,请使用 ReverseWebSocketServer

import asyncio
from napcat import ReverseWebSocketServer, NapCatClient, GroupMessageEvent

async def handler(client: NapCatClient):
    """每个新的 WebSocket 连接都会触发此回调"""
    print(f"Bot Connected! Self ID: {client.self_id}")
    
    # 就像 Client 模式一样处理事件
    async for event in client:
        if isinstance(event, GroupMessageEvent):
            print(f"收到群 {event.group_id} 消息: {event.raw_message}")
            await event.reply("服务端已收到")

async def main():
    # 启动服务器监听 8080 端口
    server = ReverseWebSocketServer(handler, host="0.0.0.0", port=8080, token="my-token")
    await server.run_forever()

if __name__ == "__main__":
    asyncio.run(main())
🖼️ 发送富媒体消息 (图片/At/回复)

SDK 提供了强类型的 MessageSegment,告别手动拼接 CQ 码。

from napcat import (
    NapCatClient,
    Text,
    Image,
    At,
    Message,
)

async def send_rich_media(client: NapCatClient, group_id: str):
    # 构建消息链:@某人 + 文本 + 图片
    message: list[Message] = [
        At(qq="12345678"),
        Text(text=" 来看这张图:"),
        Image(file="https://example.com/image.jpg"),
    ]
    
    # 直接发送列表
    await client.send_group_msg(group_id=group_id, message=message)
🔗 调用 OneBot API (100% 类型提示)

所有 API 方法都直接挂载在 client 上,拥有完整的参数类型检查。

async def managing_bot(client: NapCatClient):
    # 获取登录号信息
    login_info = await client.get_login_info()
    print(f"当前登录: {login_info['nickname']}")

    # 获取群成员列表
    members = await client.get_group_member_list(
        group_id="123456",
        no_cache=True
    )
    for member in members:
        print(f"成员: {member['card'] or member['nickname']}")
    
    # 动态调用(针对未收录的 API)
    await client.call_action("some_new_action", {"param": 1})
⚠️ 错误处理 (异常类型)

SDK 提供了明确的异常类型,方便区分错误来源:

from napcat import NapCatAPIError, NapCatProtocolError, NapCatStateError

try:
    await client.get_login_info()
except NapCatAPIError as exc:
    print("API 失败:", exc)
    print("action=", exc.action, "retcode=", exc.retcode)
except NapCatProtocolError as exc:
    print("上报数据异常:", exc)
except NapCatStateError as exc:
    print("客户端状态错误:", exc)

🛠️ Development

本项目使用 uv 进行包管理。

  1. 克隆项目并同步环境:
git clone --recursive https://github.com/faithleysath/napcat-sdk.git
cd napcat-sdk
uv sync
corepack enable
corepack prepare pnpm@latest --activate
cd NapCatQQ
pnpm install --frozen-lockfile
cd ..
  1. 同步协议定义: SDK 的核心代码由 OpenAPI 规范自动生成,请运行以下命令重新生成代码:
uv run scripts/schema-codegen.py

这会自动更新 src/napcat/types/messages/generated.pysrc/napcat/types/schemas.pysrc/napcat/client_api.py 以及相关的 __init__.py。如果你的环境里没有全局 pnpm,请先在 NapCatQQ 中执行 corepack pnpm --filter napcat-schema run build:openapi,然后改用 uv run scripts/schema-codegen.py --no-openapi-pre-codegen

  1. 如需同步 notice 事件定义:
OPENAI_API_KEY=你的key uv run scripts/notice-codegen.py
uv run scripts/update-init.py

脚本默认已经配置好 Google 的 OpenAI-compatible base_url 和模型;通常只需要传 OPENAI_API_KEY

  1. 运行测试:
# 运行 tests
uv run pytest src/tests -q

📄 License

MIT License © 2025 faithleysath

Star History Chart

About

NapCat SDK for Python - Fully typed and async ready.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages