asyncsteem
Twisted based asynchonous python steem API.
This project aims to implement an asynchronous python library for the STEEM JSON-RPC API.
Eventually asyncsteem aims to become a complete asynchronous alternative to steem-python that runs under both Python 2 and Python 3. The current beta however runs only on Python 2 and does not yet implement cryptographic signing operations that would be needed to, post, vote, etc. The asyncsteem library is a asynchonous library, designed to woth with the defacto Python asynchonous networking framework twisted.
If you wish to stay informed on my progress on this library, please follow @mattockfs on steemit or join this discord server. I'll try to blog regularily on my progress. Donations for this project in the form of STEEM or in the form of steemit post upvotes are very much welcomed, as are pull requests with featyres or bug fixes.
Please note that there currently is no install script or pip install available yet, the code is currently in early beta, and ease of install is something I havent gotten to yet at the moment.
In order to use the asyncsteem library, you should define a Python class that implements one or more of the following methods:
- account_create
- account_create_with_delegation
- account_update
- account_witness_proxy
- account_witness_vote
- cancel_transfer_from_savings
- change_recovery_account
- claim_reward_balance
- comment
- comment_options
- convert
- custom
- custom_json
- delegate_\vesting_shares
- delete_comment
- feed_publish
- limit_order_cancel
- limit_order_create
- recover_account
- request_account_recovery
- set_withdraw_vesting_route
- transfer
- transfer_from_savings
- transfer_to_savings
- transfer_to_vesting
- vote
- withdraw_vesting
- witness_update
These methods map one on one to the operation types that are found on the blockchain. For convenience, the following methods may also be implemented:
- transaction
- block
- hour
- day
- week
An example :
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()
In order to use the bot, you will need to use Twisted:
from twisted.internet import reactor
...
blockchain = ActiveBlockChain(reactor)
blockchain.register_bot(bot,"demobot")
reactor.run()
This will let the bot start listening to new events from the STEEM blockchain.
You may also instead opt to pick a day in the past where the bot should start streaming. This could come in handy if you want to test your code, or if you want to limit your bot's online time.
blockchain = ActiveBlockChain(reactor,rewind_days=7)
While the core of the library is aimed at streaming operations from the blockchain, it is likely your bot will need to query other JSON-RPC API's as well. For this, the client argument of the bots methods provides the entry point. But note, the API is asynchonous and works through a command queue and a client pool. Let us zoom in a bit on how to use the client argument in our code.
def vote(self,tm,vote_event,client):
def process_vote_content(event, client):
for vote in event["active_votes"]:
if vote["voter"] == vote_event["voter"] and vote["rshares"] != 0:
print vote["time"],vote["voter"],"=>",vote_event["author"],vote["rshares"]
opp = client.get_content(vote_event["author"],vote_event["permlink"])
opp.on_result(process_vote_content)
Basically, you define a closure for handling the additional API query, you put the command you wish to invoke on the asynchonous command queue and then you bind the result to your closure that will be invoked asynchonously when the command on the queue has been handled by the HTTPS client pool.
In some cases, a JSON-RPC call may return an error for your command. You may create an other callback for the error situation:
def err_handler(errno, msg, rpcclient):
print "OOPS:",msg,"(",errno,")"
opp.on_error(err_handler)
You've seen the example using get_content, this is one of a wide range of JSON-RPC API calls available through the API. The API is fully transperant, so any silly typo you make will result in a bogus JSON-RPC call to one of the STEEM API nodes. For convenience, here is a list of currently commonly available valid API method names:
- get_account_bandwidth
- get_account_count
- get_account_history
- get_account_references
- get_account_votes
- get_accounts
- get_active_votes
- get_active_witnesses
- get_block
- get_block_header
- get_chain_properties
- get_comment_discussions_by_payout
- get_config
- get_content
- get_content_replies
- get_conversion_requests
- get_current_median_history_price
- get_discussions_by_active
- get_discussions_by_author_before_date
- get_discussions_by_blog
- get_discussions_by_cashout
- get_discussions_by_children
- get_discussions_by_comments
- get_discussions_by_created
- get_discussions_by_feed
- get_discussions_by_hot
- get_discussions_by_payout
- get_discussions_by_promoted
- get_discussions_by_trending
- get_discussions_by_votes
- get_dynamic_global_properties
- get_escrow
- get_expiring_vesting_delegations
- get_feed_history
- get_hardfork_version
- get_key_references
- get_liquidity_queue
- get_miner_queue
- get_next_scheduled_hardfork
- get_open_orders
- get_ops_in_block
- get_order_book
- get_owner_history
- get_post_discussions_by_payout
- get_potential_signatures
- get_recovery_request
- get_replies_by_last_update
- get_required_signatures
- get_reward_fund
- get_savings_withdraw_from
- get_savings_withdraw_to
- get_state
- get_tags_used_by_author
- get_transaction
- get_transaction_hex
- get_trending_tags
- get_vesting_delegations
- get_withdraw_routes
- get_witness_by_account
- get_witness_count
- get_witness_schedule
- get_witnesses
- get_witnesses_by_vote
- lookup_account_names
- lookup_accounts
- lookup_witness_accounts
- set_block_applied_callback
- verify_account_authority
- verify_authority
You will need to look elsewhere for now for documentation on the above API calls. When unsure about the exact syntax, please make sure to use an on_error callback. Often the error messages can provide some info on correct usage.
As stated, the library is in early beta now. I would very much appreciate any feedback on my work so far, so please test out what there is and let me know what needs improvement.