A Python tool to download images and videos from Bluesky — from your liked posts or any user's gallery.
Available as a GUI app, a CLI tool, and a portable AppImage for Arch/CachyOS.
- Download all images and/or videos from your liked posts
- Download media from any user's gallery (their public media tab)
- Filter by media type: images, videos, or both
- Configurable page depth (up to 200 pages × 50 posts)
- Download summary on completion — images, videos, total files, total MB
- Configurable post delay — fixed timing or random range (min–max) to avoid rate limiting
- Skips files already on disk — safe to re-run
- Live file progress bar with filename and byte-level size display
- Overall progress bar with file count
- Latest downloaded image shown as a live preview thumbnail
- Error messages highlighted in red in the log
- Saves and restores last-run options between sessions
- Credentials stored in
~/.config/blueskydownload/config.ini(XDG standard) - Downloads saved to
~/Pictures/BlueSkyDownloadby default
Download BlueSkyDownloader.exe from Releases — no Python, yt-dlp, or ffmpeg needed. Everything is bundled.
Download the AppImage from Releases — Python, yt-dlp, and ffmpeg are all bundled. No system packages required.
If running from source instead:
sudo pacman -S python-requests python-tqdm python-pyqt6 python-cryptography yt-dlp ffmpegGenerate an App Password on Bluesky:
Settings → Privacy and Security → App Passwords
On first run, enter your handle and app password in the GUI — they'll be saved automatically.
For CLI-only use, create the config file manually:
mkdir -p ~/.config/blueskydownload
cat > ~/.config/blueskydownload/config.ini << EOF
[credentials]
handle = yourname.bsky.social
app_password = xxxx-xxxx-xxxx-xxxx
EOFpython gui.pySelect your mode, target handle, media type, output folder, and post delay, then click Start Download.
When the download finishes, a summary is shown in the log:
── Summary ── Images: 42 │ Videos: 3 │ Total: 45 files │ 128.4 MB
| Mode | Behaviour |
|---|---|
| Fixed | Waits exactly N seconds between posts |
| Variable | Waits a random duration between Min and Max seconds |
Default is Variable 0.5–2.0 s. Set to 0 s (fixed) to disable all delays.
# Download your liked posts (images + videos)
python apitest.py --mode likes
# Download a specific user's gallery (images only)
python apitest.py --mode gallery --user someartist.bsky.social --media images
# Full options
python apitest.py --helpAvailable flags:
| Flag | Options | Default |
|---|---|---|
--mode |
likes / gallery |
likes |
--user |
any Bluesky handle | your own account |
--media |
images / videos / both |
both |
--pages |
1–200 | 25 (50 posts/page) |
--output |
directory path | ~/Pictures/BlueSkyDownload |
--handle |
your handle | from config |
--password |
your app password | from config |
Download BlueSkyDownloader.exe from Releases and double-click to run. No installation required — yt-dlp and ffmpeg are bundled inside the executable.
First launch may take a few seconds while the app unpacks itself.
Download BlueSkyDownloader-x86_64.AppImage from Releases, then:
chmod +x BlueSkyDownloader-x86_64.AppImage
./BlueSkyDownloader-x86_64.AppImageAppImageUpdate BlueSkyDownloader-x86_64.AppImageRequires AppImageUpdate. The AppImage contains embedded update metadata pointing to the latest GitHub release.
Files are saved as:
{author_handle}_{YYYYMMDD_HHMMSS}_{post_id}_{index}.{ext}
Example: someartist_20240315_143022_3ld5abc_1.jpeg
Videos: someartist_20240315_143022_3ld5abc_v1.mp4
Register the app in your application menu:
cp blueskydownload.desktop ~/.local/share/applications/
# Edit the Exec line to point to the absolute path of gui.pyUses the Bluesky AT Protocol REST API directly — no browser automation or scraping.
| Mode | Endpoint |
|---|---|
| Liked posts | app.bsky.feed.getActorLikes |
| User gallery | app.bsky.feed.getAuthorFeed?filter=posts_with_media |
Videos are downloaded via yt-dlp using the HLS playlist URL exposed by the API.
- Windows exe and Linux AppImage are now fully self-contained — Python, yt-dlp, and ffmpeg are all bundled; no separate installs required
- Switched from yt-dlp subprocess to Python API for cleaner integration
- yt-dlp added as a proper Python dependency
- App password is now encrypted at rest in the config file using Fernet symmetric encryption
- Encryption key stored in
~/.config/blueskydownload/secret.key(user-only, mode 600) - Existing plain-text configs are migrated automatically on first save
- Version number shown in the window title
- Download summary on completion: images count, videos count, total files, total size in MB/KB
- Configurable post delay: Fixed (single value) or Variable (random min–max range)
- Delay setting is saved and restored between sessions
- Windows 11 compatible standalone
.exe(via GitHub Actions / PyInstaller)
- Initial release
- GUI with overall and per-file progress bars, live preview, colored error log
- Liked posts and user gallery download modes
- Image and video support via
yt-dlp - Saved credentials and last-run UI state
- AppImage with embedded auto-update metadata
Personal use. No warranty.