steem-python is a fork of the legendary Piston library by
@xeroc.
It features a refactored codebase, JSON-RPC support, new types and transactions, full API coverage, and a handful of new features.
You can install steem-python with pip:
pip install -U git+git://github.com/Netherdrake/steem-python
Warning: This is NOT the officialsteem-python library.
Use at own risk.
Full documentation is available at http://steem.readthedocs.io
Here are a few example scripts that utilize steem-python.
Here is a relatively simple script built on top of steem-python that will let you sync STEEM blockchain into a simple file. You can run this script as many times as you like, and it will continue from the last block it synced.
importjsonimportosfromcontextlibimportsuppressfromsteem.blockchainimportBlockchaindefget_last_line(filename):
ifos.path.isfile(filename):
withopen(filename, 'rb') asf:
f.seek(-2, 2)
whilef.read(1) !=b"\n":
f.seek(-2, 1)
returnf.readline()
defget_previous_block_num(block):
ifnotblock:
return-1iftype(block) ==bytes:
block=block.decode('utf-8')
iftype(block) ==str:
block=json.loads(block)
returnint(block['previous'][:8], base=16)
defrun(filename):
b=Blockchain()
# automatically resume from where we left off# previous + last + 1start_block=get_previous_block_num(get_last_line(filename)) +2withopen(filename, 'a+') asfile:
forblockinb.stream_from(start_block=start_block, full_blocks=True):
file.write(json.dumps(block, sort_keys=True) +'\n')
if__name__=='__main__':
output_file='/home/user/Downloads/steem.blockchain.json'withsuppress(KeyboardInterrupt):
run(output_file)To see how many blocks we currently have, we can simply perform a line count.
wc -l steem.blockchain.json
We can also inspect an arbitrary block, and pretty-print it. Replace 10000 with desired block_number + 1.
sed '10000q;d' steem.blockchain.json | python -m json.tool
Occasionally things go wrong: software crashes, servers go down... One of the main roles for STEEM witnesses is to reliably mint blocks. This script acts as a kill-switch to protect the network from missed blocks and prevents embarrassment when things go totally wrong.
importtimefromsteemimportSteemsteem=Steem()
# variablesdisable_after=10# disable witness after 10 blocks are missedwitness_name='furion'witness_url="https://steemit.com/steemit/@furion/power-down-no-more"witness_props= {
"account_creation_fee": "0.500 STEEM",
"maximum_block_size": 65536,
"sbd_interest_rate": 15,
}
deftotal_missed():
returnsteem.get_witness_by_account(witness_name)['total_missed']
if__name__=='__main__':
treshold=total_missed() +disable_afterwhileTrue:
iftotal_missed() >treshold:
tx=steem.commit.witness_update(
signing_key=None,
url=witness_url,
props=witness_props,
account=witness_name)
print("Witness %s Disabled!"%witness_name)
quit(0)
time.sleep(60)Most of the time each transaction contains only one operation (for example, an upvote, a transfer or a new post). We can however cram multiple operations in a single transaction, to achieve better efficiency and size reduction.
This script will also teach us how to create and sign transactions ourselves.
fromsteem.transactionbuilderimportTransactionBuilderfromsteembaseimportoperations# lets create 3 transfers, to 3 different peopletransfers= [
{
'from': 'richguy',
'to': 'recipient1',
'amount': '0.001 STEEM',
'memo': 'Test Transfer 1'
},
{
'from': 'richguy',
'to': 'recipient2',
'amount': '0.002 STEEM',
'memo': 'Test Transfer 2'
},
{
'from': 'richguy',
'to': 'recipient3',
'amount': '0.003 STEEM',
'memo': 'Test Transfer 3'
}
]
# now we can construct the transaction# we will set no_broadcast to True because# we don't want to really send funds, just testing.tb=TransactionBuilder(no_broadcast=True)
# lets serialize our transfers into a format Steem can understandoperations= [operations.Transfer(**x) forxintransfers]
# tell TransactionBuilder to use our serialized transferstb.appendOps(operations)
# we need to tell TransactionBuilder about# everyone who needs to sign the transaction.# since all payments are made from `richguy`,# we just need to do this oncetb.appendSigner('richguy', 'active')
# sign the transactiontb.sign()
# broadcast the transaction (publish to steem)# since we specified no_broadcast=True earlier# this method won't actually do anythingtx=tb.broadcast()Here is a simple bot that will reciprocate by upvoting all new posts that mention us. Make sure to set whoami to your Steem username before running.
fromcontextlibimportsuppressfromsteem.blockchainimportBlockchainfromsteem.postimportPostdefrun():
# upvote posts with 30% weightupvote_pct=30whoami='my-steem-username'# stream comments as they are published on the blockchain# turn them into convenient Post objects while we're at itb=Blockchain()
stream=map(Post, b.stream(filter_by=['comment']))
forpostinstream:
ifpost.json_metadata:
mentions=post.json_metadata.get('users', [])
# if post mentions more than 10 people its likely spamifmentionsandlen(mentions) <10:
post.upvote(weight=upvote_pct, voter=whoami)
if__name__=='__main__':
withsuppress(KeyboardInterrupt):
run()