Sunday, April 10, 2016

Seventh Week of LITG Program

The remaining tasks expected to be completed over the next few weeks are to code the API for returning the Quora user profile information and deploy it to Heroku. Prior to this, I was instructed by my mentor to acquire a fundamental understanding of how to work with Flask which is a Python web framework. It provides the developer with tools, libraries and technologies that allow to build a web application such as a blog, a wiki page or even a commercial website. Flask is a micro-framework. Micro-frameworks are normally frameworks with little to no dependencies to external libraries. The framework is light meaning that there are little dependencies to update. This also means that some times the developer has to do more work by himself. Flask has basically two dependencies namely, Werkzeug a WSGI utility library and jinja2 which is its template engine. 

I followed the documentation available at http://flask.pocoo.org/docs/0.10/quickstart/#http-methods to learn about Flask. I experimented with several special commands available with Flask. These exercises were pushed to the github repository at https://github.com/hansika/Flask_Learning

Using Flask in our Applications

First of all, if we want to use Flask in our web applications, we need to import Flask using the following statement.

from flask import Flask

The next task is to create an instance of the class Flask. The first argument is the name of the application's module or package. If it is a single module, the argument should be __name__. 

app = Flask(__name__)

To run the local server with our application we use the run() function as in the following statement. 

if __name__ == '__main__':
            app.run()

if __name__ == '__main__': makes sure the server only runs if the script is executed directly from the Python interpreter and not used as an imported module. Once these initial statements are included, we are good to go ahead and explore other functions of Flask.

Debug Mode

As changes are done to the code, we need to restart the server. But when debugging mode is on, the server will reload itself at code changes. This can be done in two ways.

app.debug = True                               or                                        app.run(debug=True)
app.run()

Routing

The route() decorator is used to bind a function to a URL. Following are few examples.

@app.route('/')
When running on localhost port 5000, this function can be called by using the URL http://127.0.0.1:5000/ 

@app.route('/hello')
This function can be called by using the URL http://127.0.0.1:5000/hello

Variable Rules

Variable rules are used to make certain parts of the URL dynamic. These special parts are denoted in the route as <variable_name>. These parts are passed to the function as keyword arguments. An example is shown below. 

@app.route('/user/<username>')

Optionally a converter can be used by specifying a rule with<converter:variable_name> as in the following example.

@app.route('/post/<int:post_id>')

Redirection Behavior

Consider the following example.

@app.route('/projects/')

Here, the URL with a trailing slash is similar to a folder on a file system. When we try to access it without the trailing slash, Flask will redirect it to the URL with the trailing slash. 

@app.route('/about')

In this example, there is no trailing slash. This is similar to the pathname of a file on UNIX-like systems. When you try to access this URL with the trailing slash, it produces a 404 “Not Found” error.

URL Building

To build a URL to a specific function we can use the url_for() function. It accepts the name of the function as first argument and a number of keyword arguments, each corresponding to the variable part of the URL rule. Unknown variable parts are appended to the URL as query parameters. Building a URL in this manner would be more beneficial than hard coding it especially when we want to change these URLs. We can then change these URLs in one go without having to remember to change URLs all over the place. Two examples are shown below.

url_for('login', next='/') - 'next' appended as a query parameter.
url_for('profile', username='John Doe') – username sent to the dynamic part of the URL.

Static Files

Dynamic web applications also need static files such as JavaScript files and CSS files. During development Flask can serve these static files as well. All we have to do is to create a folder called static in the package or next to the module and it will be available at '/static' on the application.

To generate URLs for static files, we need to use the special 'static' endpoint name.

url_for('static', filename='style.css')

The file has to be stored on the filesystem as static/style.css. When running on localhost this CSS file can be accessed via the URL http://127.0.0.1:5000/static/style.css

Rendering Templates

To render a HTML template, render_template() method can be used. For that we need to provide the name of the template and the variables that we have to pass to the template engine as keyword arguments. Shown below is one example of this. 

def hello(name=None):
        return render_template('hello.html', name=name)

Flask looks for templates in the templates folder. Therefore this templates folder should either be next to your module or else if it is a package, this folder should be inside the package.

The Request Object

For a request object the route decorator looks like shown below. 

@app.route('/login', methods=['POST', 'GET'])

The current request method is available by using the 'method' attribute. For example we can check if the method is is POST method by using the following statement.

if request.method == 'POST':

Furthermore, form data(data transmitted in a POST or PUT request) can be accessed using the form attribute. An example is shown below. 

if valid_login(request.form['username'], request.form['password']):

Horoscope-API 

After obtaining a basic knowledge about Flask, I learned about a sample REST API developed by my mentor. This API namely the Horoscope-API deployed at Heroku has been developed using Flask. It uses the horoscope package developed to fetch and parse data from GaneshaSpeaks. This API has methods to return Today's horoscope, Weekly horoscope, Monthly horoscope and Yearly horoscope. Also there is a method to know more about a given sunsign.

GET requests have been used for all the methods in the application. Shown below is the route decorator for the index_route function which returns basic details of the project and the author such as the author name, author URL, project name, project URL etc. 

@app.route('/', methods=['GET']) 

These details are returned as a json object. For that the jsonify() method of Flask has been used. jsonify method creates a response with the JSON representation of the given arguments. The arguments to this method can be any one of the following three forms. 

jsonify(**kwarg)

jsonify(mapping, **kwarg)

jsonify(iterable, **kwarg)

mapping is a positional argument. It actually takes the form of a dictionary having key-value pairs. The key becomes the key in the JSON object and the value becomes the corresponding value. **kwarg denotes a set of keyword arguments. When used with keyword arguments, the argument name becomes the key in the JSON object and the argument value becomes the corresponding value. This method can also accept a positional argument which is an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the JSON object, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the JSON object. Following is an example JSON response returned when using keyword arguments. 

return jsonify(username=g.user.username, email=g.user.email, id=g.user.id)

This returns the following JSON response. 

{
"username": "admin",
"email": "admin@localhost",
"id": 42
}

Horoscope-API uses the first two forms of arguments for the jsonify method. index_route method uses mapping object type positional argument and all the other methods use keyword arguments to the jsonify method.

Another special method used by the Horoscope-API is the dict method. This accepts the same set of arguments as mentioned above for the jsonify method. The task of this method is to return a new dictionary from the arguments passed to it. If no positional argument is given, an empty dictionary is created. The methods of the horoscope package return their results embedded in Python dictionary objects. Horoscope-API creates new dictionaries from these dictionary objects by using them as mapping object arguments to the dict method. Shown below is an example of two ways of using the dict method. Both the ways return the dictionary {"one": 1, "two": 2, "three": 3}.

a = dict(one=1, two=2, three=3)
b = {'one': 1, 'two': 2, 'three': 3}

With the knowledge gained regarding the Flask web framework and the Horoscope-API I will be starting to code the API to return the Quora user profile information over the next week.

No comments:

Post a Comment