create account

Part 2: Streaming EOS Blocks With Python by steempytutorials

View this thread on: hive.blogpeakd.comecency.com
· @steempytutorials · (edited)
$57.27
Part 2: Streaming EOS Blocks With Python
<center>![steem-python.png](https://steemitimages.com/0x0/https://cdn.steemitimages.com/DQmeBnp3UNcivaVgrNiz6EZBQFQsJjnEKDx5mdzCtEABSBD/banner.png)</center>

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
https://github.com/EOSIO/eos

#### 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](https://github.com/Juless89/eos-tutorials/tree/master/02). 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](https://steemit.com/utopian-io/@steempytutorials/part-1-using-python-to-make-api-requests-to-eos-public-api-endpoints) 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)
```
<br>
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
```
<br>

#### 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)
```
<br>
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"
		}]
	}
}
```
<br>
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
```
<br>
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
```
<br>
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
```
<br>
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](https://steemit.com/utopian-io/@steempytutorials/part-1-using-python-to-make-api-requests-to-eos-public-api-endpoints) 

---

The code for this tutorial can be found on [GitHub](https://github.com/Juless89/eos-tutorials/tree/master/02)!

This tutorial was written by @juliank.
πŸ‘  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 6 others
properties (23)
authorsteempytutorials
permlinkpart-2-streaming-eos-blocks-with-python
categoryutopian-io
json_metadata{"tags":["utopian-io","tutorials","eos","programming","python"],"users":["juliank"],"image":["https://steemitimages.com/0x0/https://cdn.steemitimages.com/DQmeBnp3UNcivaVgrNiz6EZBQFQsJjnEKDx5mdzCtEABSBD/banner.png"],"links":["https://github.com/EOSIO/eos","https://github.com/Juless89/eos-tutorials/tree/master/02","https://steemit.com/utopian-io/@steempytutorials/part-1-using-python-to-make-api-requests-to-eos-public-api-endpoints"],"app":"steemit/0.1","format":"markdown"}
created2018-07-10 08:18:15
last_update2018-07-10 13:00:27
depth0
children3
last_payout2018-07-17 08:18:15
cashout_time1969-12-31 23:59:59
total_payout_value44.460 HBD
curator_payout_value12.813 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length6,574
author_reputation31,094,047,689,691
root_title"Part 2: Streaming EOS Blocks With Python"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id64,132,057
net_rshares28,590,701,966,086
author_curate_reward""
vote details (70)
@bitzar ·
https://teespring.com/stores/cryptic-bazaar
![](https://cdn.steemitimages.com/DQmSFBrFids1MstypBPZsX8y2xKk1og3ADSLJUq63GZ1sUm/image.png)
πŸ‘  
properties (23)
authorbitzar
permlinkre-steempytutorials-part-2-streaming-eos-blocks-with-python-20180712t121933466z
categoryutopian-io
json_metadata{"tags":["utopian-io"],"image":["https://cdn.steemitimages.com/DQmSFBrFids1MstypBPZsX8y2xKk1og3ADSLJUq63GZ1sUm/image.png"],"links":["https://teespring.com/stores/cryptic-bazaar"],"app":"steemit/0.1"}
created2018-07-12 12:19:39
last_update2018-07-12 12:19:39
depth1
children0
last_payout2018-07-19 12:19:39
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length136
author_reputation-990,165,403,615
root_title"Part 2: Streaming EOS Blocks With Python"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id64,402,935
net_rshares170,146,025
author_curate_reward""
vote details (1)
@portugalcoin ·
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](https://join.utopian.io/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](https://review.utopian.io/result/8/21114313).

---- 
Need help? Write a ticket on https://support.utopian.io/. 
Chat with us on [Discord](https://discord.gg/uTyJkNm). 
[[utopian-moderator]](https://join.utopian.io/)
πŸ‘  
properties (23)
authorportugalcoin
permlinkre-steempytutorials-part-2-streaming-eos-blocks-with-python-20180710t200458433z
categoryutopian-io
json_metadata{"tags":["utopian-io"],"users":["steempytutorials"],"links":["https://join.utopian.io/guidelines","https://review.utopian.io/result/8/21114313","https://support.utopian.io/","https://discord.gg/uTyJkNm","https://join.utopian.io/"],"app":"steemit/0.1"}
created2018-07-10 20:04:57
last_update2018-07-10 20:04:57
depth1
children0
last_payout2018-07-17 20:04:57
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length621
author_reputation598,828,312,571,988
root_title"Part 2: Streaming EOS Blocks With Python"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id64,202,251
net_rshares4,670,714,268
author_curate_reward""
vote details (1)
@utopian-io ·
Hey @steempytutorials
**Thanks for contributing on Utopian**.
We’re already looking forward to your next contribution!

**Want to chat? Join us on Discord https://discord.gg/h52nFrV.**

<a href='https://v2.steemconnect.com/sign/account-witness-vote?witness=utopian-io&approve=1'>Vote for Utopian Witness!</a>
πŸ‘  
properties (23)
authorutopian-io
permlinkre-part-2-streaming-eos-blocks-with-python-20180711t124010z
categoryutopian-io
json_metadata"{"app": "beem/0.19.42"}"
created2018-07-11 12:40:09
last_update2018-07-11 12:40:09
depth1
children0
last_payout2018-07-18 12:40:09
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length308
author_reputation152,955,367,999,756
root_title"Part 2: Streaming EOS Blocks With Python"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id64,281,787
net_rshares5,838,392,836
author_curate_reward""
vote details (1)