14.7.3. Demo: Display Real Bluesky Comments and Replies#

Choose Social Media Platform: Reddit | Discord | Bluesky | No Coding

Now lets do the same thing we did on the last page (using recursion to display comments and replies), but do it on Bluesky! (Either for real or faked with the fake_atproto library).

Normal Bluesky Setup#

We’ll start by doing our normal steps including these helper functions:

load atproto library#

# Load some code called "Client" from the "atproto" library that will help us work with Bluesky
from atproto import Client

(optional) make a fake Bluesky connection with the fake_atproto library#

For testing purposes, we”ve added this line of code, which loads a fake version of atproto, so it wont actually connect to Bluesky. If you want to try to actually connect to Bluesky, don’t run this line of code.

%run ../../fake_apis/fake_atproto.ipynb
Fake atproto (bsky.app) is replacing the atproto.blue library. Fake atproto doesn't need real passwords, and prevents you from accessing real Bluesky

login to Bluesky#

# Login to Bluesky
# TODO: put your account name and password below

client = Client(base_url="https://bsky.social")
client.login("your_account_name.bsky.social", "m#5@_fake_bsky_password_$%Ds")
Fake atproto is pretending to set up a client connection to: https://bsky.social
Fake atproto is pretending log into your account: your_account_name.bsky.social

Helper function to display text in an indented box#

(You don’t need to worry about how this works. This is that function that helps display posts in indented boxes)

from IPython.display import HTML, Image, display
import html
def display_indented(text, left_margin=0):
    display(
        HTML(
            "<pre style='border:solid 1px;padding:3px;margin-top:3px;margin-bottom:3px;margin-left:"+ str(left_margin) + "px'>" + 
            html.escape(text) + 
            "</pre>"
        )
    )

Code to print a post with replies#

The print_post_thread is a function that takes a Bluesky Post weblink (url) (instructions on where to get one below), downloads the thread that follows that post, and then uses the print_post_and_replies function to print out that post and the replies to that post.

def print_post_thread(postUrl):

    at_post_link = get_at_post_link_from_url(postUrl)
    
    # Fetch the post details
    post_data = client.get_post_thread(at_post_link)
    
    print_post_and_replies(post_data.thread)

The print_post_and_replies function takes a given post and recursively prints that post as well as all replies to that post (which will also print all the replies to those replies, etc.)

def print_post_and_replies(postInfo, num_indents=0):
    
    # make sure this post isn't blocked (since we can't read blocked posts)
    if not (hasattr(postInfo,'blocked') and postInfo.blocked):
        
        post = postInfo.post
        replies = postInfo.replies

        # If replies is None, make it an empty array (so the for loop later doesn't crash)
        if not replies:
            replies = []
    
        display_text = (
            post.record.text + "\n" +
            "-- " + str(post.author.display_name) + " (" + str(post.author.handle) + ")\n" + 
            " (likes: " + str(post.like_count) + 
            ", replies: " + str(post.reply_count) +
            ", reposts: " + str(post.repost_count) + 
            ", quotes: " + str(post.quote_count) + ") - " 
        )
        
        display_indented(display_text, num_indents*20)
    
        #print replies (and the replies of those, etc.)
        for reply in replies:
            print_post_and_replies(reply, num_indents = num_indents + 1)

Finding post IDs and testing our code#

In order to test it out, we need to find a link to a Bluesky post with replies. Once you find the post, find the ‘Copy Link to Post’ option to get a web url for the post.

Bluesky Post. The three dot "Open post options menu" is opened, and from there the "Copy Link to Post" option is selected.

It should be something like: https://bsky.app/profile/realgdt.bsky.social/post/3lihunicmds2y

Now we can test it out by calling the print_post_thread, passing it the url as a string. Then you should see the comment tree.

print_post_thread('https://bsky.app/profile/realgdt.bsky.social/post/3lihunicmds2y')
This is a fake fact about movie costuming and I find it so interesting!
-- Imaginary User (imaginary_user.bsky.social)
 (likes: 25, replies: 2, reposts: 13, quotes: 7) - 
Wow! That is a cool fake fact!
-- Fake User (fake_user.bsky.social)
 (likes: 6, replies: 2, reposts: 5, quotes: 1) - 
You're totally right! I never saw that before!
-- False User (false_user.bsky.social)
 (likes: 3, replies: 1, reposts: 0, quotes: 0) - 
Yeah, and did you see this other detail too?
-- Fake User (fake_user.bsky.social)
 (likes: 7, replies: 1, reposts: 4, quotes: 10) - 
Wow! No way!
-- False User (false_user.bsky.social)
 (likes: 4, replies: 0, reposts: 0, quotes: 0) - 
It's not cool! You are a bad person for saying it's cool!
-- Troll User (troll_user.bsky.social)
 (likes: 0, replies: 0, reposts: 0, quotes: 2) - 
I saw a completely unrelated movie once and I liked it!
-- Pretend User (pretend_user.bsky.social)
 (likes: 1, replies: 1, reposts: 0, quotes: 0) - 
I don't see how that's relevant
-- Fake User (fake_user.bsky.social)
 (likes: 2, replies: 0, reposts: 1, quotes: 1) -