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