Attach media from Python and the CLI
Attach screenshots and videos to Hub discussions from Python and the CLI
This pull request lets you attach an image, a video or an audio file to a Hub discussion or pull request, straight from Python or the terminal. There's one new method on HfApi, and a new attach option on three discussions commands.
Calling /uploads by hand
Until now, attaching a file from code meant calling the undocumented /uploads endpoint by hand
The Hub web editor uploads a file when you drag it into a comment box. From Python or the command line, you had to call the undocumented uploads endpoint yourself. Going through the client with the usual auth headers also fixes attribution. Uploads now land under your user ID, instead of under no-auth.
HfApi.upload_attachment
upload_attachment(path) returns the file's CDN URL
Here's the new method in hf_api.py. It takes a path and an optional token, and returns a string. It looks up a content type from the file extension, and raises a value error for any format the Hub editor doesn't accept. Then it posts the raw bytes to the uploads endpoint and returns the response body, which is the file's URL.
Supported formats
Ten file extensions, the same list the Hub web editor accepts
.gif .webp
.webm
.wav
Files up to 10 MB, or 50 MB for video
The allowed formats live in one dictionary, mapping each extension to its content type. Five image extensions, three for video and two for audio, matching what the web editor takes. The documented limit is 10 megabytes per file, or 50 megabytes for a video.
The --attach option
Three discussions commands take a repeatable --attach option
On the command line, create, including with the pull request option, comment and edit all take an attach option you can repeat, modeled on the attach flag in GitHub's own CLI. Each value is a file path, optionally followed by a hash sign and the alt text for that image.
How the body is rewritten
A reference in the body points to the upload, and other files go at the end
Here's what attach does to the body. You write an ordinary markdown image pointing at a local file, and pass that file to attach, along with a second one. The local path is swapped for the uploaded URL. The second file had no reference, so it's appended at the end, with the alt text from after the hash.
Markdown per media type
Appended files get the markdown the Hub web editor writes
Appended files get the same markdown the web editor inserts. An image becomes an image embed, and an audio file becomes an audio tag with controls. A video stays a bare URL, because the Hub turns any uploaded video URL into a player, so a video referenced in the body is rewritten the same way.
Every file is checked first
The CLI checks every attached file before it uploads any of them
hf discussions comment now runs with --attach and no --body
Here's the loop that reads the attach values. It checks every one of them first, and stops with an error if a file is missing or its type isn't on the list. Only then does it upload, so a typo in the third file stops the command before the first two are uploaded. And comment now runs with attach alone, without a body.
What review caught
Review caught paths with spaces, which the merged regex handles, and tilde paths, which stay as written
Cursor's Bugbot raised two issues in review. An image reference with spaces, angle brackets or a percent-encoded path didn't match its file. The merged pattern accepts all three, and decodes the path before matching. A quoted path starting with a tilde isn't expanded, and that's still true in the merged code. Write the full path whenever you quote a value to add alt text.
The author's run
One command opened a pull request with both images embedded


Here's the author's own run against a test repository. One create command, with the pull request option and two attach values, opens pull request number one. Both files landed on the Hub's CDN under the author's user ID. These are the two test images as uploaded: the first replaced its reference in the body, and the second was appended.
Limits and where to start
Put the before and after in the pull request itself with --attach
Two limits are deliberate. Only image-style embeds are rewritten, using a regex instead of a markdown parser, and adding attachments to the upload command's create pull request option is left for a later change. The CLI guide's new section, Attach images and videos, has the examples. Next time a fix changes how something looks, put the before and after in the pull request itself, with attach.











