深入解析 MLflow 仓库 upload-media Skill本地媒体一键上传 GitHub user-attachments 并嵌入 PR 评论【免费下载链接】mlflowThe open source AI engineering platform for agents, LLMs, and ML models. MLflow enables teams of all sizes to debug, evaluate, monitor, and optimize production-quality AI applications while controlling costs and managing access to models and data.项目地址: https://gitcode.com/GitHub_Trending/ml/mlflow导读MLflow 开源仓库在.claude/skills/upload-media/目录下内置了一个名为upload-media的 Claude Code Skill用于把本地截图、录屏等媒体文件一次性上传到 GitHub 的user-attachments附件存储并为每个文件返回可直接嵌入 Markdown 的https://github.com/user-attachments/...链接。本文以该 Skill 的官方定义文档SKILL.md为主体结合仓库内完整的命令实现upload_media.py、底层上传模块uploads.py与测试用例test_upload_media.py、test_uploads.py带你掌握如何调用该命令、输出格式是什么、图片与视频分别如何正确嵌入 PR 正文/Issue/评论以及底层端点、认证、大小限制与错误处理的具体行为。一、Skill 的定位与使用场景根据 SKILL.md 的 frontmatter 定义该 Skill 的用途是Upload one or more local images or videos to GitHub and get back auser-attachmentsURL for each, to embed in a PR body, issue, or comment. Use when asked to attach screenshots or screen recordings.也就是说当 Claude 在代码审查、问题回复等场景中被要求附上截图或录屏时就通过该命令把本地媒体上传到 GitHub拿到链接后嵌入 PR 正文、Issue 或评论。argument-hint指明其参数为要上传的图片或视频的路径。整个 Skills 体系位于 .claude/skills/是一个名为skills的 Python 包通过 pyproject.toml 注册了skills skills.cli:main控制台入口并由 .claude/skills/README.md 给出统一的调用方式uv run --package skills skills command [args]upload-media只是其中一条子命令其余还有embed-media、pr-review、analyze-ci等。它依赖的命令实现位于 .claude/skills/src/skills/commands/upload_media.py。二、命令用法与输出格式1. 基本调用SKILL.md 给出的核心命令只有一行uv run --package skills skills upload-media path...path...是一个或多个媒体文件路径多个文件依次上传当参数为空时SKILL.md 约定使用请求中直接提到的路径when empty, the paths named in the request。从 upload_media.py 的 argparse 定义看除位置参数paths外还支持一个可选参数参数默认值说明paths位置参数必填nargs要上传的媒体文件一个或多个--repomlflow/mlflow附件绑定的目标仓库格式为owner/repo如--repo harupy/mlflow2. 输出格式命令对每个文件输出一行以 Tab 分隔格式固定为path\turl即本地路径 Tab 上传成功后返回的 user-attachments URL。test_upload_media.py 的test_prints_a_url_for_each_file用例验证了这一点两个文件shot.png与clip.mp4各输出一行path\turl。3. 使用示例# 上传单张截图 uv run --package skills skills upload-media /tmp/experiment-ui.png # 输出/tmp/experiment-ui.png https://github.com/user-attachments/assets/2f1c0a3e-0000-4000-8000-000000000001 # 同时上传图片和录屏 uv run --package skills skills upload-media screenshot.png demo.mp4 # 上传到指定仓库 uv run --package skills skills upload-media --repo mlflow/mlflow screenshot.png三、底层执行流程源码级拆解命令run的执行路径upload_media.py分三步取凭证 → 解析仓库 ID → 逐个上传并打印 URL。1. GitHub 凭证解析凭证解析在 .claude/skills/src/skills/github/utils.py 中实现优先级为环境变量GH_TOKEN存在则直接使用否则调用gh auth token获取已登录 CLI 的令牌两者都没有时打印错误并退出Error: GH_TOKEN not found (set env var or install gh CLI)2. 仓库 ID 解析resolve_repository_idupload_media.py通过 GitHub CLI 查询数字仓库 IDgh api repos/{repo} --jq .id默认查询mlflow/mlflow返回类似136202695的数字 ID。如果gh调用失败如仓库不存在返回 404或未安装ghCLI错误信息中的可操作部分stderr会被原样打印到 stderr 后以退出码 1 结束——test_upload_media.py 专门验证了这一行为避免用户只看到 returned non-zero exit status 1 这种无意义信息。3. 逐个上传与失败处理主循环对每个路径做三件事路径不是文件not path.is_file()时打印failed path: not a file到 stderr置失败标记上传成功则打印path\turl到 stdout上传抛UploadFailed时若异常fatal为真说明该故障与当前文件无关、剩余文件也会同样失败则打印提示并break中止整个批次否则只记录失败并继续处理下一个文件。其中 401 场景还会追加提示; check GH_TOKEN or run gh auth loginupload_media.py。任何文件失败都会导致最终sys.exit(1)第 72-73 行。测试 test_upload_media.py 验证了401/403/404 这类凭证级故障会立即停止剩余上传而单个文件自身的失败如不支持的扩展名不会阻塞同批次的其他文件。四、上传端点与文件约束1. 端点与请求构造底层上传实现在 uploads.py 的upload_asset函数第 119-185 行目标是 GitHub 未公开文档化的接口https://uploads.github.com/user-attachments/assets请求为POSTQuery 参数包含三项name文件名、content_typeMIME 类型、repository_id数字仓库 ID请求体为文件原始字节Header 携带Authorization: Bearer token与Accept: application/json超时 60 秒。测试 test_uploads.py 对请求 URL 的编码如content_typeimage%2Fpng、鉴权头和请求体都做了断言。2. 支持的文件类型MIME 白名单MIME_TYPESuploads.py限制了可上传的扩展名扩展名必须与 content_type 一致否则端点返回 422扩展名MIME 类型类别.pngimage/png图片.jpg/.jpegimage/jpeg图片.gifimage/gif图片.webpimage/webp图片.mp4video/mp4视频.movvideo/quicktime视频.webmvideo/webm视频源码注释明确了两点边界音频格式会被端点拒绝即使 GitHub 官方文档声称支持附件音频.svg技术上能上传成功但因为还没有人确认 GitHub 会在 Markdown 中渲染 svg 附件所以被刻意排除在白名单外。扩展名不在表中时直接抛UploadFailed: unsupported extension。3. 大小限制图片上限MAX_IMAGE_BYTES 10 * 1024 * 102410 MB视频上限MAX_VIDEO_BYTES 100 * 1024 * 1024100 MB空文件也会被拒绝the file is empty。max_bytes按扩展名区分视频与图片uploads.py。test_uploads.py 中的test_a_video_between_the_image_and_video_caps_is_not_skipped特意验证介于 10MB 与 100MB 之间的录屏不会因旧的单一 10MB 上限被误杀。五、嵌入规则图片与视频的区别SKILL.md 给出了最关键的使用约定Embed an image asalt. Embed a video as the bare URL in its own paragraph, blank line above and below; anything else renders as a link rather than a player.图片用标准 Markdown 图片语法嵌入altalt为替代文本视频必须把 URL 单独放在一个段落里前后各空一行GitHub 才会渲染成播放器否则只会渲染成普通链接。这一规则在 embed_media.py 中被实现并进一步细化standalone_pattern第 33-35 行用正则^[ \t]*!?\[[^\]]*](url)[ \t]*$识别单独成行的引用对视频引用若其已单独成行则提升为裸 URL若夹在句中被![]()包裹则会渲染为损坏图片因此会去掉!使其降级为链接第 41-47 行。六、错误语义HTTP 状态码与 fatal 判定UploadFailed异常携带statusHTTP 码与fatal属性uploads.py。FATAL_STATUSES {401, 403, 404, 429}——这些故障与当前文件无关重试剩余文件必然同样失败因此会中止整个批次。各状态码的具体解读状态码含义与处理401凭证被拒绝提示检查GH_TOKEN或执行gh auth login403凭证未授权到该仓库未设置正确的权限/范围404二义性要么repository_id无法解析要么端点拒绝该凭证。此时会用describe_token按令牌前缀gho_OAuth、ghp_经典 PAT、github_pat_细粒度 PAT、ghu_App user-to-server、ghs_App/Actions、ghr_refresh指出凭证类型但绝不打印凭证本身429限流若响应头带Retry-After则报告等待秒数否则从响应体解析限流原因主限流与次级限流行为不同其它如500非 fatal可继续下一个文件422会解析响应体中的errors字段剥离面向网页上传器的 HTML 标记后输出具体原因如 Yowza thats a big file并区分类型不合法与文件过大测试 test_uploads.py 与 test_rate_limiting_stops_the_run_and_reports_the_wait 对这些消息格式均有精确断言。七、配套命令 embed-media从上传到替换引用除手动上传外仓库还提供embed-media子命令embed_media.py可看作 upload-media 的自动化升级版用于 PR 审查流程中批量替换引用uv run --package skills skills embed-media --dir 媒体目录 --target 目标文件 --repository-id 数字仓库ID核心行为--dir为存放截图的目录--target是要改写的文件.json格式的 pr-review 载荷或任意 Markdown 文件只上传**目标文本中真正被引用...形式**的文件未被引用的视为草稿跳过上传成功后把 Markdown 中的本地路径正则替换为user-attachmentsURL引用不存在的文件则剥离 Markdown 标记、降级为纯文本避免发布指向本地路径的死链--check模式只做静态检查引用是否可解析、扩展名/大小是否合法、视频是否夹在段落中间等不执行任何上传安全细节collect_files第 59-73 行会跳过符号链接文件——因为is_file()会跟随 symlink恶意放置的secret.png - /proc/self/environ会把本进程的GH_TOKEN作为附件发布出去未获取到令牌时不阻塞改写流程但会明确打印no GitHub token; not uploading。八、限制与注意事项SKILL.md 在最后给出了一条重要提醒属于必须知晓的工程风险No GitHub documentation covers this endpoint, so it can stop working without notice.user-attachments上传接口没有官方文档GitHub 随时可能改变或下线该行为而无任何通知。因此该命令适合开发期/审查期的日常使用不应作为关键生产链路的一部分遇到 404/422 等异常时优先参照上文错误语义自查仓库 ID、凭证类型、文件格式、大小限制.svg与音频文件目前明确不支持详见 uploads.py 中的 MIME 白名单注释。九、延伸阅读Skill 定义文件.claude/skills/upload-media/SKILL.md命令实现.claude/skills/src/skills/commands/upload_media.py底层上传模块.claude/skills/src/skills/github/uploads.py凭证解析.claude/skills/src/skills/github/utils.py引用改写命令.claude/skills/src/skills/commands/embed_media.py测试用例.claude/skills/tests/test_upload_media.py、.claude/skills/tests/test_uploads.pySkills 包说明与入口.claude/skills/README.md、.claude/skills/pyproject.toml【免费下载链接】mlflowThe open source AI engineering platform for agents, LLMs, and ML models. MLflow enables teams of all sizes to debug, evaluate, monitor, and optimize production-quality AI applications while controlling costs and managing access to models and data.项目地址: https://gitcode.com/GitHub_Trending/ml/mlflow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
