123云盘 (123 Cloud Drive) Skill
Agent Quick Start
脚本路径: scripts/123yunpan.py(相对于本 skill 目录)
首次使用: 先跑 config check 确认凭证有效,再操作文件
输出格式: 加 --json 获取单行 JSON,方便解析
文件 ID: 所有操作都基于 file_id(数字),先 file list 或 file search 获取 ID
⚠️ 操作规则:
- 删除规则: 用户要求删除文件时,必须先向用户展示文件列表(如"删除文件如下:A.txt、B.zip"),确认后再执行删除操作,删除后提醒"如需找回,请前往回收站恢复"
- 下载规则: 下载完成后告知用户保存位置,如"文件已保存到:/path/to/file.pdf"
- 分享规则: 分享少于 20 个文件时直接给出链接;超过 20 个时导出 Excel 文件并发送给用户
- 搜索规则: 用户未给出具体云盘位置只给了文件名,搜索到多个匹配结果时,列出文件让用户选择,不要自行决定
- 批量规则: 批量操作前先告知用户数量和预计耗时,如"共 150 个文件,预计需要 2 分钟"
- 上传规则: 用户未指定目标文件夹时,先列出根目录让用户选择上传位置
- 错误规则: 遇到错误时给出解决方案,不要只报错。如"文件不存在"→提示检查 file_id 是否正确;"分享失败"→提示检查文件是否违规
# 1. 验证配置
python3 scripts/123yunpan.py config check --json
# 2. 查看根目录
python3 scripts/123yunpan.py --json file list --parent-id 0
# 3. 搜索文件
python3 scripts/123yunpan.py --json file search "关键词" --parent-id 0
# 4. 查看目录树(快速了解结构)
python3 scripts/123yunpan.py file tree --parent-id 0 --max-depth 2
Common Workflows
🔍 "帮我找某个文件"
1. file search "关键词" --parent-id 0 --json → 获取 file_id
2. file detail --file-id {id} --json → 确认文件信息
3. file download --file-id {id} -o ./ → 下载
4. 告知用户:文件已保存到:./xxx.pdf
🔗 "把这个文件夹分享出去"
1. file tree --parent-id {folder_id} --max-depth 2 → 确认内容
2. 少于 20 个:share create 逐个创建,直接给出链接
3. 超过 20 个:share create-batch --parent-id {folder_id} --expire 0 -o links.xlsx → 导出 Excel
⬆️ "上传文件到云盘"
1. 用户未指定位置 → file list --parent-id 0 --json → 列出根目录让用户选
2. upload --file /path/to/file --parent-id {folder_id}
3. 告知用户:文件已上传到:{folder_id}/xxx.pdf
⬇️ "批量下载这些文件"
1. file search "关键词" --parent-id {root} --json → 获取 file_id 列表
2. file download-batch --file-ids "id1,id2,id3" -o ./downloads/ → 批量下载
📊 "看看空间占用情况"
1. file storage-report --parent-id 0 --top 10 → 按文件夹分析+大文件排行
🗑️ "删除文件"
1. file list --parent-id {folder_id} --search "关键词" --json → 找到 file_id
2. 向用户展示将删除的文件列表,格式:删除文件如下:XXX.txt、XXX.zip
3. file trash --file-ids "{id1},{id2}" → 移入回收站
4. 提醒用户:如需找回,请前往回收站恢复
⚠️ 删除操作必须先向用户展示文件列表,确认后再执行!
🔄 "把配置迁移到另一台机器"
# 机器 A:
config export -o config.json
# 机器 B:
config import --file config.json
config check → 验证导入成功
Overview
This skill provides a complete CLI wrapper for the 123 Cloud Drive Open Platform API. It covers 70+ API endpoints across authentication, file management, upload, download, sharing, offline download, direct links, image hosting, and video transcoding.
Prerequisites
1. Purchase Developer Access Pack
Visit https://www.123pan.com/member and purchase a developer access pack. You will receive client_id and client_secret via in-app message.
2. Configuration
The skill requires three credentials stored in environment variables:
# Required for API authentication
export TWOPAN_CLIENT_ID="your_client_id_here"
export TWOPAN_CLIENT_SECRET="your_client_secret_here"
export TWOPAN_ACCESS_TOKEN="your_access_token_here"
If these are not set when the skill is first used, the CLI will output a clear reminder:
⚠️ 123云盘技能需要配置以下环境变量才能使用:
export TWOPAN_CLIENT_ID="your_client_id"
export TWOPAN_CLIENT_SECRET="your_client_secret"
export TWOPAN_ACCESS_TOKEN="your_access_token"
获取方式:
1. 访问 https://www.123pan.com/member 购买开发者权益包
2. 通过 client_id + client_secret 调用 /api/v1/access_token 获取 access_token
3. 将三个值设置为环境变量
或运行: 123yunpan.py setup
3. Interactive Setup (Recommended)
Run 123yunpan.py setup without arguments for interactive credential entry:
$ python3 scripts/123yunpan.py setup
⚠️ 未检测到 client_id
获取方式:访问 https://www.123pan.com/member 购买开发者权益包
请输入 client_id: █
⚠️ 未检测到 client_secret
请输入 client_secret: █
正在获取 access_token...
✅ 配置已保存!
If config already exists (from a previous setup or env vars), it skips prompting and uses the existing values. Non-interactive mode also works: setup --client-id ID --client-secret SECRET.
CLI Usage
# === Global Options ===
# Add --no-color to disable colored output, --json to output raw JSON
# Setup / get token
python3 scripts/123yunpan.py setup --client-id YOUR_ID --client-secret YOUR_SECRET
# Check config status
python3 scripts/123yunpan.py config
python3 scripts/123yunpan.py config check # 验证 token 有效性
python3 scripts/123yunpan.py config export --output config.json
python3 scripts/123yunpan.py config import --file config.json
# === File Management ===
python3 scripts/123yunpan.py file list --parent-id 0 --limit 100
python3 scripts/123yunpan.py file list --parent-id 0 --trashed # 只看回收站
python3 scripts/123yunpan.py file list --parent-id 0 --show-trashed # 含回收站
python3 scripts/123yunpan.py file search "Photoshop" --parent-id 27172609 --max-depth 3
python3 scripts/123yunpan.py file tree --parent-id 0 --max-depth 3
python3 scripts/123yunpan.py file storage-report --parent-id 0 --top 10
python3 scripts/123yunpan.py file detail --file-id 12345
python3 scripts/123yunpan.py file details-multi --file-ids "1,2,3"
python3 scripts/123yunpan.py file list --search "keyword"
python3 scripts/123yunpan.py file mkdir --name "New Folder" --parent-id 0
python3 scripts/123yunpan.py file rename --file-id 12345 --new-name "renamed.txt"
python3 scripts/123yunpan.py file rename-batch --file-ids "1,2,3" --new-names "a.txt,b.txt,c.txt"
python3 scripts/123yunpan.py file move --file-ids "1,2,3" --target-parent-id 0
python3 scripts/123yunpan.py file copy --file-id 12345 --target-parent-id 0
python3 scripts/123yunpan.py file copy-batch --file-ids "1,2,3" --target-parent-id 0
python3 scripts/123yunpan.py file copy-progress --task-id abc123
python3 scripts/123yunpan.py file trash --file-ids "12345"
python3 scripts/123yunpan.py file recover --file-id 12345
python3 scripts/123yunpan.py file recover-by-path --file-id 12345 --target-parent-id 0 --filename "restored.txt"
python3 scripts/123yunpan.py file download --file-id 12345 --output /path/to/save
python3 scripts/123yunpan.py file download-batch --file-ids "1,2,3" --output-dir /path/to/save
# === Upload (V2 Recommended) ===
python3 scripts/123yunpan.py upload --file /path/to/file.txt --parent-id 0
# === Share Management ===
python3 scripts/123yunpan.py share create --name "My Share" --file-ids "1,2,3" --expire 7
python3 scripts/123yunpan.py share create-batch --parent-id 27172609 --expire 0 -o result.xlsx
python3 scripts/123yunpan.py share list --limit 10
python3 scripts/123yunpan.py share list --all-pages
python3 scripts/123yunpan.py share stats --top 10
python3 scripts/123yunpan.py share delete-batch --share-ids 1 2 3
python3 scripts/123yunpan.py share delete-batch --all -y # 删除全部(跳过确认)
python3 scripts/123yunpan.py share update --share-ids "1,2" --traffic-switch 2
python3 scripts/123yunpan.py share export --output shares.xlsx
python3 scripts/123yunpan.py share export --output shares.json --format json
python3 scripts/123yunpan.py share pay-create --name "Paid Share" --file-ids "1,2" --amount 10
python3 scripts/123yunpan.py share pay-list --limit 10
python3 scripts/123yunpan.py share pay-update --share-ids "1" --amount 20
# === Offline Download ===
python3 scripts/123yunpan.py offline create --url "https://example.com/file.zip" --parent-id 0
python3 scripts/123yunpan.py offline progress --task-id abc123
python3 scripts/123yunpan.py offline list
# === User Info ===
python3 scripts/123yunpan.py user-info
# === Direct Link ===
python3 scripts/123yunpan.py direct-link enable --file-id 12345
python3 scripts/123yunpan.py direct-link disable --file-id 12345
python3 scripts/123yunpan.py direct-link url --file-id 12345
python3 scripts/123yunpan.py direct-link short-url --file-id 12345 # 短直链(更隐私)
python3 scripts/123yunpan.py direct-link cache-refresh --file-id 12345
python3 scripts/123yunpan.py direct-link ip-list
python3 scripts/123yunpan.py direct-link ip-switch --switch 1
python3 scripts/123yunpan.py direct-link ip-update --ips "1.1.1.1,2.2.2.2"
python3 scripts/123yunpan.py direct-link offline-logs
python3 scripts/123yunpan.py direct-link traffic-logs
# === Image Hosting (OSS) ===
python3 scripts/123yunpan.py oss list --parent-id 0 --limit 100
python3 scripts/123yunpan.py oss detail --file-id 12345
python3 scripts/123yunpan.py oss delete --file-id 12345
python3 scripts/123yunpan.py oss move --file-id 12345 --target-parent-id 0
python3 scripts/123yunpan.py oss copy --file-ids "1,2,3" --target-parent-id 0
python3 scripts/123yunpan.py oss copy-process --task-id abc123
python3 scripts/123yunpan.py oss copy-fail --task-id abc123
# === Video Transcode ===
python3 scripts/123yunpan.py transcode list --parent-id 0 --limit 100
python3 scripts/123yunpan.py transcode folder --parent-id 0
python3 scripts/123yunpan.py transcode resolutions --file-id 12345
python3 scripts/123yunpan.py transcode transcode --file-id 12345 --resolution 1080p
python3 scripts/123yunpan.py transcode record --file-id 12345
python3 scripts/123yunpan.py transcode result --file-id 12345
python3 scripts/123yunpan.py transcode delete --file-id 12345
python3 scripts/123yunpan.py transcode download --file-id 12345 --output /path/
python3 scripts/123yunpan.py transcode download-m3u8 --file-id 12345 --output /path/
python3 scripts/123yunpan.py transcode download-all --file-id 12345 --output /path/
python3 scripts/123yunpan.py transcode upload-cloud --file-id 12345 --parent-id 0
# === Safebox ===
python3 scripts/123yunpan.py safebox unlock --password "your_password"
# === Cache Management ===
python3 scripts/123yunpan.py cache list # 列出所有缓存文件
python3 scripts/123yunpan.py cache clear # 清除全部缓存
python3 scripts/123yunpan.py cache clear --root-id 12345 # 清除指定文件夹的缓存
python3 scripts/123yunpan.py cache info # 显示缓存目录信息
JSON Output Fields (--json)
加 --json 后所有命令输出单行 JSON,以下是主要命令的字段说明:
file list --json
{"code":0, "data":{"fileList":[
{"fileId":12345, "filename":"报告.pdf", "size":1048576, "type":0,
"parentFileID":0, "createAt":"2026-01-01T00:00:00Z", "trashed":0}
], "lastFileId":12345}}
type: 0=文件, 1=文件夹trashed: 0=正常, 1=已删除size: 字节数
file detail --json
{"fileId":12345, "filename":"报告.pdf", "size":1048576,
"md5":"abc123...", "type":0, "parentFileID":0,
"downloadUrl":"https://...", "createAt":"2026-01-01T00:00:00Z"}
user-info --json
{"uid":1812749510, "nickname":"暖心向阳335",
"spaceUsed":9223372036854775807, "spacePermanent":9223372036854775807,
"vip":1}
spaceUsed/spacePermanent: 字节数,用human_size()转换
share create --json
{"code":0, "data":{"shareID":5193007, "shareKey":"JyAKVv-o6bI"},
"_shareUrl":"https://www.123pan.com/s/JyAKVv-o6bI"}
_shareUrl是 CLI 自动拼接的,不是 API 返回的
share list --json
{"code":0, "data":{"shareList":[
{"shareId":5193007, "shareName":"分享",
"shareKey":"JyAKVv-o6bI", "shareExpire":7,
"previewCount":10, "downloadCount":5, "saveCount":2,
"createAt":"2026-01-01T00:00:00Z"}
], "lastShareId":5193007}}
upload --json
{"code":0, "data":{"fileID":12345, "completed":true, "reuse":false}}
reuse: true=秒传成功(文件已存在)
通用规则
- 所有 API 返回格式:
{"code":0, "message":"ok", "data":{...}} code=0表示成功,非 0 为错误file list和share list使用lastFileId/lastShareId做游标分页- 错误时返回:
{"code":错误码, "message":"错误描述"}
API Reference Summary
| Category | Endpoint | Method |
|----------|----------|--------|
| Cache | cache list | CLI |
| Cache | cache clear | CLI |
| Cache | cache info | CLI |
| Auth | /api/v1/access_token | POST |
| Auth (OAuth2) | /api/v1/oauth2/access_token | POST |
| File List (v2) | /api/v2/file/list | GET |
| File List (v1) | /api/v1/file/list | GET |
| File Detail | /api/v1/file/detail | GET |
| File Details (multi) | /api/v1/file/infos | POST |
| Create Dir | /upload/v1/file/mkdir | POST |
| Rename (single) | /api/v1/file/name | PUT |
| Rename (batch) | /api/v1/file/rename | POST |
| Move | /api/v1/file/move | POST |
| Copy (single) | /api/v1/file/copy | POST |
| Copy (batch) | /api/v1/file/async/copy | POST |
| Copy Progress | /api/v1/file/async/copy/process | GET |
| Trash | /api/v1/file/trash | POST |
| Recover | /api/v1/file/recover | POST |
| Recover (by path) | /api/v1/file/recover/by_path | POST |
| Download Info | /api/v1/file/download_info | GET |
| Upload V1 | /upload/v1/file/create | POST |
| Upload V2 | /upload/v2/file/create | POST |
| Upload Slice | /upload/v2/file/slice | POST |
| Upload Complete | /upload/v2/file/upload_complete | POST |
| Upload Domain | /upload/v2/file/domain | GET |
| SHA1 Reuse | /upload/v2/file/sha1_reuse | POST |
| Single Upload | /upload/v2/file/single/create | POST |
| Share Create | /api/v1/share/create | POST |
| Share List | /api/v1/share/list | GET |
| Share Delete | /api/v1/share/delete | POST |
| Share Update | /api/v1/share/list/info | PUT |
| Pay Share Create | /api/v1/share/content-payment/create | POST |
| Pay Share List | /api/v1/share/payment/list | GET |
| Pay Share Update | /api/v1/share/list/payment/info | PUT |
| Offline Download | /api/v1/offline/download | POST |
| Offline Progress | /api/v1/offline/download/process | GET |
| User Info | /api/v1/user/info | GET |
| Direct Link Enable | /api/v1/direct-link/enable | POST |
| Direct Link Disable | /api/v1/direct-link/disable | POST |
| Direct Link URL | /api/v1/direct-link/url | GET |
| Direct Link Cache | /api/v1/direct-link/cache/refresh | POST |
| IP Blacklist Switch | /api/v1/developer/config/forbide-ip/switch | POST |
| IP Blacklist Update | /api/v1/developer/config/forbide-ip/update | POST |
| IP Blacklist List | /api/v1/developer/config/forbide-ip/list | GET |
| Direct Link Logs | /api/v1/direct-link/offline/logs | GET |
| Direct Link Traffic | /api/v1/direct-link/log | GET |
| Image Upload Flow | /upload/v1/oss/file/mkdir | POST |
| Image Create Dir | /upload/v1/oss/file/mkdir | POST |
| Image Create | /upload/v1/oss/file/create | POST |
| Image Upload URL | /upload/v1/oss/file/get_upload_url | POST |
| Image Upload Done | /upload/v1/oss/file/upload_complete | POST |
| Image Upload Result | /upload/v1/oss/file/upload_async_result | POST |
| Image Copy | /api/v1/oss/source/copy | POST |
| Image Copy Process | /api/v1/oss/source/copy/process | GET |
| Image Copy Fail | /api/v1/oss/source/copy/fail | GET |
| Image Move | /api/v1/oss/file/move | POST |
| Image Delete | /api/v1/oss/file/delete | POST |
| Image Detail | /api/v1/oss/file/detail | GET |
| Image List | /api/v1/oss/file/list | POST |
| Image Offline | /api/v1/oss/offline/download | POST |
| Image Offline Process | /api/v1/oss/offline/download/process | GET |
| Video Upload Cloud | /api/v1/transcode/upload/from_cloud_disk | POST |
| Video Folder Info | /api/v1/transcode/folder/info | POST |
| Video Resolutions | /api/v1/transcode/video/resolutions | POST |
| Video Transcode List | /api/v1/video/transcode/list | GET |
| Video Transcode | /api/v1/transcode/video | POST |
| Video Record | /api/v1/transcode/video/record | POST |
| Video Result | /api/v1/transcode/video/result | POST |
| Video Delete | /api/v1/transcode/delete | POST |
| Video Download | /api/v1/transcode/file/download | POST |
| Video M3U8 Download | /api/v1/transcode/m3u8_ts/download | POST |
| Video All Download | /api/v1/transcode/file/download/all | POST |
| Safebox Unlock | /api/v1/safebox/id | GET |
Short Direct Link (短直链)
除了分享链接和完整直链外,还可以生成短直链 — 格式为 https://{user_id}.v.123pan.cn/{user_id}/{file_id},不暴露文件名,更隐私友好。
生成短直链
# CLI 命令
python3 scripts/123yunpan.py direct-link short-url --file-id 12345
# 输出示例
{
"short_url": "https://1812749510.v.123pan.cn/1812749510/12345",
"user_id": 1812749510,
"file_id": 12345
}
手动拼接(Python)
import base64, json
def get_user_id_from_token(token):
"""从 JWT token 解析 user_id,无需额外 API 调用"""
parts = token.split(".")
payload = parts[1] + "=" * (4 - len(parts[1]) % 4)
return json.loads(base64.b64decode(payload)).get("id", 0)
user_id = get_user_id_from_token(access_token)
short_url = f"https://{user_id}.v.123pan.cn/{user_id}/{file_id}"
三种链接格式对比
| 格式 | 示例 | 特点 |
|------|------|------|
| 分享链接 | https://www.123pan.com/s/JyAKVv-o6bI | 需要登录/跳转,最常用 |
| 完整直链 | https://xxx.v.123pan.cn/xxx/xxx/filename.zip | 直接下载,暴露文件名 |
| 短直链 | https://1812749510.v.123pan.cn/1812749510/12345 | 直接下载,不暴露文件名 |
⚠️ 短直链需要文件已在开启了直链功能的文件夹中,否则无法使用。
Share URL Construction
The share create API returns shareID and shareKey — it does NOT return a full shareUrl. You must construct the URL yourself. The CLI supports two formats via --url-format:
| Format | CLI 参数 | URL 模式 | 示例 |
|--------|----------|----------|------|
| short (默认) | --url-format short | https://www.123pan.com/s/{shareKey} | https://www.123pan.com/s/JyAKVv-o6bI |
| uid | --url-format uid | https://{user_id}.share.123pan.cn/123pan/{shareKey} | https://666666666.share.123pan.cn/123pan/JyAKVv-o6bI |
uid 格式自动从 JWT token 解析 user_id,无需额外 API 调用。解析失败时自动回退到 short。
# 默认 short 格式
python3 scripts/123yunpan.py share create --name "分享" --file-ids 123,456 --expire 7
# UID 格式
python3 scripts/123yunpan.py share create --name "分享" --file-ids 123,456 --url-format uid
# 批量分享也支持
python3 scripts/123yunpan.py share create-batch --parent-id 27172609 --url-format uid -o result.xlsx
Example response from POST /api/v1/share/create:
{
"code": 0,
"message": "ok",
"data": {
"shareID": 5193007,
"shareKey": "JyAKVv-o6bI"
}
}
Direct Link & Short Direct Link
The skill supports two types of direct links:
Full direct link (contains filename in URL):
https://{user_id}.v.123pan.cn/{user_id}/{file_id}/{filename}
Short direct link (privacy-friendlier, no filename):
https://{user_id}.v.123pan.cn/{user_id}/{file_id}
To generate short direct links, parse user_id from the JWT access token (no extra API call needed):
import base64, json
parts = token.split(".")
payload = parts[1] + "=" * (4 - len(parts[1]) % 4)
user_id = json.loads(base64.b64decode(payload))["id"]
short_link = f"https://{user_id}.v.123pan.cn/{user_id}/{file_id}"
See
references/competitor-upload-patterns.mdfor full upload workflow, SHA1 reuse, and WebDAV patterns.
Recursive File Listing
The file list API only returns direct children of a folder. To find all files in a multi-level directory tree, you must traverse recursively. See references/bulk-operations.md for BFS and layered traversal patterns.
Quick pattern — find all files under a root folder:
from collections import deque
def find_all_files(root_id, list_folder_fn):
queue = deque([(root_id, [])])
all_files = []
while queue:
pid, path = queue.popleft()
for item in list_folder_fn(pid):
if item.get("trashed"):
continue
if item["type"] == 1: # folder
queue.append((item["fileId"], path + [item["filename"]]))
else: # file
all_files.append({
"fileId": item["fileId"],
"filename": item["filename"],
"path": "/".join(path),
})
return all_files
⚠️ Deep traversal can involve hundreds of API calls. For 100+ folders, expect 5-10 minutes. Use checkpoint/resume (save progress to JSON every N items) to handle interruptions.
Common Pitfalls
-
API response format (CRITICAL): The 123yunpan API returns
{code: 0, message: "ok", data: {...}}— NOT{result: {...}}. Always parse thedatafield. Useclient._extract(resp)— the CLI script handles both formats. -
Token expiry & auto-refresh: access_token expires after a period. The CLI automatically refreshes on 401 responses using client_id/secret. For manual refresh, run
setupor call/api/v1/access_token. -
File name restrictions: Filenames must be <256 chars and cannot contain:
\\\\\\\"/:*?|>< -
Upload size: Single file upload limit is 10GB via the API.
-
fileIDListmust be a string (CRITICAL): When calling the share create API directly,fileIDListmust be a comma-separated string ("123,456"), NOT a JSON array ([123, 456]). Passing an array causes the API to return "文件列表不能为空". The CLI handles this internally via",".join(str(x) for x in file_ids). Max 100 file IDs per share.shareExpiremust be 0, 1, 7, or 30. -
Share response has no
shareUrl: The share create response only returnsshareID+shareKey. You must construct the URL. Use--url-format short(default,https://www.123pan.com/s/{shareKey}) or--url-format uid(https://{user_id}.share.123pan.cn/123pan/{shareKey}). See "Share URL Construction" section above. -
Pagination: Use
lastFileId/lastShareIdfor cursor-based pagination. When value is-1, you've reached the last page. -
Upload API domain routing (CRITICAL): Upload endpoints are split across two domains:
- Main API domain (
https://open-api.123pan.com):/upload/v2/file/create(chunked create),/upload/v1/file/create(v1 create) - Upload domain (
https://openapi-upload.123242.com):/upload/v2/file/single/create(single upload),/upload/v2/file/slice(chunked slice),/upload/v2/file/upload_complete(chunked complete) - Upload domain is obtained via GET
/upload/v2/file/domain— it returns a list["https://..."], not an object withhostfield.
- Main API domain (
-
Single upload requires multipart/form-data (CRITICAL): The
/upload/v2/file/single/createendpoint does NOT accept JSON body. It requiresContent-Type: multipart/form-datawith fieldsparentFileID,filename,etag,sizeas text parts and the file content as a file part. Sending JSON results in a 500 server crash. -
duplicateparameter (CRITICAL): Theduplicatefield in upload create causes "duplicate参数错误" when set to0(skip). Do not sendduplicateat all (defaults to overwrite), or use2(overwrite) or1(rename). The value0is rejected by the API. The CLI now defaults to not sending this parameter (overwrite behavior). -
Trash behavior: The v2 file list includes trashed files — filter by
trashedfield yourself.trashed: 1means the file is in trash. -
Batch operations rate limit: When creating shares or making many API calls (e.g., 2500+ files), limit to ~2 requests/second (0.5s sleep). Use checkpoint/resume: save progress to JSON every 10 items, skip already-processed items on restart.
-
Deep directory traversal: Folders can be 4-5 levels deep. Use BFS with a queue for unknown structures, or layered traversal when structure is known. Each level requires a separate API call — 1400+ folders may take 10+ minutes. Use BFS caching (
~/.123yunpan_cache/) to avoid repeated traversals — 57s → 0.15s on cache hit. CLI commandsfile searchandshare create-batchauto-use cache; add--no-cacheto force refresh. -
Common error responses:
| code | message | Meaning |
|--------|-----------|---------|
| 0 | ok | Success |
| 1 | 文件列表不能为空 | fileIDList is empty or wrong format (must be comma-separated string) |
| 1 | duplicate参数错误 | duplicate field value is invalid (don't send 0; use absent/1/2) |
| 1 | 分片MD5不能为空 | Slice MD5 missing — check field name matches API expectation |
| 1 | 该目录下文件名重复无法创建 | Filename already exists in target directory (use --duplicate 2 to overwrite) |
| 2 | 分享ID非法 | File ID doesn't exist or has no share permission |
| 10 | 文件名已存在 | Target folder already has a file with that name |
| 16 | 文件不存在 | File ID not found |
| 20 | 分享文件涉嫌违规,禁止分享 | File content flagged by platform policy (e.g., .alist files) |
- Packaging & versioning: Version must be updated in two places: (1)
scripts/123yunpan.pyline 4 comment (vX.Y.Z), (2)SKILL.mdfrontmatter (version: X.Y.Z). Nozip/unzipCLI — use Python'szipfilemodule. Package includes SKILL.md + README.md + scripts/ + references/ (no LICENSE per user preference). Exclude__pycache__/. Extraction for patching:python3 -c "import zipfile; zipfile.ZipFile('pkg.zip').extractall('_tmp')". Repackaging:cd _tmp && python3 -c "import zipfile,os; [zipfile.ZipFile('out.zip','w',zipfile.ZIP_DEFLATED).write(f, os.path.relpath(f,'.')) for r,d,fs in os.walk('.') for f in fs if '__pycache__' not in r]".
⚠️ Remember to also update the version in
scripts/123yunpan.pyline 4 when bumping the version in SKILL.md frontmatter.
-
Argparse parameter names must match SKILL.md exactly: Before adding/changing argparse arguments, cross-check every
--flagin SKILL.md CLI examples. Mismatches (e.g.--namein code vs--new-namein docs) silently break user workflows. Useparse_int_list()(nottype=int, nargs="+") for all file-ID arguments to support both comma-separated (1,2,3) and space-separated (1 2 3) input. -
_refresh_tokenuses imported names, not module paths: TheApiClientmethods useRequestandurlopen(fromfrom urllib.request import ...), NOTurllib.request.Request. Using the module path will crash withNameErrorsinceurllibis not imported as a module. -
BFS traversal optional params:
bfs_list_files()acceptsmax_depth,use_cache,max_age— always forward these from callers (e.g.cmd_file_search). Unused parameters silently cause unbounded traversal. -
Global options placement:
--no-colorand--jsonmust appear before the subcommand (e.g.,--json file list --parent-id 0), not after. Placing them after the subcommand will cause argparse to ignore them. -
file treevs recursive traversal:file treeis a display-only convenience command that shows directory structure. For bulk operations (downloading, moving, sharing), use recursive BFS traversal orfile listwith pagination —file treedoes not return file IDs suitable for batch operations. -
share exportformat: Without--format, the default output is Excel (.xlsx). Use--format jsonexplicitly for JSON output. Excel output requiresopenpyxl(pip install openpyxl). -
config importsafety: Importing config will overwrite your current~/.123yunpan_config.json. Back up your existing config before importing. The CLI warns before overwriting if the file exists.
See references/bulk-operations.md for batch operation code patterns, BFS traversal, and background execution tips.
Verification Checklist
- [ ] Environment variables
TWOPAN_CLIENT_ID,TWOPAN_CLIENT_SECRET,TWOPAN_ACCESS_TOKENare set - [ ] Run
123yunpan.py setupto validate credentials and fetch token - [ ] Test with
123yunpan.py file list --parent-id 0 --limit 5 - [ ] Confirm token refresh works by checking
~/.123yunpan_config.json
Changelog
v1.2.0 (2026-05-09)
- 新增:
--no-color和--json全局选项,支持禁用彩色输出和 JSON 格式输出 - 新增:
file tree命令 — 目录树展示,支持--parent-id和--max-depth参数 - 新增:
file download-batch命令 — 批量下载文件,支持--file-ids和--output-dir参数 - 新增:
file storage-report命令 — 存储分析,支持--parent-id和--top参数 - 新增:
offline list命令 — 列出离线下载任务(占位,待完善) - 新增:
share export命令 — 导出分享记录到 Excel/JSON,支持--output和--format参数 - 新增:
config export命令 — 导出配置到 JSON,支持--output参数 - 新增:
config import命令 — 从 JSON 导入配置,支持--file参数
v1.1.5 (2026-05-09)
- 修复:
upload命令的--duplicate参数默认值从0(跳过)改为不发送(默认覆盖),避免API报错 - 修复:
_refresh_token方法使用了未导入的urllib.request模块,导致自动刷新Token时崩溃 - 修复:
file search --max-depth参数未实际生效,BFS遍历无深度限制 - 修复: 代码参数名与文档不一致(
--new-name、--target-parent-id、--ips),统一到文档标准 - 优化: 所有
--file-ids/--share-ids参数同时支持逗号分隔和空格分隔格式(如1,2,3或1 2 3) - 新增:
cache list命令 - 列出所有BFS缓存文件 - 新增:
cache clear命令 - 清除缓存(支持指定文件夹或全部清除) - 新增:
cache info命令 - 显示缓存目录信息 - 优化: 批量操作进度显示增加ETA(预计剩余时间)估算
- 优化: 清理重复的import语句
v1.1.4
- 初始版本,支持70+ API端点
扫码加入微信群