<center></center> This tutorial is part of a series where different aspects of programming with `steem-python` are explained. Links to the other tutorials can be found in the curriculum section below. This part will explain how to upload images directly with an API and construct a post with the image. --- #### Repository https://github.com/steemit/steem-python #### What will I learn - Installing and configuring imgurpython - Uploading an image to Imgur - Constructing a post from a template - Submitting a post to STEEM #### Requirements - Python3.6 - `steem-python` - imgurpython #### Difficulty - basic --- ### Tutorial #### Preface The `STEEM Blockchain` allows for direct interaction without using websites like `steemit.com` or `busy.org`. Instead a `post` can be uploaded directly to the `Blockchain`. If one wants to include an image in this post a 3rd party host for this image is required. `Imgur` has an `API` which allows for easy uploading of images with `Python`. #### Setup Download the files from [Github](https://github.com/amosbastian/steempy-tutorials/tree/master/part_28). There 5 are files `post_submitter.py` which is the main file and takes two arguments `account` and `filename`, `imgur.py` which contains the code for uploading an image to Imgur, `EXIF.py` which extracts EXIF data from the image and `post.json` which is a JSON file containing information about the post and also 1 image file for testing. Run scripts as following: `> python post_submitter.py juliank post.json` ### Installing and configuring imgurpython Installation is simple using pip: ``` pip3 install imgurpython ``` <br><center> </center> <br> However to use the `Imgur API` an account is required. Signing up up is free. Go to the following [link](https://api.imgur.com/oauth2/addclient) and create an account. After that a client has to be added for which you will receive a `client_id` and `client_secret`. Add these settings to the `imgur.py` file. <br><center>  </center> #### Uploading an image to Imgur The `Imgur API` is simple to use. After setting the account settings uploading an image is done by calling `upload_from_path()`, it requires the `path` of the `filename`. In this case `anon` is set to `True` so uploader is anonymous. ``` from imgurpython import ImgurClient # account settings client_id = '' client_secret = '' client = ImgurClient(client_id, client_secret) ``` Upon successful upload a `JSON dict` is returned containing all the information about the uploaded image. ``` { 'id': 'kQPLkLs', 'title': None, 'description': None, 'datetime': 1531837066, 'type': 'image/jpeg', 'animated': False, 'width': 2222, 'height': 1481, 'size': 782184, 'views': 0, 'bandwidth': 0, 'vote': None, 'favorite': False, 'nsfw': None, 'section': None, 'account_url': None, 'account_id': 0, 'is_ad': False, 'in_most_viral': False, 'has_sound': False, 'tags': [], 'ad_type': 0, 'ad_url': '', 'in_gallery': False, 'deletehash': 'ppaO3Z1KasKq1lr', 'name': '', 'link': 'https://i.imgur.com/kQPLkLs.jpg' } ``` From this dict the `link` is retrieved to be used in the `post`. ``` def upload_image(filename): # upload the image as anonymous image = client.upload_from_path(filename, anon=True) # retrieve only the image url from the retrieved json data # return the url url = image['link'] return url ``` #### Constructing a post from a template A `post` on `STEEM` requires more than a single image. The additional data required to submit a post is stored in `post.json`. ``` { "title": "Keeping Watch", "tags": "blog street photography zagreb croatia", "caption": "Or just enjoying the view that comes with the job?", "image": "1.jpg" } ``` This data is taken from the `JSON` file and stored in `variables` to be submitted in a `post`. ``` def submit_post(self, account, filename): # Load post data post = json.load(open(filename)) title = post['title'] tags = post['tags'] caption = post['caption'] image = post['image'] ``` The image is upload via the `Imgur API` returning a `url`. ``` # upload the image and retrieve the url url = imgur.upload_image(image) ``` Optionally the image is processed for `EXIF` data which is put into a` table`, to read more about this follow this tutorial: [Extracting EXIF (Meta)Data From Images With Python](https://steemit.com/utopian-io/@steempytutorials/extracting-exif-meta-data-from-images-with-python) ``` # process the iamge for EXIF data to construct a table table = exif.process_image(image) ``` With all the required data complete the `body` of the `post` be be constructed using a simple `template`. `"""` is used to create a `multi-line` string in `Python` and `textwrap.dedent()` is used to remove the tabs in front of each string. This allows for elegant formatting. ``` # Use template to construct a body for the post body = textwrap.dedent( f""" <center> {caption} --- []({url}) --- {table} </center """) ``` #### Submitting a post to STEEM Submitting a post to `STEEM` is done by calling the `post()` function on the `Steem object`. 8 out of the 11 arguments are optional, but can be customised depending on preferences. ``` def post(self, title, body, author, permlink=None, reply_identifier=None, json_metadata=None, comment_options=None, community=None, tags=None, beneficiaries=None, self_vote=False): ``` The `title` and `tags` were taken from `post.json`, the `body` was constructed and the `account` is set when calling `post_submitter.py`. ``` # Submit post to the Steem Blockchain self.steem.post(title=title, body=body, author=account, tags=tags) ``` The function `post()` returns a `dict` with all the information about the `post` that was just submitted. ``` { 'ref_block_num': 7964, 'ref_block_prefix': 1056726494, 'expiration': '2018-07-17T13:45:31', 'operations': [ ['comment', { 'parent_author': '', 'parent_permlink': 'photography', 'author': 'juliank', 'permlink': 'keeping-watch', 'title': 'Keeping Watch', 'body': '\n<center>\nOr just enjoying the view that comes with the job?\n---\n[])(https://i.imgur.com/mSIa5CN.jpg)\n---\n\n\n<table>\n<tr><td>Settings</td><td><b>ISO 100 85\nmm f/7/5 1/640 sec </b></td></tr>\n<tr><td>Camera</td><td><b>SONY ILCE-7M3</b></td></tr>\n<tr><td>Lens</td><td><b>FE 85mm F1.4 GM</b></td></tr>\n<tr><td>Date</td><td><b>2018:07:17 15:31:41</b></td></tr>\n</table>\n\n</center\n', 'json_metadata': '{"tags": ["photography", "blog", "zagreb", "street", "croatia"]}' }] ], 'extensions': [], 'signatures': ['2004881217455592399c83510cb4c55219f229ff681113972db4850e31634d700d74a02381aad27ac735cbaec0af2509336deed8d48a7f1844abb48518841f4f26'] } ``` Inside here information like the `permlink` which is required for `upvoting` the `post` can be found. #### Running the script Running the code will upload the image to imgur and construct a post that is submitted to the STEEM Blockchain ``` python post_submitter.py juliank post.json ```  <br> The constructed post: ``` <center> Or just enjoying the view that comes with the job? --- [](https://i.imgur.com/mSIa5CN.jpg) --- <table> <tr><td>Settings</td><td><b>ISO 100 85 mm f/7/5 1/640 sec </b></td></tr> <tr><td>Camera</td><td><b>SONY ILCE-7M3</b></td></tr> <tr><td>Lens</td><td><b>FE 85mm F1.4 GM</b></td></tr> <tr><td>Date</td><td><b>2018:07:17 15:31:41</b></td></tr> </table> </center> ``` #### Curriculum ##### Set up: - [Part 0: How To Install Steem-python, The Official Steem Library For Python](https://steemit.com/utopian-io/@amosbastian/how-to-install-steem-python-the-official-steem-library-for-python) - [Extracting EXIF (Meta)Data From Images With Python](https://steemit.com/utopian-io/@steempytutorials/extracting-exif-meta-data-from-images-with-python) --- The code for this tutorial can be found on [GitHub](https://github.com/amosbastian/steempy-tutorials/tree/master/part_28)! This tutorial was written by @juliank.
author | steempytutorials |
---|---|
permlink | part-28-uploading-images-via-an-api-constructing-posts-from-a-template-submitting-posts-directly-to-steem |
category | utopian-io |
json_metadata | {"tags":["utopian-io","tutorials","steem-python","python","programming"],"users":["juliank"],"image":["https://res.cloudinary.com/hpiynhbhq/image/upload/v1515886103/kmzfcpvtzuwhvqhgpyjp.png","https://cdn.steemitimages.com/DQmaQwaQYgN3eUPTEABrsr2Jh1TUkrCCuwFYTauyGeZEfLC/Screenshot%202018-07-17%2016.09.24.png","https://cdn.steemitimages.com/DQmRx2CH9z6pA2xS4G7KcDXtMHFe5Yj6V5T2QxzoLSMATLo/Screenshot%202018-07-17%2016.09.51.png","https://cdn.steemitimages.com/DQmbawKcmoYPxRvByzkFuFzKexTjjXkF7ZK8Y8Fc1gKZJDJ/Screenshot%202018-07-17%2016.37.35.png"],"links":["https://github.com/steemit/steem-python","https://github.com/amosbastian/steempy-tutorials/tree/master/part_28","https://api.imgur.com/oauth2/addclient","https://steemit.com/utopian-io/@steempytutorials/extracting-exif-meta-data-from-images-with-python","https://steemit.com/utopian-io/@amosbastian/how-to-install-steem-python-the-official-steem-library-for-python"],"app":"steemit/0.1","format":"markdown"} |
created | 2018-07-17 14:50:57 |
last_update | 2018-07-17 14:50:57 |
depth | 0 |
children | 7 |
last_payout | 2018-07-24 14:50:57 |
cashout_time | 1969-12-31 23:59:59 |
total_payout_value | 54.486 HBD |
curator_payout_value | 11.379 HBD |
pending_payout_value | 0.000 HBD |
promoted | 0.000 HBD |
body_length | 8,753 |
author_reputation | 31,094,047,689,691 |
root_title | "Part 28: Uploading Images Via An API, Constructing Posts From A Template, Submitting Posts Directly To STEEM" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 65,000,796 |
net_rshares | 31,582,947,436,694 |
author_curate_reward | "" |
voter | weight | wgt% | rshares | pct | time |
---|---|---|---|---|---|
brandonp | 0 | 215,392,016,847 | 100% | ||
ace108 | 0 | 44,908,283,084 | 4% | ||
cristi | 0 | 95,553,088,776 | 21% | ||
achiron | 0 | 15,077,407,348 | 100% | ||
eroche | 0 | 25,576,926,742 | 100% | ||
steemitboard | 0 | 431,103,066 | 1% | ||
fronttowardenemy | 0 | 9,513,973,366 | 25% | ||
juliank | 0 | 122,543,650,743 | 50% | ||
aleister | 0 | 6,943,351,259 | 25% | ||
samuelgichu | 0 | 598,571,542 | 100% | ||
upheaver | 0 | 1,125,931,042 | 6% | ||
drorion | 0 | 1,419,190,148 | 100% | ||
modernpastor | 0 | 1,344,684,975,292 | 100% | ||
swissclive | 0 | 191,139,404,746 | 100% | ||
scorer | 0 | 39,175,681,938 | 100% | ||
makerhacks | 0 | 34,081,487,343 | 20% | ||
jrawsthorne | 0 | 17,062,362,753 | 100% | ||
k0d3g3ar | 0 | 0 | 100% | ||
utopian-io | 0 | 27,474,611,202,581 | 17.8% | ||
greenorange | 0 | 609,471,115 | 100% | ||
steemitstats | 0 | 3,304,985,519 | 5% | ||
kryptoblogger | 0 | 47,804,569,036 | 100% | ||
amosbastian | 0 | 56,146,930,826 | 100% | ||
grzesiekb | 0 | 173,408,054,692 | 100% | ||
jjay | 0 | 467,574,709 | 66% | ||
kujou | 0 | 1,124,322,393 | 100% | ||
aytekinaygun | 0 | 608,940,665 | 100% | ||
steempytutorials | 0 | 7,919,371,483 | 100% | ||
johangericke | 0 | 1,752,280,973 | 100% | ||
degrimmis | 0 | 567,249,506 | 100% | ||
hevictor | 0 | 4,537,474,935 | 100% | ||
runorg | 0 | 255,087,696,402 | 100% | ||
phlatattak | 0 | 1,363,867,667,082 | 100% | ||
adam-saudagar | 0 | 2,718,700,948 | 100% | ||
stanprucha | 0 | 599,992,109 | 100% | ||
tamaxadi | 0 | 443,985,689 | 100% | ||
nicknyr | 0 | 5,080,871,763 | 100% | ||
mrf | 0 | 6,612,412,429 | 100% | ||
iauns | 0 | 10,446,275,804 | 100% |
Thank you ... I very take advantage of your tutorials.
author | aytekinaygun |
---|---|
permlink | re-steempytutorials-part-28-uploading-images-via-an-api-constructing-posts-from-a-template-submitting-posts-directly-to-steem-20180717t194417282z |
category | utopian-io |
json_metadata | {"community":"busy","app":"busy/2.5.3","format":"markdown","tags":["utopian-io"],"users":[],"links":[],"image":[]} |
created | 2018-07-17 19:44:21 |
last_update | 2018-07-17 19:44:21 |
depth | 1 |
children | 0 |
last_payout | 2018-07-24 19:44:21 |
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 | 54 |
author_reputation | 3,749,800,672 |
root_title | "Part 28: Uploading Images Via An API, Constructing Posts From A Template, Submitting Posts Directly To STEEM" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 65,029,470 |
net_rshares | 0 |
Thank you for these tutorials!
author | fronttowardenemy |
---|---|
permlink | re-steempytutorials-part-28-uploading-images-via-an-api-constructing-posts-from-a-template-submitting-posts-directly-to-steem-20180717t184623046z |
category | utopian-io |
json_metadata | {"tags":["utopian-io"],"app":"steemit/0.1"} |
created | 2018-07-17 18:46:21 |
last_update | 2018-07-17 18:46:21 |
depth | 1 |
children | 1 |
last_payout | 2018-07-24 18:46:21 |
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 | 30 |
author_reputation | 63,901,774,804,002 |
root_title | "Part 28: Uploading Images Via An API, Constructing Posts From A Template, Submitting Posts Directly To STEEM" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 65,024,225 |
net_rshares | 8,245,034,729 |
author_curate_reward | "" |
voter | weight | wgt% | rshares | pct | time |
---|---|---|---|---|---|
steempytutorials | 0 | 8,245,034,729 | 100% |
Thanks, you are welcome!
author | steempytutorials |
---|---|
permlink | re-fronttowardenemy-re-steempytutorials-part-28-uploading-images-via-an-api-constructing-posts-from-a-template-submitting-posts-directly-to-steem-20180717t192422670z |
category | utopian-io |
json_metadata | {"tags":["utopian-io"],"app":"steemit/0.1"} |
created | 2018-07-17 19:24:21 |
last_update | 2018-07-17 19:24:21 |
depth | 2 |
children | 0 |
last_payout | 2018-07-24 19:24:21 |
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 | 24 |
author_reputation | 31,094,047,689,691 |
root_title | "Part 28: Uploading Images Via An API, Constructing Posts From A Template, Submitting Posts Directly To STEEM" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 65,027,839 |
net_rshares | 9,730,200,034 |
author_curate_reward | "" |
voter | weight | wgt% | rshares | pct | time |
---|---|---|---|---|---|
fronttowardenemy | 0 | 9,730,200,034 | 25% |
Thank you. Very helpful. Question: Is there any downside of hosting images on one's own webserver rather than using IMGUR or some other 3rd party server?
author | k0d3g3ar |
---|---|
permlink | re-steempytutorials-part-28-uploading-images-via-an-api-constructing-posts-from-a-template-submitting-posts-directly-to-steem-20180827t193753850z |
category | utopian-io |
json_metadata | {"tags":["utopian-io"],"app":"steemit/0.1"} |
created | 2018-08-27 19:37:54 |
last_update | 2018-08-27 19:37:54 |
depth | 1 |
children | 0 |
last_payout | 2018-09-03 19:37:54 |
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 | 156 |
author_reputation | 353,394,874,854 |
root_title | "Part 28: Uploading Images Via An API, Constructing Posts From A Template, Submitting Posts Directly To STEEM" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 69,533,510 |
net_rshares | 0 |
Thank you for your contribution. 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/22311313). ---- 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-28-uploading-images-via-an-api-constructing-posts-from-a-template-submitting-posts-directly-to-steem-20180717t210401740z |
category | utopian-io |
json_metadata | {"tags":["utopian-io"],"links":["https://join.utopian.io/guidelines","https://review.utopian.io/result/8/22311313","https://support.utopian.io/","https://discord.gg/uTyJkNm","https://join.utopian.io/"],"app":"steemit/0.1"} |
created | 2018-07-17 21:04:00 |
last_update | 2018-07-17 21:04:00 |
depth | 1 |
children | 0 |
last_payout | 2018-07-24 21:04:00 |
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 | 524 |
author_reputation | 598,828,312,571,988 |
root_title | "Part 28: Uploading Images Via An API, Constructing Posts From A Template, Submitting Posts Directly To STEEM" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 65,036,288 |
net_rshares | 6,276,105,671 |
author_curate_reward | "" |
voter | weight | wgt% | rshares | pct | time |
---|---|---|---|---|---|
espoem | 0 | 5,838,392,836 | 5% | ||
mops2e | 0 | 437,712,835 | 18% |
Congratulations @steempytutorials! You have completed the following achievement on Steemit and have been rewarded with new badge(s) : [](http://steemitboard.com/@steempytutorials) Award for the number of comments <sub>_Click on the badge to view your Board of Honor._</sub> <sub>_If you no longer want to receive notifications, reply to this comment with the word_ `STOP`</sub> To support your work, I also upvoted your post! **Do not miss the last post from @steemitboard:** [SteemitBoard World Cup Contest - The results, the winners and the prizes](https://steemit.com/steemitboard/@steemitboard/steemitboard-world-cup-contest-the-results-and-prizes) > Do you like [SteemitBoard's project](https://steemit.com/@steemitboard)? Then **[Vote for its witness](https://v2.steemconnect.com/sign/account-witness-vote?witness=steemitboard&approve=1)** and **get one more award**!
author | steemitboard |
---|---|
permlink | steemitboard-notify-steempytutorials-20180718t053526000z |
category | utopian-io |
json_metadata | {"image":["https://steemitboard.com/img/notify.png"]} |
created | 2018-07-18 05:35:24 |
last_update | 2018-07-18 05:35:24 |
depth | 1 |
children | 0 |
last_payout | 2018-07-25 05:35:24 |
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 | 967 |
author_reputation | 38,975,615,169,260 |
root_title | "Part 28: Uploading Images Via An API, Constructing Posts From A Template, Submitting Posts Directly To STEEM" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 65,075,751 |
net_rshares | 0 |
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-28-uploading-images-via-an-api-constructing-posts-from-a-template-submitting-posts-directly-to-steem-20180719t161009z |
category | utopian-io |
json_metadata | "{"app": "beem/0.19.42"}" |
created | 2018-07-19 16:10:09 |
last_update | 2018-07-19 16:10:09 |
depth | 1 |
children | 0 |
last_payout | 2018-07-26 16:10: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 28: Uploading Images Via An API, Constructing Posts From A Template, Submitting Posts Directly To STEEM" |
beneficiaries | [] |
max_accepted_payout | 1,000,000.000 HBD |
percent_hbd | 10,000 |
post_id | 65,260,763 |
net_rshares | 0 |