Skip to main content

mass-downloader-for-bluesky

mass-downloader-for-bluesky (mdfb) is a Python cli application that can download large amounts of posts from bluesky from any given account.

Installation

You will need Python to be installed to use this CLI.

You can install via pip by:

pip install mdfb

Manual

Have Poetry installed.

Then clone the project, open a poetry shell and then install all dependencies.

git clone git@github.com:IbrahimHajiAbdi/mass-downloader-for-bluesky.git
cd mdfb
poetry shell
poetry install

Usage

mdfb works by using the public API offered by bluesky to retrieve posts liked, reposted, posted or bookmarked by the desired account.

mdfb will download the information for a post and the accompanying media, video or image(s). If there is no image(s) or video, it will just download the information of the post. The information of the post will be a JSON file and have lots of accompanying data, such as the text in the post, creation time of the post and author details. Currently, the retrieved posts start from the latest post to the oldest.

You will need to be inside a poetry shell to use mdfb if installed manually

Examples

Some example commands would be:

mdfb download --handle bsky.app -l 10 --like --threads 3 --format "{RKEY}_{HANDLE}" ./media/
mdfb download -d did:plc:z72i7hdynmk6r22z27h6tvur --archive --like --threads 3 --format "{DID}_{HANDLE}" ./media/
mdfb download --handle bsky.app --update --like --threads 3 --format "{RKEY}_{HANDLE}" ./media/
mdfb download --restore bsky.app --like --threads 3 --format "{RKEY}_{HANDLE}" ./media/
mdfb download --handle bsky.app --bookmark -l 10 --threads 3 --format "{RKEY}_{HANDLE}" ./media/

Naming Convention

By default, mdfb's naming convention is: "{rkey}_{handle}_{text}". If it is downloading a post with multiple images then the naming will be: "{rkey}_{handle}_{text}_{i}", where "i" represents the order of the images in the post ranging from 1 - 4. In addition, the filenames are limited to 256 bytes and will be truncated down to that size.

However, you can specify the name of the files by using the --format flag and passing a valid format string, e.g. "{RKEY}_{DID}". You can put anything in the format string inbetween the keywords. This is case-sensitive.

For --format, the valid keywords are:

  • RKEY
  • DID
  • HANDLE
  • TEXT
  • DISPLAY_NAME

Download Amount

When specifying the limit, this will be true for all types of post downloaded. For example:

mdfb download --handle bsky.app -l 100 --like --repost --post ./media/

This would download 100 likes, reposts and post, totalling 300 posts downloaded.

Furthermore, you can archive whole accounts. For exmaple:

mdfb download --handle bsky.app --archive --like --repost --threads 3 --format "{DID}_{HANDLE}" ./media/

This would download all likes and reposts.

Bookmarks

mdfb can also download your own bookmarked posts using the --bookmark flag. Since bookmarks are private to your account, this requires an authenticated session, so --bookmark must be used together with --handle (not --did), and you must have logged in with an app password beforehand (see the Feed section below for how login works).

--bookmark cannot currently be combined with --like, --repost or --post in the same command, so it must be run on its own.

Example

mdfb download --handle bsky.app --bookmark --archive --threads 3 ./media/

Note

The --media-types flag is currently not applied when downloading bookmarks; all bookmarked posts will be downloaded regardless of the media types they contain.

Database

When downloading posts, mdfb inserts into the database some post identifiers. This allows for you to download only new posts from an account that you haven't downloaded yet.

However, there are some constraints, if you delete a file, this is not reflected in the database and thus, if you use the --update flag, it will not redownload it. Furthermore, the posts identifiers are only committed to the database once all posts have been downloaded, so if mdfb topples over during downloading, none of the posts downloaded will be reflected into the database.

The database is stored in: (Linux) ~/.local/share/mdfb/, (Windows) C:\\Users\\$USER\\AppData\\Local\\mdfb and (macOS) /Users/$USER/Library/Application Support/mdfb.

Example

mdfb db --delete_user bsky.app

Feed

When using the feed subcommand ,there are a few quirks. One of them being that since it is a generator there is not guaranteed order that the posts will be returned. This has the implication of doing the same command will likely produce different sets of downloaded content. This is up the person who owns the feed and how they decide it is generated.

Furthermore, you need to login using the login subcommand, this requires you to generate a app password for the account you want to authenticate as. The subcommand login is only required when using the feed subcommand. The app password will be valid as long as the password for the account does not change or is revoked by the user. The subcommand feed will use the app password provided until changed.

There can be multiple accounts in the config yaml with their own app password.

You can generate an app password here.

The config yaml is stored in: (Linux) ~/.config/mdfb/, (Windows) C:\\Users\\$USER\\AppData\\Local\\mdfb and (macOS) /Users/$USER/Library/Application Support/mdfb.

Note

IMPORTANT: When using the feed subcommand, None of the posts downloaded will be added to the database. Meaning that the update flag cannot be used and if the same posts pops up on someone elses feed, it will be downloaded.

