create account

How To Use Python To Interact With Steemconnect's Access Tokens, Refresh Tokens And Perform Voting by steempytutorials

View this thread on: hive.blogpeakd.comecency.com
· @steempytutorials · (edited)
$47.70
How To Use Python To Interact With Steemconnect's Access Tokens, Refresh Tokens And Perform Voting
<center>![banner.png](https://cdn.steemitimages.com/DQmaqmkNGUPGei1xJdTmHcqEotS9ac6oaigWg9AN2Zv4Eoz/banner.png)</center>

This tutorial will explain how Steemconnect and Python can be used to build a back-end application that is used to perform voting.

---

#### Repository
https://github.com/steemit/steemconnect
https://github.com/emre/steemconnect-python-client

#### What will I learn

- Storing access tokens
- Retrieving access token en refreshing
- Voting and response
- Error handling

#### Requirements

- Python3.6
- MySQL
- Steemconnect

#### Difficulty

- intermediate

---

### Tutorial

#### Preface
Python is a great language to build back-end applications that work great in conjunction with a front-end that is for example build with a framework like WordPress. This tutorial will look into how voting can be done by fetching `access_tokens` from a MySQL database. There are 3 files that are not set up to do anything in particular but include all the functions and database table structure to do so. [Github link](https://github.com/amosbastian/steempy-tutorials/tree/master/part_30).

#### Install Steemconnect for Python
A splendid Steemconnect written for Python by @emrebeyler.
```
pip3 install steemconnect
```

#### Setting up your Steemconnect app
This tutorial requires access to a Steemconnect app. It is somewhat a continuation on the Steemconnect & WordPress tutorials [1](https://steemit.com/utopian-io/@steempytutorials/integrate-steemconnect-v2-user-authentication-into-any-wordpress-website) and [2](https://steemit.com/utopian-io/@steempytutorials/integrate-steemconnect-v2-user-authorisation-into-any-wordpress-website). However, they are not required for this tutorial.

All Steemconnect actions are performed via the `Client` object. It takes the `client_id` and `client_secret` from your Steemconnect app. In addition it requires the `access_token` for the account that actions will be performed for. A separate `Client` is needed for each account, or the `access_token` has to be changed.

```
c = Client(
        client_id=CLIENT_ID,
        client_secret=CLIENT_SECRET,
        access_token=access_token,
    )
```

The `client_id` and `client_secret` are declared outside of the function. This is also true for the database variables. They have to be configured for the code to work.


#### Storing access tokens
For the storing of the access tokens a MySQL database is used that has the following properties. This tutorial assumes that there is already a solution in place to obtain the initial access tokens and will look into how they can be used afterwards.

```
CREATE TABLE `steem_authorization` (
  `id` int(11) NOT NULL,
  `access_token` text NOT NULL,
  `user_login` varchar(20) NOT NULL,
  `expires_in` datetime NOT NULL,
  `refresh_token` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `steem_authorization`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `user_login` (`user_login`);

ALTER TABLE `steem_authorization`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
```

There are 4 main attributes. The `access_token` itself, the `user_login`, which STEEM account is belongs to, `expires_in`, this is calculated when the access_token is created. And the `refresh_token`, this is given when offline access is requested and is used to refresh the `access token` when it expires.

#### Retrieving access tokens and refreshing
The query is relatively simple as there should only be 1 `access_token` per user in the database. If this is not the case the updating and or registering for the `access_token` is not dealt with properly. `get_data()` fetches all the rows and return them.

```
def get_user_auth(self, voter):
    query = ("SELECT `access_token`,`refresh_token`,`expires_in` FROM " +
             f"`steem_authorization` WHERE `user_login` = '{voter}'")
    return self.get_data(query)
```
<br>
The access token is fetched from the database with its relevant data. The next step is to verify that the `access_token` is still valid, if not it must be renewed. **Note: This is only possible if the user gave authorisation for offline access.**
```
result = self.db.get_user_auth(voter)
access_token, refresh_token, expire_on = result[0]
dt = datetime.now()
```
<br>
The current date is referenced against the date when the token expires. The `access_token` is then refreshed by calling the `refresh_access_token()` function inside Client. The new variables are then stored in the database.
```
# Verify access_token
if dt > expire_on:
    result = c.refresh_access_token(
                refresh_token,
                "login,vote"  # scopes
    )

# Retrieve new variables and store in DB
access_token = result['access_token']
refresh_token = result['refresh_token']
expires_in = result['expires_in']
self.db.update_authentication_tokens(
    voter,
    access_token,
    refresh_token,
    expires_in,
    self.timestamp,
)
```
<br>
The current timestamp is used to calculate the new date when the new `access_token` expires.
```
def update_authentication_tokens(self, voter, access_token, refresh_token,
                                 expires_in, timestamp):
    dt = datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S')
    expires_in = dt + timedelta(seconds=expires_in)

    query = ("UPDATE `steem_authorization` SET `access_token` = " +
             f"'{access_token}', `expires_in` = '{expires_in}', " +
             f"`refresh_token` = '{refresh_token}' WHERE " +
             f"`user_login` = '{voter}';")
    self.post_data(query, 'steem_authorization')
```


#### Voting and response
Voting is relatively simple as it just requires the parameters that make up the vote.

```
# Perform vote
vote = Vote(voter, author, permlink, weight)
```
<br>
The vote will return a response, if it succeeds or fails.
```
result = c.broadcast([vote.to_operation_structure()])
```
<br>
A successful example:
```
{
	'result': {
		'id': 'b0e79cc31de3d248d7a90406edadf9dc3e979e14',
		'block_num': 24673233,
		'trx_num': 21,
		'expired': False,
		'ref_block_num': 31679,
		'ref_block_prefix': 3139963426,
		'expiration': '2018-08-01T01:57:57',
		'operations': [
			['vote', {
				'voter': 'juliank',
				'author': 'axeman',
				'permlink': 'girls-n-cars-greta-vs-mb',
				'weight': 1000
			}]
		],
		'extensions': [],
		'signatures': ['1f7b83bba9177a8f5c980e6185f7546134554ae6229363a1ef2986bdb29ba60d0b5b7e3cf6975e8d3d955a3274b2b8cbf526fd42b1b2f88ed0167c45296a50d15a']
	}
}
```
An example of an error:
```
{
	'error': 'server_error',
	'error_description': 'itr->vote_percent != o.weight: You have already voted in a similar way.'
}
```

#### Error handling
Error handling is done by just looking if there is an `error` key in the result.

```
if 'error' in result:
   message = result['error_description']
   print(message)
else:
   message = 'Succes'
   print(message)
```
<br>
It is recommend to capture the `error` message and store this inside the database for manual review. This way the application can continue.

```
self.db.add_to_error_log(
    voter, author, permlink, weight,
    message, self.timestamp,

def add_to_error_log(self, voter, author, permlink, weight, message,
                     timestamp):
    query = (
        'INSERT INTO `error_log` (`id`, `voter`, `author`, ' +
        '`permlink`, `weight`, `error`, `timestamp`) VALUES ' +
        f'(NULL, "{voter}", "{author}", "{permlink}", ' +
        f'"{weight}", "{message}", "{timestamp}");')
    self.post_data(query, 'error_log')
```
---

The files are available on [Github](https://github.com/amosbastian/steempy-tutorials/tree/master/part_30).

This tutorial was written by @juliank.
πŸ‘  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
properties (23)
authorsteempytutorials
permlinkhow-to-use-python-to-interact-with-steemconnect-s-access-tokens-refresh-tokens-and-perform-voting
categoryutopian-io
json_metadata{"tags":["utopian-io","tutorials","programming","steem","steemconnect"],"users":["emrebeyler","juliank"],"image":["https://cdn.steemitimages.com/DQmaqmkNGUPGei1xJdTmHcqEotS9ac6oaigWg9AN2Zv4Eoz/banner.png"],"links":["https://github.com/steemit/steemconnect","https://github.com/emre/steemconnect-python-client","https://github.com/amosbastian/steempy-tutorials/tree/master/part_30","https://steemit.com/utopian-io/@steempytutorials/integrate-steemconnect-v2-user-authentication-into-any-wordpress-website","https://steemit.com/utopian-io/@steempytutorials/integrate-steemconnect-v2-user-authorisation-into-any-wordpress-website"],"app":"steemit/0.1","format":"markdown"}
created2018-08-01 04:40:12
last_update2018-08-01 04:43:51
depth0
children4
last_payout2018-08-08 04:40:12
cashout_time1969-12-31 23:59:59
total_payout_value36.386 HBD
curator_payout_value11.312 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length7,631
author_reputation31,094,047,689,691
root_title"How To Use Python To Interact With Steemconnect's Access Tokens, Refresh Tokens And Perform Voting"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id66,715,800
net_rshares28,215,325,008,830
author_curate_reward""
vote details (55)
@gregjava ·
Exactly what I needed to play with right now. Thanks a lot for this.

However, can we get steemconnect and js version of this (if there is)? That will be also interesting to read (maybe even more interesting).
πŸ‘  
properties (23)
authorgregjava
permlinkre-steempytutorials-how-to-use-python-to-interact-with-steemconnect-s-access-tokens-refresh-tokens-and-perform-voting-20180801t050042374z
categoryutopian-io
json_metadata{"tags":["utopian-io"],"app":"steemit/0.1"}
created2018-08-01 05:00:45
last_update2018-08-01 05:00:45
depth1
children1
last_payout2018-08-08 05:00:45
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_length209
author_reputation407,441,374,496
root_title"How To Use Python To Interact With Steemconnect's Access Tokens, Refresh Tokens And Perform Voting"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id66,717,250
net_rshares11,179,601,772
author_curate_reward""
vote details (1)
@steempytutorials · (edited)
You can look around, maybe somebody else hopped on that bandwagon. I barely know js myself so I cannot help you with that. However, the idea stays the same, just different syntax.
properties (22)
authorsteempytutorials
permlinkre-gregjava-re-steempytutorials-how-to-use-python-to-interact-with-steemconnect-s-access-tokens-refresh-tokens-and-perform-voting-20180801t051329172z
categoryutopian-io
json_metadata{"tags":["utopian-io"],"app":"steemit/0.1"}
created2018-08-01 05:13:30
last_update2018-08-01 05:48:06
depth2
children0
last_payout2018-08-08 05:13:30
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_length179
author_reputation31,094,047,689,691
root_title"How To Use Python To Interact With Steemconnect's Access Tokens, Refresh Tokens And Perform Voting"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id66,718,237
net_rshares0
@portugalcoin ·
$0.03
Thank you for your contribution.

- As always an interesting tutorial. Thank you and good work.

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/11334113).

---- 
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-how-to-use-python-to-interact-with-steemconnect-s-access-tokens-refresh-tokens-and-perform-voting-20180801t211648217z
categoryutopian-io
json_metadata{"tags":["utopian-io"],"links":["https://join.utopian.io/guidelines","https://review.utopian.io/result/8/11334113","https://support.utopian.io/","https://discord.gg/uTyJkNm","https://join.utopian.io/"],"app":"steemit/0.1"}
created2018-08-01 21:16:48
last_update2018-08-01 21:16:48
depth1
children0
last_payout2018-08-08 21:16:48
cashout_time1969-12-31 23:59:59
total_payout_value0.022 HBD
curator_payout_value0.005 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length587
author_reputation599,460,589,822,571
root_title"How To Use Python To Interact With Steemconnect's Access Tokens, Refresh Tokens And Perform Voting"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id66,803,844
net_rshares17,357,960,160
author_curate_reward""
vote details (2)
@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 (22)
authorutopian-io
permlinkre-how-to-use-python-to-interact-with-steemconnect-s-access-tokens-refresh-tokens-and-perform-voting-20180805t180508z
categoryutopian-io
json_metadata"{"app": "beem/0.19.42"}"
created2018-08-05 18:05:09
last_update2018-08-05 18:05:09
depth1
children0
last_payout2018-08-12 18:05: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"How To Use Python To Interact With Steemconnect's Access Tokens, Refresh Tokens And Perform Voting"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id67,214,443
net_rshares0