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 differentrequest
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 ofstatus
overloads the status code, andheaders
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 pageIn 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