This tutorial is part of a series where different aspects of programming with EOS
are explained. This part will look at streaming blocks
from the EOS Blockchain
by using Python
. The full curriculum can be found below.
Repository
What will I learn
- Create an iterable block stream
- Increase performance by using a session
- Dealing with status codes
Requirements
- Python3.6
Difficulty
- basic
Tutorial
Setup
Download the file from Github. There is 1 file get_blocks.py
. Running the file without any arguments will initiate a performance test, it is also possible to run get_blocks.py
with 2 arguments start_block
and block_count
.
Run scripts as following:
> python get_blocks.py
or
> python get_blocks.py 1 100
Create an iterable block stream
The previous tutorial looked at how to retrieve EOS blocks
by using API POST requests
. Expanding on this code a basic version for streaming these block would be to build a loop. In order to have iterable output yield
can be used.
def stream_blocks(start_block, block_count):
for block_num in range(start_block, start_block + block_count):
yield get_block(block_num)
This makes the function callable as a list which can be iterated, which in turn simplifies processing the blocks afterwards.
for block in stream_blocks(start_block, block_count):
# perform action
Increase performance by using a session
The problem with looping standard POST requests
is that the performance will suffer. For every request
a new connection has to be established. Instead a Session
can be created which is then used to handle all the requests
.
import requests
s = requests.Session()
request = s.post(url=url, data=parameters)
The session needs to be created outside of the loop.
s = requests.Session()
for block_num in range(start_block, start_block + block_count):
yield get_block(block_num, s)
Dealing with status codes
The increased performance creates a new set of problems. Depending on which api_endpoint
is being used there might be restrictions on how many requests can be made in a specific time frame. Which can be solved by adding a delay time.sleep()
before each request
.
EOS
has a block_time
of 500 ms or 2 blocks per second. This means that when the head_block
is reached requests
can be made for blocks
that do not exist yet. Each request
comes with a status_code
, 200
means that everything is ok. There are several status_codes
that can indicate different kind of problems. EOS nodes
use the status_code
500
when a block that does not exist is requested.
{
"code": 500,
"message": "Internal Service Error",
"error": {
"code": 3100002,
"name": "unknown_block_exception",
"what": "unknown block",
"details": [{
"message": "Could not find block: 6000000",
"file": "chain_plugin.cpp",
"line_number": 832,
"method": "get_block"
}]
}
}
By creating a loop that only returns when the correct status_code
the stream will halt until the issue has been dealt with.
while True:
request = s.post(url=url, data=parameters)
if verify_request(request):
return request.text
This allows for unique handling of each status_code
.
def verify_request(request):
if request.status_code == 200:
return True
elif request.status_code == 500:
# Deal with the problem
This can be taken a step further by looking at the error
code
inside the text part of the request
.
elif request.status_code == 500:
error_code = json.loads(request.text)['error']['code']
if error_code == 3100002:
print('Waiting for blockchain to catch up\n')
time.sleep(0.5)
Running the code
Running the code without any arguments will initiate the performance test. 20 blocks will be retrieved with and without using a session. The total time for requesting all blocks will be displayed.
python get_blocks.py
Starting performance test without session
Block 1
Block 2
.
.
Block 20
Took 12.307921886444092 seconds for completion
Starting performance test with session
Block 1
Block 2
.
.
Block 20
Took 3.4480578899383545 seconds for completion
In addition running the code with the arguments start_block
and block_count
will stream the block_count
amount of blocks
from start_block
.
python get_blocks.py 1 10
Block 1
{"timestamp":"2018-06-08T08:08:08.500","producer":"","confirmed":1,"previous":"0000000000000000000000000000000000000000000000000000000000000000","transaction_mroot":"0000000000000000000000000000000000000000000000000000000000000000","action_mroot":"aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906","schedule_version":0,"new_producers":null,"header_extensions":[],"producer_signature":"SIG_K1_111111111111111111111111111111111111111111111111111111111111111116uk5ne","transactions":[],"block_extensions":[],"id":"00000001405147477ab2f5f51cda427b638191c66d2c59aa392d5c2c98076cb0","block_num":1,"ref_block_prefix":4126519930}
Block 2
{"timestamp":"2018-06-09T11:56:30.000","producer":"eosio","confirmed":0,"previous":"00000001405147477ab2f5f51cda427b638191c66d2c59aa392d5c2c98076cb0","transaction_mroot":"0000000000000000000000000000000000000000000000000000000000000000","action_mroot":"e0244db4c02d68ae64dec160310e247bb04e5cb599afb7c14710fbf3f4576c0e","schedule_version":0,"new_producers":null,"header_extensions":[],"producer_signature":"SIG_K1_KhKRMeFHa59AzBaqNvq89Mye9uTNsRsY4koYZk4GBxb4UfSEakj4LwxxP5xQVK4q9N32JFhMpjnHa8pgTKNLwP1vXpU6eg","transactions":[],"block_extensions":[],"id":"0000000267f3e2284b482f3afc2e724be1d6cbc1804532ec62d4e7af47c30693","block_num":2,"ref_block_prefix":976177227}
.
.
.
Curriculum
Part 1: Using Python To Make API Requests To EOS Public API Endpoints
The code for this tutorial can be found on GitHub!
This tutorial was written by @juliank.
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!Hey @steempytutorials
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!
Thank you for your contribution @steempytutorials.
I liked your tutorial, but if the tutorial was more detailed I liked it more!
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Chat with us on Discord.
[utopian-moderator]Need help? Write a ticket on https://support.utopian.io/.