Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Smerity/f896e0a9d27c725b2bc03cd85e105b31 to your computer and use it in GitHub Desktop.
Save Smerity/f896e0a9d27c725b2bc03cd85e105b31 to your computer and use it in GitHub Desktop.

Revisions

  1. Smerity created this gist Nov 26, 2024.
    349 changes: 349 additions & 0 deletions all_examples_from_bluesky_atproto_python_api.py.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,349 @@
    === Start of delete_post.py ===

    from atproto import Client


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    # same with the like_post.py example we need to keep a reference to the post
    post_ref = client.send_post('Test send-delete from Python SDK')
    print('Post reference:', post_ref)

    # this method returns True/False depends on the response
    print('Deleted successfully:', client.delete_post(post_ref.uri))


    if __name__ == '__main__':
    main()


    === End of delete_post.py ===


    === Start of home_timeline.py ===

    from atproto import Client


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    print('Home (Following):\n')

    # Get "Home" page. Use pagination (cursor + limit) to fetch all posts
    timeline = client.get_timeline(algorithm='reverse-chronological')
    for feed_view in timeline.feed:
    action = 'New Post'
    if feed_view.reason:
    action_by = feed_view.reason.by.handle
    action = f'Reposted by @{action_by}'

    post = feed_view.post.record
    author = feed_view.post.author

    print(f'[{action}] {author.display_name}: {post.text}')


    if __name__ == '__main__':
    main()


    === End of home_timeline.py ===


    === Start of like_post.py ===

    from atproto import Client


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    post = client.send_post(text='Hello World from Python!')
    print('Post reference:', post)

    print('Like reference:', client.like(uri=post.uri, cid=post.cid))


    if __name__ == '__main__':
    main()


    === End of like_post.py ===


    === Start of process_notifications.py ===

    from time import sleep

    from atproto import Client

    # how often we should check for new notifications
    FETCH_NOTIFICATIONS_DELAY_SEC = 3


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    # fetch new notifications
    while True:
    # save the time in UTC when we fetch notifications
    last_seen_at = client.get_current_time_iso()

    response = client.app.bsky.notification.list_notifications()
    for notification in response.notifications:
    if not notification.is_read:
    print(f'Got new notification! Type: {notification.reason}; from: {notification.author.did}')
    # example: "Got new notification! Type: like; from: did:plc:hlorqa2iqfooopmyzvb4byaz"

    # mark notifications as processed (isRead=True)
    client.app.bsky.notification.update_seen({'seen_at': last_seen_at})
    print('Successfully process notification. Last seen at:', last_seen_at)

    sleep(FETCH_NOTIFICATIONS_DELAY_SEC)


    if __name__ == '__main__':
    main()


    === End of process_notifications.py ===


    === Start of profile_posts.py ===

    from atproto import Client


    def main(client: Client, handle: str) -> None:
    print(f'\nProfile Posts of {handle}:\n\n')

    # Get profile's posts. Use pagination (cursor + limit) to fetch all
    profile_feed = client.get_author_feed(actor=handle)
    for feed_view in profile_feed.feed:
    print('-', feed_view.post.record.text)


    if __name__ == '__main__':
    at_client = Client()
    at_client.login('my-handle', 'my-password')

    while True:
    input_handle = input('\nPlease, enter the handle of the user: ')
    main(at_client, input_handle)


    === End of profile_posts.py ===


    === Start of repost_post.py ===

    from atproto import Client


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    post_ref = client.send_post(text='Hello World from Python!')
    print('Post reference:', post_ref)

    print('Reposted post reference:', client.repost(uri=post_ref.uri, cid=post_ref.cid))


    if __name__ == '__main__':
    main()


    === End of repost_post.py ===


    === Start of send_image.py ===

    from atproto import Client


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    # replace the path to your image file
    with open('cat.jpg', 'rb') as f:
    img_data = f.read()

    client.send_image(text='Post with image from Python', image=img_data, image_alt='Text version of the image (ALT)')


    if __name__ == '__main__':
    main()


    === End of send_image.py ===


    === Start of send_images.py ===

    from atproto import Client


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    # replace the path to your image file
    paths = ['cat.jpg', 'dog.jpg', 'bird.jpg']
    image_alts = ['Text version', 'of the image (ALT)', 'This parameter is optional']

    images = []
    for path in paths:
    with open(path, 'rb') as f:
    images.append(f.read())

    client.send_images(text='Post with image from Python', images=images, image_alts=image_alts)


    if __name__ == '__main__':
    main()


    === End of send_images.py ===


    === Start of send_post.py ===

    from atproto import Client


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    client.send_post(text='Hello World from Python!')


    if __name__ == '__main__':
    main()


    === End of send_post.py ===


    === Start of send_reply.py ===

    from atproto import Client, models


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    root_post_ref = models.create_strong_ref(client.send_post('Post from Python SDK'))

    # Reply to the root post. We need to pass ReplyRef with root and parent
    reply_to_root = models.create_strong_ref(
    client.send_post(
    text='Reply to the root post',
    reply_to=models.AppBskyFeedPost.ReplyRef(parent=root_post_ref, root=root_post_ref),
    )
    )

    # To reply on reply, we need to change the "parent" field. Let's reply to our previous reply
    client.send_post(
    text='Reply to the parent reply',
    reply_to=models.AppBskyFeedPost.ReplyRef(parent=reply_to_root, root=root_post_ref),
    )


    if __name__ == '__main__':
    main()


    === End of send_reply.py ===


    === Start of send_rich_text.py ===

    from atproto import Client, client_utils

    # To send links as "link card" or "quote post" look at the advanced_usage/send_embed.py example.
    # There is a more advanced way to send rich text without helper class in the advanced_usage/send_rich_text.py example.


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    text_builder = client_utils.TextBuilder()
    text_builder.tag('This is a rich message. ', 'atproto')
    text_builder.text('I can mention ')
    text_builder.mention('account', 'did:plc:kvwvcn5iqfooopmyzvb4qzba')
    text_builder.text(' and add clickable ')
    text_builder.link('link', 'https://atproto.blue/')

    # You can pass instance of TextBuilder instead of str to the "text" argument.
    client.send_post(text_builder) # same with send_image method

    # Same with chaining:
    client.send_post(client_utils.TextBuilder().text('Test msg using ').link('Python SDK', 'https://atproto.blue/'))


    if __name__ == '__main__':
    main()


    === End of send_rich_text.py ===


    === Start of send_video.py ===

    from atproto import Client


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    # replace the path to your video file
    with open('video.mp4', 'rb') as f:
    vid_data = f.read()

    client.send_video(text='Post with video from Python', video=vid_data, video_alt='Text version of the video (ALT)')


    if __name__ == '__main__':
    main()


    === End of send_video.py ===


    === Start of unlike_post.py ===

    from atproto import Client


    def main() -> None:
    client = Client()
    client.login('my-handle', 'my-password')

    post = client.send_post('Test like-unlike from Python SDK')
    print('Post reference:', post)

    like = client.like(uri=post.uri, cid=post.cid)
    print('Like reference:', like)

    # this method return True/False depends on the response. could throw exceptions too
    print(client.unlike(like.uri))


    if __name__ == '__main__':
    main()


    === End of unlike_post.py ===