Example

mdfb feed --handle bsky.app --url 'https://bsky.app/profile/bsky.app/feed/whats-hot' --limit 100 media/ -t 3 

Note

The maximum number of threads is currently 3, that can be changed in the mdfb/utils/constants.py file. Furthermore, there are more constants that can be changed in that file, such as delay between each request and the number of retries before marking that post as a failure and continuing.

Subcommands and arguments

  • download

    • --handle
      • The handle of the target account.
    • --did, -d
      • The DID of the target account.
    • --limit, -l
      • The amount of posts that want to be downloaded.
    • --archive
      • Downloads all posts from the selected post type.
    • --update, -u
      • Downloads all of the latest posts that haven't been downloaded.
    • directory
      • Positional argument, where all the downloaded files are to be located. Required.
    • --threads, -t
      • The amount of threads wanted to download posts more efficiently, maximum number of threads is 3.
    • --format, -f
      • Format string that file's will use for their name. Furthermore the keywords used are case-sensitive and should be all upper case.
    • --like
      • To retrieved liked posts
    • --repost
      • To retrieved reposts
    • --post
      • To retrieved posts
    • --bookmark
      • To retrieve your own bookmarked posts. Requires --handle (bookmarks require an authenticated session) and cannot be combined with --like, --repost or --post.
    • --media-types
      • Only download posts that contain this specified type of media. Valid keywords are: image, video and text.
    • --include, -i
      • Whether to include only json information or media from the post.
    • --restore
      • Downloads all posts stored in the database, can optionally pass a did or handle to only restore posts from that account.
  • db

    • --delete_user
      • Deletes all posts associated with the given user from the database. Have to pass the handle of the user.
  • login

    • This is only a subcommand and is needed to use fetch subcommand, needed to add the app password which can be found here
  • feed

    • --url
    • --handle
      • Handle of the user to login in as. Required.
    • --limit, -l
      • Number of posts to download. Required.
    • --media-types
      • Only download posts that contain this specified type of media. Valid keywords are: image, video and text.
    • --include, -i
      • Whether to include only json information or media from the post.
    • directory
      • Positional argument, where all the downloaded files are to be located. Required.
  • generic commands

    • --resource, -r
      • Logs resource usage for memory and cpu every 5 seconds.

Note

At least one of the flags: --like, --repost, --post or --bookmark are required (when using download).

Both (--did, -d and --handle) and (--archive, --limit, -l and --update) are mutually exclusive, and one of each of them is required as well (when using download).

--bookmark is mutually exclusive with --like, --repost and --post, and requires --handle to be set instead of --did.

The argument --media-types needs to be either before or after any positional arguments. E.g.

mdfb download --handle bsky.app --update --like --threads 3 --media-types image --format "{RKEY}_{HANDLE}" ./media/`

Furthermore, if you want to filter by text and image or media and then use --include by media, this would not include any post filter by text. E.g.

mdfb download --handle bsky.app --update --like --threads 3 --media-types image text -i media ./media/`

This would just download images only.

When using feed, another example of a valid command is:

mdfb feed --handle bsky.app --url 'https://bsky.app/profile/bsky.app/feed/whats-hot' --limit 5 media/ -t 3 --media-types video --include media

This would download the first 5 posts that contain a video and only download the media, not the accompanying metadata json

Metadata

Release files for mdfb 1.7.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mdfb 1.7.2
File Size Uploaded
mdfb-1.7.2.tar.gz 23.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mdfb 1.7.2
File Interpreter ABI Platform
mdfb-1.7.2-py3-none-any.whl Python 3 none any Details

Total release size: 52.5 kB

Release files / mdfb-1.7.2.tar.gz

Download URL mdfb-1.7.2.tar.gz
Size 23.3 kB
Tags Source
SHA-256 checksum
How to use checksums
daccf090c269c91201c84ab9f6532393ab36d2492222f5315694d6f23509ca31
BLAKE2b-256 checksum
How to use checksums
4afa66cd7ad7fc00cbcc06a1fe486563d36c862ada7bf0c3f22fa2ebe91bd558
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Release files / mdfb-1.7.2-py3-none-any.whl

Download URL mdfb-1.7.2-py3-none-any.whl
Size 29.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
233690082a1c3c8063463753b26dc923abf63e78faeb5ecc26f898f2a340f17f
BLAKE2b-256 checksum
How to use checksums
030a46b90c821d4735e6d2f648d2008e439119769ec77ed1de70f5a6d4d18c00
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

1.7.2 This release

2 release files

1.7.1

2 release files

1.7.0

2 release files

1.6.5

2 release files

1.6.4

2 release files

1.6.3

2 release files

1.6.2

2 release files

1.6.1

2 release files

1.6.0

2 release files

1.5.8

2 release files

1.5.7

2 release files

1.5.6

2 release files

1.5.5

2 release files

1.5.4

2 release files

1.5.3

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page