Python101: 14. Introduction to Flask for Web Development

post thumb
Python
by Admin/ on 12 Jul 2021

Python101: 14. Introduction to Flask for Web Development


Web development is a must-have skill for programs nowadays, as most software is provided in web form, and you need to understand the concepts and features of web development in order to produce backend development or just frontend development.

Since Python is an interpreted scripting language, it’s perfect for Web development, and Python has hundreds of Web development frameworks and mature templating technology, making Web development as easy as possible. Today, we’ll borrow the Flask framework to quickly learn about Web development in Python.


Flask framework


Flask is designed to be easy to use and extend. It was originally intended to build a solid foundation for all kinds of complex web applications. Feel free to plug in any extensions. Flask is suitable for all kinds of projects. It is especially useful for prototyping.Flask relies on two external libraries: the Jinja2 template engine and the Werkzeug WSGI toolkit.

Flask is one of the most polished and feature-rich microframeworks. flask is still young, with a thriving community, first-class extensions and a beautiful API. flask has the advantages of fast templates, powerful WSGI features, full unit testability at the web application and library level, and extensive documentation.

The Flask framework was also chosen because it is easy to get started, has a simple structure, zero configuration, and is a great tool for learning Python web development.

Install Flask


Like the other modules, Flask is easy to install with the following package manager via pip

pip install flask

To check if the installation is correct, type python at the command line to enter command line mode. Introduce the flask module, enter

import flask

If there is no error alert, it means the installation is successful

Hello world


The following is the simplest web application you can write hello.py

from flask import Flask # Introduce the Flask module

app = Flask(__name__) # Create an application

@app.route('/')
def index(): # Define the root handler
    return '<h1>Hello World!</h1>'

if __name__ == '__main__':
    app.run() # Start the service

Open a terminal, jump to the folder where the hello.py file is located, enter python command line mode, and start the service

python hello.py

If they work together normally there will be feedback like the following

 * Serving Flask app "hello" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 Use a production WSGI server instead. * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Since the service is started by app.run(), there will be an error reminding you that you cannot deploy this web application in a production environment, so you can ignore it for now

At this point, open your browser and type 127.0.0.1:5000/ or localhost:5000/, and you will see the words Hello World!

Routing


Routing is a very important concept in web development, used to map different requests, to response processing methods, this method is called view function. For example, the Hello application just mapped the root request to the index handler.

Flask uses modifiers (similar to Java’s annotations) to establish route mapping relationships, and has seen the modifier app.rotue()

Simple Routing

For example, visit /hello

@app.route('/hello')
def hello():
    return 'Hello!'

Dynamic routing

For example, accessing /user/bob or /user/lily will map to the same view function

@app.route('/user/<name>')
def user(name):
    return '<h1>Hello, %s! </h1>' % name

The dynamic part of the dynamic domain name can be used as a parameter of the view function, which also supports multiple dynamic parameters, such as accessing /user/bob/23

@app.route('/user/<name>/<age>')
def user(name, age):
    return "<h1> Hello, %s, you're %s years old" % (name, age)

It is also possible to specify the data type of the dynamic part, such as

@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return 'Post %d' % post_id

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    # show the subpath after /path/
    return 'Subpath %s' % escape(subpath)

Supported Data Types

Type Description
string (default) Any text that does not contain a slash
int positive integer
float positive floating point
path is similar to string, but can contain slashes
uuid accepts the UUID string

Specify the HTTP method

HTTP protocol, supports a variety of HTTP methods, such as HEAD, OPTIONS, and the common GET, POST, etc. Flask automatically handles HEAD and OPTIONS, the default method accepted by the route is GET, if you want to match other request methods, you can specify in the methods parameter of the route method to specify

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return do_the_login()
    else:
        return show_the_login_form()

Composite Routing

You can also use multiple routing rules for a single view function, e.g. accessing /job/ and accessing /work/ has the same effect

@app.route('/job/')
@app.route('/work/')
def show_works():
    return 'This is works page'

A more complex example

@app.route('/users/', defaults={'page': 1})
@app.route('/users/page/<int:page>')
def show_users(page):
    pass

The above code means that the show_users view function handles access to either /user/ or /user/page/<pageindex>, and also provides a default value for /user/, i.e. accessing /user/ is equivalent to accessing /user/page/1

Request and Response


