Hardware and software Environment

  • windows 10 64bit
  • Anaconda3 with python 3.7
  • Pycharm 2020.1.2
  • Flask 1.1.2
  • Flask – restful 0.3.8

RESTful-API

Introduction to the

In flask routing, app.route can be used to specify HTTP request methods (GET, POST, PUT, DELETE, etc.), and different business logic can be executed according to different request methods in request functions. Now you have a simple Restful request. But there’s a better way to do this in Flask, and that’s the Flask-restful extension.

According to the RESTful architecture, meta-operations on data, namely CRUD(adding, deleting, and modifying data), correspond to HTTP methods. GET is used to obtain resources, POST is used to create resources (or update resources), PUT is used to update resources, and DELETE is used to DELETE resources. In this way, data operation interfaces are unified. Only through HTTP method, you can add, delete, check and change the data.

Install the flask – restful

General operation, via PIP installation

pip install flask-restful
Copy the code

Flask-restful Basic use

Once the plug-in is installed, you can import the module, as shown in the following example

from flask import Flask, jsonify
from flask_restful import Api, Resource, reqparse

USERS = [
    {"name": "zhangsan"},
    {"name": "lisi"},
    {"name": "wangwu"},
    {"name": "zhaoliu"}]class Users(Resource) :
    def get(self) :
        return jsonify(USERS)

    def post(self) :
        args = reqparse.RequestParser() \
            .add_argument('name'.type=str, location='json', required=True.help="Name cannot be empty.") \
            .parse_args()

        if args['name'] not in USERS:
            USERS.append({"name": args['name']})

        return jsonify(USERS)

    def delete(self) :
        USERS = []
        return jsonify(USERS)


app = Flask(__name__)
api = Api(app, default_mediatype="application/json")

api.add_resource(Users, '/users')

app.run(host='0.0.0.0', port=5001, use_reloader=True)
Copy the code

Flask-restful extensions add routes through the api.add_resource() method. The first parameter to the method is a class name that inherits the Resource base class, whose member methods define the logic of different HTTP request methods. The second parameter defines the URL path. In the Users class, we implement get, POST, and DELETE methods respectively, corresponding to HTTP GET, POST, and DELETE requests.

Flask-restful also provides ArgParse, which makes it easy to validate data sent by clients in HTTP requests. This is a bit like a form validation method, which is very useful in real projects.

The program starts, we visit http://127.0.0.1:5001/users, GET request will give the content of the USERS, the USERS when they POST request to add a (if not) and return the USERS updated content. The DELETE request empties USERS and returns null.

On the client side, we use Postman to simulate requests

How do I GET parameters in the GET method

For each user name, we write a class, also derived from Resource, that takes the parameter userID in the GET method. For simplicity, userID is defined as the index of the user name in the USERS list

class UserId(Resource) :
    def get(self, userid) :
        return jsonify(
            {"name": USERS[int(userid)].get("name")}
        )

api.add_resource(UserId, '/user/<userid>')
Copy the code

In the api.add_resource() method, the

in the second parameter /user/

is the parameter passed by the user, which is written exactly the same as the flask route. After the start process, visit http://127.0.0.1:5001/user/0 for is the first user information USERS list

Add logs in flask-restful

Flask Tutorial (11) The log has already mentioned how to use logging in Flask. In flask-restful, logger can be used in a more elegant way, for example

import logging.config
from flask import Flask, jsonify
from flask_restful import Api, Resource, reqparse

logging.config.dictConfig(
    {
        "version": 1."disable_existing_loggers": False."formatters": {
            "simple": {"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"}},"handlers": {
            "console": {
                "class": "logging.StreamHandler"."level": "DEBUG"."formatter": "simple"."stream": "ext://sys.stdout",},"info_file_handler": {
                "class": "logging.handlers.RotatingFileHandler"."level": "INFO"."formatter": "simple"."filename": "info.log"."maxBytes": 10485760."backupCount": 50."encoding": "utf8",},"error_file_handler": {
                "class": "logging.handlers.RotatingFileHandler"."level": "ERROR"."formatter": "simple"."filename": "errors.log"."maxBytes": 10485760."backupCount": 20."encoding": "utf8",},"debug_file_handler": {
                "class": "logging.handlers.RotatingFileHandler"."level": "DEBUG"."formatter": "simple"."filename": "debug.log"."maxBytes": 10485760."backupCount": 50."encoding": "utf8",}},"loggers": {
            "my_module": {"level": "ERROR"."handlers": ["console"]."propagate": "no"}},"root": {
            "level": "DEBUG"."handlers": ["error_file_handler"."debug_file_handler"],
        },
    }
)

USERS = [
    {"name": "zhangsan"},
    {"name": "lisi"},
    {"name": "wangwu"},
    {"name": "zhaoliu"}]class Users(Resource) :
    def __init__(self, **kargs) :
        self.logger = kargs.get('logger')

    def get(self) :
        return jsonify(USERS)

    def post(self) :
        args = reqparse.RequestParser() \
            .add_argument('name'.type=str, location='json', required=True.help="Name cannot be empty.") \
            .parse_args()

        self.logger.debug(args)

        if args['name'] not in USERS:
            USERS.append({"name": args['name']})

        return jsonify(USERS)

    def delete(self) :
        USERS = []
        return jsonify(USERS)


app = Flask(__name__)
api = Api(app, default_mediatype="application/json")

api.add_resource(Users, '/users', resource_class_kwargs={
    "logger": logging.getLogger('/Users')
})

app.run(host='0.0.0.0', port=5001, use_reloader=True)
Copy the code

The dictConfig is used last time. The main difference is that in the api.add_resource() method, the parameter resource_class_kwargs is used, and then the __init__ constructor in the Resource subclass retrits the logger, This can then be used in individual processing methods. Using postman again to make a POST request, you can see debug.log looks like this