Creating the application routes

Now we can start creating the routes. First, we are going to add the root route:

@app.route('/')
def home():

config = read_config()

get_oauth_token(config)

url = f'{config.authorize_url}?oauth_token=
{req_token.oauth_token}'

return render_template('index.html', link=url)

We read the configuration file and pass it the get_oauth_token function. This function will populate the global variable req_token with the oauth_token value; we need this token to start the authorization process. Then we build the authorization URL with the values of authorize_url obtained from the configuration file and the OAuth request token.

Lastly, we use the render_template to render the index.html template that we created and we also pass to the function a second argument, which is the context. In this case, we are creating an item called link with the value set to url. If you remember the index.html template, there is an "{{url}}" placeholder. This placeholder will be replaced by the value that we assigned to link in the render_template function.

By default, Flask uses Jinja2 as a template engine but that can be changed to the engine of your preference; we are not going into the details of how to do this in this book because it is beyond our scope.

The last route that we are going to add is the /callback route and that will be the route that will be called by Twitter after the authorization:

@app.route('/callback')
def callback():

global req_token
global consumer

config = read_config()

oauth_verifier = request.args.get('oauth_verifier', '')

token = oauth.Token(req_token.oauth_token,
req_token.oauth_token_secret)

token.set_verifier(oauth_verifier)

client = oauth.Client(consumer, token)

resp, content = client.request(config.access_token_url, 'POST')
access_token = dict(parse_qsl(content.decode('utf-8')))

with open('.twitterauth', 'w') as req_auth:
file_content = yaml.dump(access_token,
default_flow_style=False)
req_auth.write(file_content)

return 'All set! You can close the browser window and stop the
server.'

The implementation of the callback route starts off by using global statements so we can use the global variables req_token and consumer.

Now we get to the interesting part. After the authorization, Twitter will return an outh_verifier so we get it from the request arguments and set it to the variable oauth_verifier; we create a Token instance using the oauth_token and oauth_token_secret that we obtained in the first part of our authorization process.

And we set the oauth_verifier in the Token object and finally create a new client that we are going to use to perform a new request with.

We decode the data received from the request and add it to the access token variable and, to wrap things up, we write the content of access_token to a file .twitterauth in the twittervotes directory. This file is also in YAML format so we are going to add another model and one more function in the config.py file to read the new settings.

Note that this process needs to be done just once. That is the reason that we store the data in the .twitterauth file. Further requests need only to use the data contained in this file.

If you check the contents of the .twitterauth file, you should have something similar to the following:

oauth_token: 31******95-**************************rt*****io
oauth_token_secret: NZH***************************************ze8v
screen_name: the8bitcoder
user_id: '31******95'
x_auth_expires: '0'

To finish the Flask application, we need to add the following code at the end of the file:

if __name__ == '__main__':
app.run(host='localhost', port=3000)

Let's add a new model to the models.py file in twittervotes/core/models/ with the following content:

RequestAuth = namedtuple('RequestAuth', ['oauth_token',
'oauth_token_secret',
'user_id',
'screen_name',
'x_auth_expires', ])

Great! One more thing—we need to import the new model in the __init__.py file in the twittervotes/core/models directory:

from .models import RequestAuth

Also, let's add a function to read the .twittervotes file in config.py in twittervotes/core. First, we need to import the RequestAuthnamedtuple that we just created:

from .models import RequestAuth

Then we create a function called read_reqauth shown as follows:

def read_reqauth():
try:
return _read_yaml_file('.twitterauth', RequestAuth)
except IOError as e:
print(('It seems like you have not authorized the
application.\n'
'In order to use your twitter data, please run the '
'auth.py first.'))

This function is very straightforward: we just call the _read_yaml_file, passing as arguments the .twitterauth file and the new namedtuple, RequestAuth, that we just created. Again, if some error occurs, we raise an exception and show a help message.

Now we can try the authentication. In the twittervotes directory, execute the script twitter_auth.py. You should see the following output:

Great! The server is up and running so we can open a browser and go to http://localhost:3000. You should see a very simple page with a link to perform the authentication:

If you inspect the link with the browser development tools, you will see that the link is pointing to the authorize endpoint and it is passing the oauth_token that we created:

Go ahead and click on the link and you will be sent to the authorization page:

If you click on the Authorize app button, you will be redirected back to localhost and a success message will be displayed:

If you pay attention to the URL Twitter has sent back to us, you will find some information. The important point here is the oauth_verifier that we will set to the request token and we perform one last request to get the access token. Now you can close the browser, stop the Flask app, and see the results in the file .twitterauth in the twittervotes directory:

oauth_token: 31*******5-KNAbN***********************K40
oauth_token_secret: d**************************************Y3
screen_name: the8bitcoder
user_id: '31******95'
x_auth_expires: '0'

Now, all the functionality that we implemented here is very useful if other users are going to use our application; however, there's an easier way to obtain the access token if you are authorizing your own Twitter app. Let's have a look at how that is done.

Go back to the Twitter application settings in https://apps.twitter.com/; select the Keys and Access Tokens tab and scroll all the way down. If you have already authorized this application, you will see the same information we have now in the file .twitterauth but if you haven't authorized the application yet, you will see a Your Access Token section looking like the following:

If you click on Create my access token, Twitter will generate the access token for you:

After the access token is created, you can just copy the data into the .twitterauth file.