The Flask framework provides a request object request and a response object response that can be easily used in the view function.

Request

Flask wraps the HTTP request sent by the client into a request request object and temporarily makes request globally accessible using a context, so it can be used directly in the view.

Note: request is not really a global variable! Imagine a multi-threaded server where multiple threads are processing different requests from different clients at the same time, each thread will see a different request object.

Flask has two contexts, the program context and the request context, and the global variables corresponding to each are listed below:

Variable name Context type Remarks
current_app program_context Indicates the current instance of the running program
g program_context Used as a temporary storage object while the request is being processed, and will be reset for each request
request Request context The request object from the client
session The session information carried by the request

Before you can use the request object, you need to introduce the

from flash import request

The request object provides a rich set of properties and methods, as an example here. The current request method can be manipulated by using the method property, and form data (data transferred in a POST or PUT request) can be handled by using the form property. Here is an example of using the above two properties:

@app.route('/login', methods=['POST', 'GET'])
def login():
    error = None
    if request.method == 'POST':
        if valid_login(request.form['username'],
                       request.form['password']):
            return log_the_user_in(request.form['username'])
        else:
            error = 'Invalid username/password'
    # the code below is executed if the request method
    # was GET or the credentials were invalid
    return render_template('login.html', error=error)

Note: What happens when the key does not exist in the form property? A KeyError is raised. If this error is not handled, an HTTP 400 Bad Request error page will be displayed.

If you want to manipulate the parameters submitted in the URL (e.g. ?key=value) you can use the args property, e.g. : searchword = request.args.get('key', '')

Request hooks

Sometimes it can be useful to execute code before or after the request is processed. For example, at the beginning of a request, it may be necessary to create a database connection or authenticate the user who initiated the request. To avoid using duplicate code in every view function, Flask provides the ability to register generic functions that can be called before or after the request is distributed to the view function. Request hooks are implemented using modifiers. flask supports the following 4 types of hooks:

  • before_first_request: Register a function to be run before the first request is processed.
  • before_request: register a function to be run before each request.
  • after_request: Register a function to run after each request if no unhandled exceptions are thrown.
  • teardown_request: register a function to be run after each request even if there are unhandled exceptions thrown.

Example: On receiving the first request, print the sentence.

@app.before_first_request
def first_quest():
    print("run before first request")

Sharing data between request hook functions and view functions generally uses the context global variable g.. For example, the before_request handler may load the logged-in user from the database and save it to g.user. When the view function is subsequently called, the view function then uses g.user to get the user.

Response

A response is a response from the web server to a request, and in Flask, there are several forms of responses. The return value of a view function is automatically converted into a response object.

If the return value is a string, it is converted to a response object containing a string as the response body, a 200 OK error code, and a text/html type response object.

If the return value is a dictionary, then jsonify() is called to generate a response. The following are the rules for conversion.

  • If the view returns a response object, then it is returned directly.
  • If a string is returned, then a response object is generated for return based on the string and default parameters.
  • If a dictionary is returned, then call jsonify to create a response object.
  • If a tuple is returned, then the items in the tuple can provide additional information. The tuple must contain at least one item, and the item should consist of (response, status), (response, headers), or (response, status, headers). The value of status overloads the status code, and headers is a list or dictionary of additional header values.
  • If none of the above, then Flask assumes that the return value is a valid WSGI application and converts it to a response object.

In addition to that, you can also create responsive objects to do more personalized things with the make_response() function.

Before you can use make_response(), you need to introduce

from flask import make_response

Example.

  • The response has a tuple composition
@app.errorhandler(404)
def not_found(error):
    return render_template('error.html'), 404

The @app.errorhandler modifier maps a response code to a view function, in this case a 404 (page not found) code, into a personalized error page

In addition, render_template is a Flask template function, which is simply formatted as a dynamic html string, and the detailed usage of the template is described in the Templates section

  • Use make_response() to wrap the return expression, get the response object, modify it, and then return it:
@app.errorhandler(404)
def not_found(error):
    resp = make_response(render_template('error.html'), 404)
    resp.headers['X-Something'] = 'A value'
    return resp

Summary


This article provides a brief introduction to the basics of Python web development with the help of the Flask framework, which will hopefully help you get started quickly and get you started on the road to Python. Stay tuned for more on web development topics, templates, databases, and extensions!


Reference

comments powered by Disqus