Metadata-Version: 2.5
Name: media-data-kit
Version: 0.0.1
Summary: A unified CLI for querying data from new-media platforms
Requires-Python: >=3.10
Requires-Dist: dotenv>=0.9.9
Requires-Dist: httpx>=0.27
Description-Content-Type: text/markdown

# Media Data Kit

Media Data Kit 是一个统一的新媒体数据查询 CLI。它通过内部适配与编排层汇总不同来源的数据，为微信公众号、抖音等平台提供一致的命令行入口。

这个 CLI 最终将作为“媒体数据分析 Skill”的执行脚本，主要由 LLM 调用。因此命令 Help、参数约束、错误修复建议和 JSON 输出会保持明确、稳定并且可机器解析，同时仍支持人类直接使用。内部数据源不会出现在公共命令、Help 或查询结果中，也不能由调用者选择。

项目目前已经支持通过文章链接识别微信公众号、查询指定公众号的文章列表和一篇或多篇文章互动数据，以及通过作品标识或分享短链查询视频号作品详情、识别 finder username、查询创作者资料和作品列表。项目包含可扩展的命令注册、内部数据源适配、稳定分页游标和严格类型检查配置。

## 环境要求

- Python 3.10+
- [uv](https://docs.astral.sh/uv/)
- 查询公众号文章列表、互动数据或视频号创作者资料、作品详情及列表时，已配置内部数据源凭证

## 快速开始

```bash
uv sync
uv run media-data --help
```

检查本地配置是否完整：

```bash
uv run media-data doctor
```

通过任意可公开访问的公众号文章链接获取所属公众号信息：

```bash
uv run media-data wechat mp-accounts get \
  "https://mp.weixin.qq.com/s/G1KHnuxfCLjQZymYa2QUvw"
```

默认 JSON 结果的 `data` 包含 `biz`、`username` 和 `nickname`。其中 `username` 是通常以 `gh_` 开头的公众号原始 ID。该命令支持 `/s/<token>` 短链接，以及同时包含 `__biz`、`mid` 和 `idx` 的 `/s?...` 长链接；它直接读取微信文章页面，不需要内部数据源凭证，也不会产生接口费用。如果文章触发微信验证、访问受限或页面结构发生变化，命令会失败而不会返回不完整的账号信息。

查询指定公众号的文章列表：

```bash
uv run media-data wechat mp-articles list \
  --account gh_363b924965e9
```

默认最多请求一页并输出 JSON。需要更多结果时，可以显式增加页数和最终输出上限：

```bash
uv run media-data wechat mp-articles list \
  --account gh_363b924965e9 \
  --limit 50 \
  --max-pages 3
```

每一页都是独立的计费请求，CLI 不会自动重试。上游当前可能忽略页面大小，因此 `--limit` 只限制最终输出数量。结果中的 `pagination.next_cursor` 是 Media Data Kit 自己管理的不透明游标；续查时应保持账号不变并原样传回：

```bash
uv run media-data wechat mp-articles list \
  --account gh_363b924965e9 \
  --cursor 'mdk_cursor_v1_...'
```

通过视频号作品分享短链查询作品详情和所属账号：

```bash
uv run media-data wechat channel-videos get \
  'https://weixin.qq.com/sph/VIDEO_TOKEN'
```

`VIDEO_REF` 也可以是纯数字 object ID，或以 `export/` 开头的搜索结果标识。搜索结果同时提供 feed nonce ID 时，可用 `--nonce-id` 传入以提高命中率。结果中的 `data.account_id` 是 `v2_…@finder` 格式的 finder username；64 位作品 ID 始终以字符串输出。每次调用只查询一条作品，不会自动查询该账号的更多作品。

取得 `data.account_id` 后，查询该创作者的作品列表：

```bash
uv run media-data wechat channel-videos list \
  --account 'v2_...@finder'
```

`--account` 必须是 `v2_…@finder` 格式的 finder username；如果只有作品 ID 或分享短链，先执行 `channel-videos get`，再将其 `data.account_id` 传给列表命令。列表默认最多请求一页、最多输出 20 条作品。需要扩大查询范围时，显式设置最终输出上限和页面请求上限：

```bash
uv run media-data wechat channel-videos list \
  --account 'v2_...@finder' \
  --limit 50 \
  --max-pages 3
```

每一页都是独立的计费请求，CLI 不会自动重试。结果包含作品 ID、账号、标题、发布时间、位置和观看、点赞、收藏、分享、评论计数；缺失字段返回 `null`，不会用零值代替。64 位作品 ID 始终以字符串输出。结果不包含媒体地址、下载链接、Token 或解密密钥。

查询视频号创作者主页资料和互动统计：

```bash
uv run media-data wechat channel-accounts get \
  --account 'v2_...@finder'
```

结果包含创作者昵称、签名、头像、IP 属地、粉丝数、作品数、获赞/收藏/转发数、好友关注数、累计直播时长、原创标记、合集数、认证说明和关联公众号。`--account` 使用 `channel-videos get` 返回的 `data.account_id`；如果只有作品分享短链或作品 ID，应先查询作品详情。该接口每次查询一个创作者，可能产生费用，响应可能较慢，建议使用默认的 30 秒超时；超时请求也可能已经产生费用，CLI 不会自动重试。

续查时保持 finder username 不变，并把 `pagination.next_cursor` 原样传回：

```bash
uv run media-data wechat channel-videos list \
  --account 'v2_...@finder' \
  --cursor 'mdk_cursor_v1_...'
```

查询一篇公众号文章的互动数据：

```bash
uv run media-data wechat mp-article-stats get \
  "https://mp.weixin.qq.com/s/TSNQKkRpN1qbKsT7BvzqIw"
```

结果包含 `read_count`、`like_count`、`wow_count`、`share_count`、`favorite_count`、`comment_count` 和 `star_count`。当前文章互动查询支持公众号文章短链接和带 `__biz`、`mid`、`idx` 的长链接；新服务返回星标不可用时，`star_count` 为 `null` 并在 `warnings` 中说明。每个链接单独请求，不会自动重试；请求可能产生费用，建议保留默认的 30 秒超时，超时请求也可能已经产生费用。

也可以在一次调用中传入多个链接，CLI 会并发查询并保持输入顺序：

```bash
uv run media-data wechat mp-article-stats get \
  "https://mp.weixin.qq.com/s/ARTICLE_1" \
  "https://mp.weixin.qq.com/s/ARTICLE_2" \
  --format json
```

单个链接沿用 `data`、`meta`、`warnings` 结构；多个链接返回 `items`、`meta`、`warnings`，每项包含原始 URL 以及成功数据或 `error`。批量结果中的 `meta.success_count` 和 `meta.failure_count` 表示实际完成情况；存在失败项时命令退出码为 4，不会用零值替代失败结果。

支持 `json`、`jsonl` 和 `table` 三种输出：

```bash
uv run media-data wechat mp-articles list \
  --account gh_363b924965e9 \
  --format table
```

默认不输出诊断日志。需要排查命令分发、配置读取、分页请求或响应转换问题时，可以启用日志级别：

```bash
uv run media-data wechat mp-articles list \
  --account gh_363b924965e9 \
  --log-level debug
```

`--log-level` 接受 `debug`、`info`、`warning` 和 `error`。日志只写入标准错误，不会污染标准输出中的 JSON、JSONL 或表格数据。DEBUG 模式会从失败响应中提取 `request_id`、`code`、`message`、`message_zh` 和 `detail` 等诊断字段，但不会记录 API Key、请求头、完整响应或分页游标。

查看分层 Help 时不会读取凭证或访问网络：

```bash
uv run media-data help wechat mp-articles list
uv run media-data help wechat mp-articles list --format json
uv run media-data help wechat mp-article-stats get
uv run media-data help wechat mp-accounts get
uv run media-data help wechat channel-accounts get
uv run media-data help wechat channel-videos list
uv run media-data help wechat channel-videos get
```

也可以通过 Python 模块运行：

```bash
uv run python -m media_data_kit --help
```

## 开发与部署配置

### 本机 CLI 安装

在仓库目录执行可编辑安装：

```bash
uv tool install --editable .
```

也可以从任意目录指定仓库的绝对路径：

```bash
uv tool install --editable /Users/reynoldqin/codes/wxdata/media-data-kit
```

安装后可直接使用 `media-data`，不需要激活项目虚拟环境或使用 `uv run`。可编辑安装会直接反映源码修改；依赖或命令入口变化后，执行 `uv tool install --editable . --reinstall`。仓库需要保留在安装时的位置。

如果 uv 提示命令入口目录不在 PATH 中，执行 `uv tool update-shell`，并让调用 CLI 的终端或 Agent 使用更新后的 PATH。

### 用户级凭证

以下配置只面向项目开发者和运行环境管理员，不属于公共 CLI，也不会出现在面向 Skill 的 Help 或查询结果中：

| 环境变量 | 是否必需 | 用途 |
| --- | --- | --- |
| `TIKHUB_API_KEY` | 按命令 | 查询公众号文章列表、视频号创作者资料、作品详情和列表所需；通过文章链接获取公众号信息时不需要 |
| `DAJIALA_API_KEY` | 按命令 | 查询一篇或多篇文章互动数据所需；通过文章链接获取公众号信息时不需要 |

推荐将本机凭证放在 `~/.config/media-data-kit/.env`。首次配置时，在仓库目录执行以下命令；`cp -n` 保留已有配置，不会覆盖已有凭证：

```bash
mkdir -p ~/.config/media-data-kit
cp -n .env.example ~/.config/media-data-kit/.env
chmod 600 ~/.config/media-data-kit/.env
```

然后在本机编辑该文件，填写自己的密钥，不要将真实凭证放入技能、提交到仓库或粘贴到对话中：

```dotenv
TIKHUB_API_KEY=填写文章及视频号查询密钥
DAJIALA_API_KEY=填写文章互动查询密钥
```

CLI 按以下优先级读取配置：

1. 已有进程环境变量。
2. 从执行目录开始向上查找到的最近 `.env` 文件。
3. 固定路径 `~/.config/media-data-kit/.env`。

项目配置先加载，用户配置后加载，均不覆盖已有环境变量。高优先级的显式空值也不会被低优先级配置替换，最终按未配置处理。例如项目 `.env` 包含 `DAJIALA_API_KEY=` 时，即使用户配置存在有效密钥也不会回退；需要使用用户配置时应删除项目中的这一项，并取消同名空环境变量。

用户配置文件不存在时忽略；所有来源都没有有效凭证时，沿用配置不完整的错误。`doctor`、公众号文章列表、视频号创作者资料、作品详情及列表和互动数据查询共用这套配置逻辑。Help 和通过文章链接识别公众号账号的命令不会加载配置文件。

CLI 进程自行读取用户配置，因此 LLM 的 Bash Tool 可从任意工作目录直接调用 `media-data`，无需依赖 `.zshrc`、交互式 shell 或先运行 `export` / `source`；前提是执行环境能访问同一用户的配置文件和 CLI 入口。查询调用者不能查看或选择内部数据源。

## 查询技能

技能入口为 [skills/media-data/SKILL.md](skills/media-data/SKILL.md)，微信查询流程放在 [references/wechat.md](skills/media-data/references/wechat.md)。当前支持微信公众号、视频号作品详情、创作者资料和创作者作品列表的查询与简要解读。

技能通过已安装的 `media-data` 查询数据，不绑定仓库路径。技能文件和 CLI 分别管理：`uv tool install` 只安装 CLI，不会将技能注册到 Agent；需要按所用 Agent 的技能加载方式单独接入 `skills/media-data` 目录。后续实际接入新平台时，再增加对应参考文档。

## 项目结构

```text
.
├── src/media_data_kit/
│   ├── cli.py              # CLI 进程入口与统一错误边界
│   ├── cli_dispatch.py     # 命令路径、Help 与处理器分发
│   ├── cli_options.py      # 动作参数的通用解析与校验
│   ├── commands.py         # 通用命令类型、公共选项与 Help
│   ├── resources/          # 资源注册、命令定义与处理函数
│   ├── log.py              # 默认关闭的标准错误日志配置
│   ├── models.py           # 稳定领域模型
│   ├── services/           # 查询编排、分页与去重
│   ├── settings.py         # 环境配置读取
│   └── providers/          # 内部数据源适配与路由定义
├── docs/
│   └── cli-design.md       # CLI 公共接口设计指南
├── skills/media-data/
│   ├── SKILL.md            # 数据查询与简要解读的技能入口
│   └── references/wechat.md # 微信查询流程与能力边界
├── AGENTS.md               # 通用协作开发约定
├── CLAUDE.md               # Claude 开发约定入口
├── pyproject.toml          # 项目、依赖和 Pyright 配置
└── uv.lock                 # uv 锁定文件
```

资源模块集中定义命令、校验参数、选择内部数据源并输出结果。简单查询直接使用适配层返回的标准模型；分页、去重或聚合等逻辑放入 Service。适配层负责调用第三方 SDK/API 并转换为稳定的内部模型。不要让内部数据源名称或第三方响应结构泄漏到公共 CLI。

## 设计文档

- [CLI 设计指南](docs/cli-design.md)：定义三段式命令结构、命名规则、命令注册信息、分层 Help、分页、输出和兼容性约定。
- [新增查询命令指南](docs/adding-command.md)：说明在资源模块中新增命令的最小流程，以及模型、接口适配和业务编排的按需扩展方式。

## 开发

安装项目和开发依赖：

```bash
uv sync
```

运行类型检查：

```bash
uv run pyright
```

主要开发约束见 [AGENTS.md](AGENTS.md)。除非任务明确要求，否则不要新增或运行单元测试，也不要通过试跑 CLI 来代替用户验收。

## 许可证

项目暂未指定开源许可证。
