Detailed explanation of the flash framework of python

Posted by Muggin on Thu, 11 Jun 2020 06:29:20 +0200

Flask itself is equivalent to a kernel. Almost all other functions need to be extended, which needs to be implemented by third-party extensions. For example, you can use flask extensions to add ORM, form verification tools, file upload, authentication, etc. There is no default database for flask. You can choose MySQL or NoSQL.

Its WSGI toolkit uses Werkzeug (routing module), and its template engine uses Jinja2. These two are also the core of the Flask framework.

Flask common expansion packs:

  • Flask Sqlalchemy: operate database;
  • Flask script: insert script;
  • Flask migrate: manage the migration database;
  • Flask Session: specify the Session storage mode;
  • Flask WTF: form;
  • Flask mail: mail;
  • Flask bable: provide internationalization and localization support, translation;
  • Flask login: authentication user status;
  • Flask openid: authentication;
  • Flask restful: a tool for developing rest APIs;
  • Flask bootstrap: integrated front-end Twitter Bootstrap framework;
  • Flask moment: localization date and time;
  • Flask admin: a framework of simple and extensible management interface
  1. Chinese documents( http://docs.jinkan.org/docs/flask/)
  2. English documents( http://flask.pocoo.org/docs/0.11/)
  3. Extended list: http://flask.pocoo.org/extensions/
#install
pip install flask==0.10.1      # Followed by version number

1. New file helloworld.py

# Import the Flask class
from flask import Flask
# The Flask function takes a parameter__ name__ , which points to the package where the program is located

app = Flask(__name__)

# The purpose of the decorator is to map the route to the view function index
@app.route('/')
def index():
    return 'Hello World'

# Start the WEB server with the run method of the Flask application instance

if __name__ == '__main__':
    app.run()    # You can specify the IP address and port of the running host and whether to turn on the debugging mode
    # app.run(host="0.0.0.0", port=8888, debug = True)

2. Related configuration parameters

When creating a Flask program instance, the package (module) specified by the current Flask program needs to be passed in by default

app = Flask(__name__)

  • import_name
    • Package (module) of the Flask program, transmitting__ name__ You can
    • It determines the path that Flask looks up when it accesses a static file
  • static_path
    • Static file access path (not recommended, use static_url_path instead)
  • static_url_path
    • Static file access path, can not be transferred, default is: / + static_folder
  • static_folder
    • The folder of static file storage, which can not be transferred, is static by default
  • template_folder
    • The folder where template files are stored. It can not be transferred. The default is templates

3. Load configuration file

When the Flask program is running, you can set the relevant configuration for Flask, such as: configure the Debug mode, configure the database connection address, and so on. There are three ways to set the Flask configuration:

  • Load from configuration object (common)
    • app.config.form_object()
  • Load from configuration file
    • app.config.form_pyfile()
    Load from environment variable (not commonly used)
    • app.config.from_envvar()

3.1 configuration object loading

# Configuration object, which defines a series of configurations to be added to the APP
class Config(object):
    DEBUG = True


# Create an object of the Flask class, pointing to the name of the package where the program is located
app = Flask(__name__)

# Load configuration from configuration object
app.config.from_object(Config)

3.2 profile loading

Create profile config.ini , add configuration to profile

Format eg: DEBUG = True

# Create an object of the Flask class, pointing to the name of the package where the program is located
app = Flask(__name__)

# Load configuration from configuration file
app.config.from_pyfile('config.ini')

3.4 read configuration

  • app.config.get()
  • Using current in view functions_ app.config.get ()

Note: some commonly used configurations are set as properties of application objects by the Flask application, and some configurations can also be set / obtained directly through properties: app.debug = True

4 route definition

4.1 designated routing address

# Specify the access path as hello
@app.route('/hello')
def demo1():
    return 'hello world'

4.2 routing parameters

# Routing parameters
@app.route('/user/<user_id>')
def user_info(user_id):
    return 'hello %s' % user_id

# The parameters passed by route are treated as string by default, and the type of parameters can also be specified

# Routing parameters
@app.route('/user/<int:user_id>')
def user_info(user_id):
    return 'hello %d' % user_id

4.3 specify request method

In Flask, define a route. The default request mode is:

  • GET
  • Options (included)
  • Head (own)
@app.route('/login', methods=['GET', 'POST'])  # Support GET and POST, and support OPTIONS and HEAD
def login():
    # Get the request mode directly from the request and return
    return request.method

4.4 regular matching route

In web development, there may be scenarios that restrict users' access rules. At this time, regular matching is needed to restrict the request parameters according to their own rules before access

The specific implementation steps are as follows:

  • Import converter base class: in Flask, the matching rules of all routes are recorded with converter objects
  • Custom converter: custom class inherits from converter base class
  • Add converter to default converter dictionary
  • Using custom converter to implement custom matching rules

(1) Import converter base class

from werkzeug.routing import BaseConverter

(2) Custom converter

from flask import Flask, redirect, url_for
from werkzeug.routing import BaseConverter


class RegexConverter(BaseConverter):
    def __init__(self, url_name, *args):
        super().__init__(url_name)
        # Save the first parameter accepted as a matching rule
        self.regex = args[0]


class ListConverter(BaseConverter):
    regex = '(\\d+,?)+\\d$'

    def to_python(self, value):
        return value.split(",")

    def to_url(self, value):
        return ",".join(str(i) for i in value)

(3) Add the converter to the default converter dictionary, and specify the converter name as: re

app = Flask(__name__)
# Add a custom converter to the converter dictionary and specify the converter name to use as: re
app.url_map.converters["re"] = RegexConverter
# Add a custom converter to the converter dictionary and specify the converter name to use as: list
app.url_map.converters["list"] = ListConverter

(4) Using converter to implement custom matching rules

@app.route("/demo/<re('\d{6}'):use_name>")
def demo1(use_name):
    return "User name is %s" % use_name


@app.route("/users/<list:user_list>")
def demo11(user_list):
    return "The user list is %s" % user_list

# Converter of the system
DEFAULT_CONVERTERS = {
    'default':          UnicodeConverter,
    'string':           UnicodeConverter,
    'any':              AnyConverter,
    'path':             PathConverter,
    'int':              IntegerConverter,
    'float':            FloatConverter,
    'uuid':             UUIDConverter,
}
# The specific usage of the converter provided by the system is written in the comment code of each converter. Please pay attention to the initialization parameters of each converter

Two other functions of the custom converter are implemented:

After inheriting from the custom converter, you can also implement to_python and to_ The URL functions further process the matching parameters:

  • to_python:
    • The value value in the function parameter represents the matched value, which can be output for viewing
    • After the matching is completed, the matching parameters are processed in the last step and then returned, for example: convert to the value of int type and then return:

class RegexConverter(BaseConverter):
    def __init__(self, url_map, *args):
        super(RegexConverter, self).__init__(url_map)
        # Save the first parameter accepted as a matching rule
        self.regex = args[0]

    def to_python(self, value):
        return int(value)   # In the view function, you can view the type of parameter, which has changed from the default str to the value of int

  •   to_url:
    • Using url_ When for gets the url corresponding to the view function, this method will be called to_ View function parameters passed in after for for for further processing
    • For details, see Flask's app.py Example code written in: ListConverter

5. Simple view

5.1 return json

When using Flask to return JSON data to the client, you can directly use jsonify to generate a JSON response

#Return to JSON
@app.route('/demo')
def demo():
    json_dict = {
        "user_id": 10,
        "user_name": "laowang"
    }
    return jsonify(json_dict)
Note: not recommended json.dumps  Convert to JSON string and return directly, because the returned data should conform to the HTTP protocol specification. If it is JSON, you need to specify content-type:application/json

5.2 redirection

(1) Redirect to Baidu

# redirect
@app.route('/demo')
def demo():
    return redirect('http://www.baidu.com')

(2) Redirect to view function written by yourself

  • Directly fill in your own url path
  • Use url_for generates the url corresponding to the specified view function

@app.route('/demo1')
def demo1():
    return 'demo1'

# Redirect with url_for generates the url corresponding to demo1
@app.route('/demo2')
def demo2():
    return redirect(url_for('demo1'))

(3) Redirect to view function with parameters

# Routing parameters
@app.route('/user/<int:user_id>')
def user_info(user_id):
    return 'hello %d' % user_id

# Redirect, at URL_ Parameters passed in for
@app.route('/demo5')
def demo5():
    # Use url_for generates the url corresponding to the specified view function
    return redirect(url_for('user_info', user_id=100))

5.3 custom status code

Custom status code not conforming to http protocol

@app.route('/demo')
def demo():
    return 'Status code is 666', 666

6. Exception capture

6.1 HTTP actively throws an exception

  • abort method
    • Throw an HTTPException for a given status code or specify a response, for example, if you want to terminate the request with an exception not found on a page, you can call abort(404).
  • Parameters:
    • Code - error status code for HTTP
# abort(404)
# If the status code is thrown, only the error status code of HTTP protocol can be thrown
abort(500)

6.2 error capture

  • errorhandler decorator
    • Register an error handler, when the program throws the specified error status code, it will call the method decorated by the decorator
  • Parameters:
    • code_or_exception - HTTP error status code or specified exception

For example, the error with unified processing status code of 500 gives user-friendly prompt:

# Handle all exceptions of type 500

@app.errorhandler(500)
def internal_server_error(e):
    return 'Server moved'


# Handling specific exception items
@app.errorhandler(ZeroDivisionError)
def zero_division_error(e):
    return 'Divisor cannot be 0'

7. Hook function

During the interaction between the client and the server, some preparatory work or final work needs to be handled, such as:

  • Establish a database connection at the beginning of the request;
  • At the beginning of the request, verify the permissions according to the requirements;
  • Specify the interaction format of the data at the end of the request;

In order to avoid writing duplicate code for each view function, Flask provides the function of a common facility, that is, request hook.

Request hooks are implemented in the form of decorators. Flask supports the following four types of request hooks:

  • before_first_request
    • Execute before processing the first request
  • before_request
    • Execute before each request
    • If a response is returned in a decorated function, the view function is no longer called
  • after_request
    • If no error is thrown, execute after each request
    • Accept a parameter: the response from the view function
    • In this function, you can modify the response value in the last step before returning
    • The response in the parameter needs to be returned in this parameter
  • teardown_request:
    • Execute after each request
    • Accept a parameter: error message, if there is a related error thrown

from flask import Flask
from flask import abort

app = Flask(__name__)


# Invoking before the first request, you can do some initialization inside this method.
@app.before_first_request
def before_first_request():
    print("before_first_request")


# Before each request is called, there is a request at that time, and the request can be checked in this method.
# If the requested verification is not successful, you can respond directly in this method. After return ing directly, the view function will not be executed
@app.before_request
def before_request():
    print("before_request")
    # if request does not meet the criteria:
    #     return "laowang"


# After the view function is executed, it will be called, and the response generated by the view function will be passed in. In this method, the response can be processed uniformly in the last step
@app.after_request
def after_request(response):
    print("after_request")
    response.headers["Content-Type"] = "application/json"
    return response


# Please call after each request and accept a parameter, which is the error message of the server
@app.teardown_request
def teardown_request(e):
    print("teardown_request")


@app.route('/')
def index():
    return 'index'

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

results of enforcement

Print on 1st request:
before_first_request
before_request
after_request
teardown_request

Print on 2nd request:
before_request
after_request
teardown_request

8. Request request parameters

Request is the request object representing the current request in the flash as the request context variable (understood as a global variable, which can be directly used in the view function to get the current request)

Common properties:

attribute explain type
data Record the requested data and convert to a string *
form Record form data in request MultiDict
args Record query parameters in request MultiDict
cookies Record cookie information in the request Dict
headers Record header in request EnvironHeaders
method Record the HTTP method used by the request GET/POST
url Record the URL address of the request string
files Record files requested to be uploaded *

 

 

 

 

 

 

 

 

# Get the uploaded image and save it locally
@app.route('/', methods=['POST'])
def index():
    pic = request.files.get('pic')
    pic.save('./static/aaa.png')
    return 'index'

9. Flag context parameter

Context: equivalent to a container, which holds some information during the operation of the Flask program.

There are two contexts in Flask, request context and application context

  1. application refers to when you call app = Flask(__name__ )The created object app;

  2. Request refers to every http request, WSGI server (such as gunicorn) calls Flask__ call__ () after that, the request object created inside the flag object;

  3. Application represents the application itself used to respond to WSGI requests, and request represents each http request;

  4. The life cycle of an application is greater than request. During the lifetime of an application, there may be multiple http requests, so there will be multiple requests

The source code knows how to implement these two kinds of context s with flask:

# Code excerpt from flash 0.5 ctx.py Document, partially deleted
class _RequestContext(object):
    
    def __init__(self, app, environ):
        self.app = app
        self.request = app.request_class(environ)
        self.session = app.open_session(self.request)
        self.g = _RequestGlobals()

# Use of flash_ The code of RequestContext is as follows:
class Flask(object):

    def request_context(self, environ):
        return _RequestContext(self, environ)

In the flask class, this request is called every time a request is made_ Context function. This function creates a_ RequestContext object. When this object is created, it passes in the flag instance itself as an argument_ RequestContext itself, therefore, self.app = Flask().

So, although each http request creates a_ The RequestContext object, however, will pass the same flag object into the app member variable of the object each time it is created, so that:

Created by a request that the same flag object responds to_ The app member variables of the RequestContext object share the same application

By creating in a Flask object_ RequestContext object and pass in the flag itself as a parameter_ The method of request context object realizes the purpose that multiple request contexts correspond to one application context.   

(1) Request context

The request context objects are: request, session

    • request
      • Encapsulates the content of the HTTP request for the HTTP request. Example: user= request.args.get ('user '), which gets the parameters of the get request.
    • session
      • It is used to record the information in the request session, aiming at the user information. Example: session ['name ']= user.id , can record user information. You can also use session.get('name ') gets user information.

(2) Application context

The application context objects are: current_app,g

  ①current_app

Application context, used to store variables in the application, can be accessed through current_app.name Print the name of the current app, or at current_ Some variables are stored in app, such as:

  • Which file is the application startup script and which parameters are specified at startup
  • Which configuration files are loaded and which configurations are imported
  • Which database is connected
  • What are the public tool classes and constants
  • On which machine does the application run, how much IP and memory
current_app.name
current_app.test_value='value'

② g variable

As a temporary global variable of the flash program, g acts as an intermediate medium. We can pass some data through it. g stores the global variables of the current request. Different requests will have different global variables, which are different through different thread IDs

g.name='zhangsan'
  • Request context: saves data for client server interaction
  • Application context: some configuration information saved during the operation of the flash application, such as program name, database connection, application information, etc

10.cookie use

Cookie: refers to the data (usually encrypted) stored locally by some websites in order to identify users and track their sessions.

  • Plural Cookies.
  • The cookie is generated by the server and sent to the client browser. The browser will save the key/value of the cookie. The cookie will be sent to the server the next time the same website is requested (provided that the browser is set to enable cookie).
  • The key/value of the Cookie can be defined by the server itself.

# Set cookie s
# When the browser requests a website, all Cookie information under the website will be submitted to the server, so Cookie information can be read in the request

from flask imoprt Flask, make_response
@app.route('/cookie')
def set_cookie():
    resp = make_response('this is to set cookie')
    resp.set_cookie('username', 'zhangsan')
    resp.set_cookie("pwd", "12321")     
    return resp

# Set expiration time
@app.route('/cookie')
def set_cookie():
    response = make_response('hello world')
    response.set_cookie('username', 'zhangsan', max_age=3600)  # Expires 3600 seconds
    return response


# Get cookie s
from flask import Flask, request

@app.route('/request')
def resp_cookie():
    resp = request.cookies.get('username')
    return resp

# delete cookie 
@app.route("/logout")
def logout():
    resp = make_response("success")
    resp.delete_cookie("username")
    resp.delete_cookie("pwd")
    return resp

11. Session use

# session data acquisition
# session: request context object, used to process some data content in http request

# Set secret_key
# Function: set a secret_key value, used as various HASH
app.secret_key = 'python'
# For security reasons, this key is not recommended to be stored in the program. The best way is to store it in your system environment variable through os.getenv(key, default=None) get
    

#Set session and redirect to the index function to get session
@app.route("/login")
def login():
    session["username"] = 'zhangsan'
    session['password'] = "1234321"
    return redirect(url_for("index"))


# Get session
@app.route("/")
def index():
    username = session.get("username")
    password = session.get("password")
    return "The world is so beautiful%s======%s" % (username, password)


# Delete the session and redirect to the index function to get the session
@app.route("/logout")
def logout():
    session.pop("username")
    session.pop("password")
    return redirect(url_for("index"))

12. Blueprint

Blueprint is a container for storing operation methods. These operations can be called after the blueprint is registered in an application. Flask can organize URL s and process requests through blueprint.

Flask uses Blueprint to modularize the application. In flask, Blueprint has the following attributes:

  • An application can have multiple blueprints
  • You can register a Blueprint to any unused URL, such as' / ',' / sample ', or subdomain name
  • In an application, a module can be registered multiple times
  • Blueprint can have its own template, static file or other general operation methods. It is not necessary to implement the views and functions of the application
  • When an application is initialized, you should register the Blueprint you need to use

But a Blueprint is not a complete application, it can not run independently of the application, but must be registered in an application.

Blueprint / blueprint object is similar to an application / flag object. The biggest difference is that a blueprint object can not run independently. It must be registered on an application object to take effect

Using blueprints can be divided into three steps

  • 1. Create a blueprint object
admin=Blueprint('admin',__name__)
  • 2. Operate on the blueprint object, register the route, specify the static folder, and register the template filter
@admin.route('/admin')
def index():
    return 'admin_home'
  • 3. Register the blueprint object on the application object
app.register_blueprint(admin,url
_prefix='/admin')

When the application is started, you can access the view functions defined in the blueprint through / admin/admin /

operating mechanism

  • A blueprint is a set of operations that can be performed on an application object in the future. Registering a route is an operation
  • When the route decorator is called on the application object to register the route, this operation will modify the URL of the object_ Map routing table
  • However, the blueprint object does not have a routing table at all. When we call the route decorator on the blueprint object to register the route, it is only a list of deferred operation records defined_ An item was added to functions
  • When register of application object is executed_ When the blueprint () method is used, the application object will be defined from the blueprint object_ Each item in the functions list is taken out, and the anonymous function is executed with itself as a parameter, that is, the add of the application object is called_ url_ Rule () method, which will actually modify the routing table of the application object

url prefix of blueprint

  • When we register a blueprint on the application object, we can specify a url_prefix keyword parameter (this parameter defaults to /)
  • In the application of the final routing table URL_ In map, the route URLs registered on blueprints are automatically prefixed with this prefix, which can ensure that the same URL rules are used in multiple blueprints without eventually causing conflicts, as long as different blueprints are linked to different self paths when registering blueprints

  • url_for

url_for('admin.index') # /admin/admin / register the route of index function under admin   

Register static route

Unlike the application object, the route of the static directory is not registered by default when the blueprint object is created. We need to specify static when creating_ Folder parameter.

The following example shows the static in the directory where the blueprint is located_ Admin directory set to static directory

admin = Blueprint("admin",__name__,static_folder='static_admin')
app.register_blueprint(admin,url_prefix='/admin')

Now you can use / admin/static_admin / access static_ The static files in the admin directory customize the URL rules of the static Directory: static can be used when creating blueprint objects_ url_ Path to change the routing of the static directory. The following example will be static_ The route of the admin folder is set to / lib

admin = Blueprint("admin",__name__,static_folder='static_admin',static_url_path='/lib')
app.register_blueprint(admin,url_prefix='/admin')

Set template directory

The default template directory of the blueprint object is the template directory of the system. You can use template when creating the blueprint object_ Folder keyword parameter setting template directory

admin = Blueprint('admin',__name__,template_folder='my_templates')

Note: if in templates and my_ For files with the same name as templates, the system will give priority to the files in templates. Refer to the link: https://stackoverflow.com/questions/7974771/flask-blueprint-template-folder

13. Flask script extension

By using the Flask script extension, we can pass in parameters through the command line when the Flask server starts. Not just through app.run() method, for example, we can pass:

python  main.py  Runserver - host IP address - P port

# 1. Install the flask script extension
pip install flask-script


# 2. Integrated flask script
from flask import Flask
from flask_script import Manager

app = Flask(__name__)
# Associate the Manager class with the application instance
manager = Manager(app)

@app.route('/')
def index():
    return 'hello world'

if __name__ == "__main__":
    manager.run()

 

Topics: Session JSON Database pip