Avian Flu

How to post Images with Hashtags on Bluesky using Python

As it turns out, posting to Bluesky (bsky.app) with Python is very easy.

All you need is the atproto library and an app password to your account. 8 lines of code later and you can upload text posts to your account no problem.

from atproto import Client
def main():
    client = Client()
    client.login(USER, APP_PASS)
    client.send_post(text='#AvianFlu')
if __name__ == '__main__':
    main()

But, what if you want to upload an image? That actually not hard at all either.

BUT, what if you want to upload an image with text that contains an interactable hashtag so that your post shows up on that tags feed? Impossible…..according to Google.

And the BSky development docs are also unclear as to how to approach this with Python. So I had to dig and research and test and re-test. Finally I found what I was looking for with the atproto documentation. Even after that I had to add my own armature spin to the code.

The following code will allow you to create a function and pass it three variables: Text, Image path, Alt text. From there the function will determine if any word in the text you provided needs to be enriched as to become a hashtag or stay as plain text.

This function is currently serving as a way to publicly broadcast my analysis of Avian Flu and its spread through the US food system.

## Import atproto library
from atproto import Client

def bsky_image_post(post_text,image,alt_text):

    ## Create the client and login with app password
    client = Client()
    client.login(USER, APP_PASS)

    ## Call TextBuilder to create a richtext post
    text_builder = client_utils.TextBuilder()   ## Creates a fresh text_builder object to add to

    # Itterate through text to find tags, build out tag for post
    for word in post_text.split(' '):

        ## If words first character is not a hastag
        if word[0] != '#':
            text_builder.text(word+" ")     ## Add word as plain text with a space after

        ## If word first character is a hastag
        if word[0] == '#':
            text_builder.tag(word+" ", word.replace('#',''))        ## Add word as a tag, tag value must be the word only as the text_builder will add a #
            text_builder.text(" ")                                  ## Add a plain text space after to space out the words

    ## Load Image
    with open(image, 'rb') as f:
        img_data = f.read()

    ## Send post to BlueSky
    client.send_image(text=text_builder,        ## Add Text
                      image=img_data,           ## Add Image
                      image_alt=alt_text        ## Add Image alternative text
                      )