Write Steem bots and more in Python with asyncsteem

in utopian-io •  7 years ago  (edited)

This is a guide on how to setup and start working with the asyncsteem library for Python 2.7 by @mattockfs. You'll find this most helpful if you have some experience with Python and interfacing with Steem via steem-python or Piston. Being able to install Python and Twisted is a requirement. We'll briefly explore the motivations for plugging into the blockchain with asynchronous programming, then see how the asyncsteem library makes it simple to write bots and more.

What's so cool about async?

Simply put, asynchronous communication in programming means that we can perform other tasks while we wait for a reply back or confirmation that our message was received. For our purposes, this means retrieving data from Steem nodes. Operating asynchronously offers some advantages: we can make multiple requests in parallel to increase performance, and we can respond to events as they arrive rather than periodically querying for new information. The asyncsteem library provides a basic framework for listening to and acting on updates to the Steem blockchain, which makes it simple to implement basic bots, as we'll see below.

Install

Asyncsteem just depends on Python 2 and the Twisted async framework. Check those links for install instructions, if you don't already have them both. Make sure you get Twisted for Python 2 by using pip2 to install or getting a package labeled something like python2-twisted if you're on Linux. Then download asyncsteem from GitHub by grabbing the zip file or using Git to clone the repository:

$ git clone https://github.com/pibara-utopian/asyncsteem.git


Once you have the code, navigate to the asyncsteem directory in your terminal. You should have the following files:

DeepinScreenshot_select-area_20180221182430.png

Rather than install asnycsteem system wide, we'll just work within this directory where Python can import the library. Create a new file called print_upvotes.py and copy the example code below into it. This is the sample bot given in the asyncsteem README file, which prints info about votes on Stem as they happen.

from twisted.internet import reactor
from twisted.logger import Logger
from asyncsteem import ActiveBlockChain

log = Logger()

class DemoBot:
    def vote(self,tm,vote_event,client):
        w = vote_event["weight"]
        if w > 0:
            print "Vote by",vote_event["voter"],"for",vote_event["author"]
        else:
            if w < 0:
                print "Downvote by",vote_event["voter"],"for",vote_event["author"]
            else:
                print "(Down)vote by",vote_event["voter"],"for",vote_event["author"],"CANCELED"

bot = DemoBot()

blockchain = ActiveBlockChain(reactor, log)
blockchain.register_bot(bot,"demobot")
reactor.run()


Now we can use Python to execute the script:

$ python2 print_votes.py


If everything is flowing through the tubes as expected, you should see a scrolling list of all the votes being made on Steem. Pretty cool, eh? It's not hard to imagine how this simple "bot" could be expanded to do something more useful than spitting out data faster than we can read it. But first, let's walk through this code to see what's making it tick.

from twisted.internet import reactor
from twisted.logger import Logger
from asyncsteem import ActiveBlockChain

log = Logger()


We start by importing some classes from twisted and asyncsteem. Twisted's reactor is going to handle the connections we need to make to Steem nodes over the internet and make callbacks when replies are received. ActiveBlockChain is the asyncsteem class that provides hooks for different events on the blockchain. The logger is needed to initialize an instance of ActiveBlockChain, but otherwise isn't important here.

class DemoBot:
    def vote(self,tm,vote_event,client):
        w = vote_event["weight"]
        if w > 0:
            print "Vote by",vote_event["voter"],"for",vote_event["author"]
...


Our DemoBot class contains the logic for our bot. The vote method will be called whenever a new vote occurs on Steem and print the details to the console. It will be passed the time, a dict with details on the vote, and a client object that can be used for additional queries. By creating other methods with names that correspond to the available hooks, we can respond to other kinds of events on the blockchain. Check asyncsteem's README for a complete list.

bot = DemoBot()

blockchain = ActiveBlockChain(reactor, log)
blockchain.register_bot(bot,"demobot")
reactor.run()


In the final lines of print_votes.py, we instantiate our bot and the ActiveBlockChain object that interacts with the Twisted reactor. Then we register our bot to receive messages from the blockchain object and run the reactor to set everything in motion. You can do some additional reading on how Twisted works to get a better idea for what's going on here, if this bit is confusing.

We can listen for comments by adding a comment method to our class instead. Make another file called print_comments.py for the following code:

from twisted.logger import Logger
from asyncsteem import ActiveBlockChain

log = Logger()

class DemoBot:
    def comment(self,tm,comment_event,client):
        print 'Comment by {} on post {} by {}:'.format(comment_event['author'],
                                                       comment_event['parent_permlink'],
                                                       comment_event['parent_author'])
        print comment_event['body']
        print


bot = DemoBot()

blockchain = ActiveBlockChain(reactor, log)
blockchain.register_bot(bot,"demobot")
reactor.run()


Then run it like the other script and watch the comments fly by in your terminal. Pretty fun, eh? We could modify this to only print comments on certain posts or in response to certain users. At the moment, asyncsteem is best suited for streaming messages off the blockchain, rather than making specific queries. It also doesn't yet have the ability to do cryptographic signing, which is needed for operations like making votes, posts, and comments. But there's still plenty it can do, especially with a bit of imagination.

Asyncsteem is in beta, and its author, @mattockfs, would appreciate any input or bug reports. Check out the latest release post for more details. Please leave any questions about this guide in the comments and I'll get back to you as soon as I can.



Posted on Utopian.io - Rewarding Open Source Contributors

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Thank you for the contribution. It has been approved.

You can contact us on Discord.
[utopian-moderator]

Hey @cha0s0000, I just gave you a tip for your hard work on moderation. Upvote this comment to support the utopian moderators and increase your future rewards!

Awesome little introductory post to this async steem library. I hope he expands it soon to be a bit more useful...as well as being Python 3 compatible...but I think I actually can think of a few uses for it right now as it is. I've always loved working with asyncronous Python.

I've ported the code to Python 3. You can check it out on GitHub.

Thanks! Fleshing out the api and adding Python 3 support are in the works, and I'm sure that any testing would be appreciated in the meantime.

Hey @scottyeager I am @utopian-io. I have just upvoted you!

Achievements

  • You have less than 500 followers. Just gave you a gift to help you succeed!
  • This is your first accepted contribution here in Utopian. Welcome!

Suggestions

  • Contribute more often to get higher and higher rewards. I wish to see you often!
  • Work on your followers to increase the votes/rewards. I follow what humans do and my vote is mainly based on that. Good luck!

Get Noticed!

  • Did you know project owners can manually vote with their own voting power or by voting power delegated to their projects? Ask the project owner to review your contributions!

Community-Driven Witness!

I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!

mooncryption-utopian-witness-gif

Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x

It doesn't work in Python 3?

I've ported the code to Python 3. You can check it out on GitHub.

Python 3 support is planned for sometime after version 1.0, according to roadmap in the 0.5 release announcement.

I've been wanting to check it out, but lack of python3 is a big turn off for me. Would be curious how well it works and how much it supports compared to steem-python.

My tests are positive, but limited. Reading data from the blockchain appears to be fully implemented, but operations requiring signing are not. @mattockfs is working on porting one of his own bots from steem-python as part of further testing.

Congratulation

Today one year ago you joined SteemIt
Thank you, for making SteemIt great and Steem on for more years to come!

(You are being celebrated here)