<center></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.
author | steempytutorials |
---|---|
permlink | part-2-streaming-eos-blocks-with-python |
category | utopian-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"} |
created | 2018-07-10 08:18:15 |
last_update | 2018-07-10 13:00:27 |
depth | 0 |
children | 3 |
last_payout | 2018-07-17 08:18:15 |
cashout_time | 1969-12-31 23:59:59 |
total_payout_value | 44.460 HBD |
curator_payout_value | 12.813 HBD |
pending_payout_value | 0.000 HBD |
promoted | 0.000 HBD |
body_length | 6,574 |
author_reputation | 31,094,047,689,691 |
root_title | "Part 2: Streaming EOS Blocks With Python" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 64,132,057 |
net_rshares | 28,590,701,966,086 |
author_curate_reward | "" |
voter | weight | wgt% | rshares | pct | time |
---|---|---|---|---|---|
berkah | 0 | 8,111,362,021 | 100% | ||
hbhades | 0 | 9,297,488,377 | 100% | ||
paco-steem | 0 | 0 | 100% | ||
corina | 0 | 17,746,246,203 | 100% | ||
ace108 | 0 | 14,963,525,846 | 1% | ||
lucashunter | 0 | 6,398,274,120 | 100% | ||
achiron | 0 | 22,559,599,273 | 100% | ||
fajarsdq | 0 | 7,935,607,369 | 100% | ||
chronogn | 0 | 6,477,692,558 | 100% | ||
jamhuery | 0 | 6,332,059,425 | 100% | ||
blackvapor | 0 | 10,580,275,429 | 100% | ||
juliank | 0 | 67,835,063,641 | 30% | ||
greeksteemjesus | 0 | 10,444,393,218 | 100% | ||
thewealthunit | 0 | 24,636,447,667 | 53% | ||
slavix | 0 | 220,589,081,035 | 100% | ||
djbk | 0 | 5,540,445,861 | 100% | ||
novale | 0 | 26,879,216,354 | 100% | ||
veleje | 0 | 11,571,504,660 | 100% | ||
bubke | 0 | 37,732,678,509 | 100% | ||
ccoin | 0 | 7,116,939,973 | 100% | ||
sonu | 0 | 42,844,429,460 | 100% | ||
botty | 0 | 3,668,933,245 | 100% | ||
elautomatico | 0 | 17,075,029,431 | 100% | ||
talalofficial | 0 | 6,057,472,606 | 100% | ||
spooks | 0 | 6,198,775,828 | 100% | ||
flowily | 0 | 13,543,330,275 | 100% | ||
shintamonica | 0 | 224,469,197 | 100% | ||
ambmicheal | 0 | 9,811,555,922 | 100% | ||
scorer | 0 | 40,581,918,624 | 100% | ||
makerhacks | 0 | 32,957,569,322 | 20% | ||
techmojo | 0 | 7,102,104,326 | 100% | ||
loshcat | 0 | 2,939,976,403 | 100% | ||
hsynterkr | 0 | 6,058,407,832 | 100% | ||
ronak10 | 0 | 42,324,704,032 | 100% | ||
leopardis | 0 | 6,943,862,877 | 100% | ||
imp.unity | 0 | 16,557,962,775 | 100% | ||
utopian-io | 0 | 27,491,791,605,410 | 17.8% | ||
steveconnor | 0 | 43,053,470,132 | 100% | ||
pedroo | 0 | 7,969,761,520 | 100% | ||
sagarthukral | 0 | 43,176,344,778 | 100% | ||
laurasusannah | 0 | 3,461,547,578 | 100% | ||
greenorange | 0 | 606,408,447 | 100% | ||
steemitstats | 0 | 3,288,298,887 | 5% | ||
intronitro | 0 | 6,659,169,663 | 100% | ||
cryptomeme | 0 | 5,391,728,254 | 100% | ||
amosbastian | 0 | 50,442,291,372 | 100% | ||
tosyne2much | 0 | 7,368,918,802 | 100% | ||
thinkingmind | 0 | 4,347,072,408 | 100% | ||
see5staar | 0 | 6,081,755,892 | 100% | ||
portugalcoin | 0 | 18,375,132,862 | 100% | ||
ikrahch | 0 | 7,254,412,815 | 100% | ||
pacolimited | 0 | 10,500,347,475 | 100% | ||
eternittyyy | 0 | 14,216,426,904 | 100% | ||
steempytutorials | 0 | 5,700,906,301 | 100% | ||
hevictor | 0 | 4,457,226,852 | 100% | ||
polbot | 0 | 228,332,204 | 100% | ||
joe420 | 0 | 3,769,969,189 | 100% | ||
supernovastaffy | 0 | 6,110,474,062 | 100% | ||
vanityplates | 0 | 15,385,329,647 | 100% | ||
properfraction | 0 | 559,869,106 | 100% | ||
freetousesounds | 0 | 5,909,260,608 | 100% | ||
dany2323 | 0 | 591,929,520 | 100% | ||
thegoldencobra | 0 | 5,745,269,980 | 100% | ||
sriz | 0 | 13,876,117,788 | 100% | ||
rasor | 0 | 4,165,759,982 | 100% | ||
coinsity | 0 | 6,447,042,384 | 100% | ||
pinkwonder | 0 | 630,036,241 | 100% | ||
ruchit786 | 0 | 11,155,296,393 | 100% | ||
eosinsider | 0 | 183,907,785 | 100% | ||
zerocloo | 0 | 4,162,141,151 | 100% |
https://teespring.com/stores/cryptic-bazaar 
author | bitzar |
---|---|
permlink | re-steempytutorials-part-2-streaming-eos-blocks-with-python-20180712t121933466z |
category | utopian-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"} |
created | 2018-07-12 12:19:39 |
last_update | 2018-07-12 12:19:39 |
depth | 1 |
children | 0 |
last_payout | 2018-07-19 12:19:39 |
cashout_time | 1969-12-31 23:59:59 |
total_payout_value | 0.000 HBD |
curator_payout_value | 0.000 HBD |
pending_payout_value | 0.000 HBD |
promoted | 0.000 HBD |
body_length | 136 |
author_reputation | -990,165,403,615 |
root_title | "Part 2: Streaming EOS Blocks With Python" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 64,402,935 |
net_rshares | 170,146,025 |
author_curate_reward | "" |
voter | weight | wgt% | rshares | pct | time |
---|---|---|---|---|---|
bitzar | 0 | 170,146,025 | 100% |
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/)
author | portugalcoin |
---|---|
permlink | re-steempytutorials-part-2-streaming-eos-blocks-with-python-20180710t200458433z |
category | utopian-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"} |
created | 2018-07-10 20:04:57 |
last_update | 2018-07-10 20:04:57 |
depth | 1 |
children | 0 |
last_payout | 2018-07-17 20:04:57 |
cashout_time | 1969-12-31 23:59:59 |
total_payout_value | 0.000 HBD |
curator_payout_value | 0.000 HBD |
pending_payout_value | 0.000 HBD |
promoted | 0.000 HBD |
body_length | 621 |
author_reputation | 598,828,312,571,988 |
root_title | "Part 2: Streaming EOS Blocks With Python" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 64,202,251 |
net_rshares | 4,670,714,268 |
author_curate_reward | "" |
voter | weight | wgt% | rshares | pct | time |
---|---|---|---|---|---|
espoem | 0 | 4,670,714,268 | 5% |
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>
author | utopian-io |
---|---|
permlink | re-part-2-streaming-eos-blocks-with-python-20180711t124010z |
category | utopian-io |
json_metadata | "{"app": "beem/0.19.42"}" |
created | 2018-07-11 12:40:09 |
last_update | 2018-07-11 12:40:09 |
depth | 1 |
children | 0 |
last_payout | 2018-07-18 12:40:09 |
cashout_time | 1969-12-31 23:59:59 |
total_payout_value | 0.000 HBD |
curator_payout_value | 0.000 HBD |
pending_payout_value | 0.000 HBD |
promoted | 0.000 HBD |
body_length | 308 |
author_reputation | 152,955,367,999,756 |
root_title | "Part 2: Streaming EOS Blocks With Python" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 64,281,787 |
net_rshares | 5,838,392,836 |
author_curate_reward | "" |
voter | weight | wgt% | rshares | pct | time |
---|---|---|---|---|---|
espoem | 0 | 5,838,392,836 | 5% |