Flask-restful is a Flask extension for quickly building REST apis.
The installation
pip install flask
pip install flask-restfulCopy the code
1 Hello World
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class HelloWorldResource(Resource):
def get(self):
return {'hello': 'world'}
def post(self):
return {'msg': 'post hello world'}
api.add_resource(HelloWorldResource, '/')
Start here is optional for Flask after 1.0
if __name__ == '__main__':
app.run(debug=True)Copy the code
Added: If it is after 1.0, it can be run through the Flask application terminal:
$ export FLASK_APP=helloworld # specifies the name of the program to run$flask run * Running on http://127.0.0.1:5000/Copy the code
It can also be run by changing the parameters of the PyCharm configuration runtime.
The effect of a GET request is as follows:
The effect of a POST request is as follows:
2 the view
2.1 the routing
Name the route using the endpoint parameter
api.add_resource(HelloWorldResource, '/', endpoint='HelloWorld')Copy the code
2.2 the blueprint
from flask import Flask, Blueprint
from flask_restful import Api, Resource
app = Flask(__name__)
user_bp = Blueprint('user', __name__)
user_api = Api(user_bp)
class UserProfileResource(Resource):
def get(self):
return {'msg': 'get user profile'}
user_api.add_resource(UserProfileResource, '/users/profile')
app.register_blueprint(user_bp)Copy the code
2.3 a decorator
Add the decorator using method_decorators
-
All methods in the class view add decorators
def decorator1(func):
def wrapper(*args, **kwargs):
print('decorator1')
return func(*args, **kwargs)
return wrapper
def decorator2(func):
def wrapper(*args, **kwargs):
print('decorator2')
return func(*args, **kwargs)
return wrapper
class DemoResource(Resource):
method_decorators = [decorator1, decorator2]
def get(self):
return {'msg': 'get view'}
def post(self):
return {'msg': 'post view'}Copy the code
-
Different methods in the class view add different decorators
class DemoResource(Resource):
method_decorators = {
'get': [decorator1, decorator2],
'post': [decorator1]
}
Use decorator1 decorator2
def get(self):
return {'msg': 'get view'}
Use the decorator1 decorator
def post(self):
return {'msg': 'post view'}
No decorators used
def put(self):
return {'msg': 'put view'}Copy the code
3 the request
Flask-restful provides the RequestParser class to help us validate and transform the request data.
from flask_restful import reqparse
parser = reqparse.RequestParser()
parser.add_argument('rate', type=int, help='Rate cannot be converted', location='args')
parser.add_argument('name')
args = parser.parse_args()Copy the code
3.1 Procedure:
-
Create a RequestParser object
-
Add parameter declarations to the RequestParser object that need to be validated or converted
-
Start the validation processing with the parse_args() method
-
You can operate according to dictionary operations or object properties when obtaining parameters from the validation results after validation
The args. Rate or the args ['rate']Copy the code
3.2 Parameter Description
required
Specifies whether the request must carry parameters. The default value is False
-
True Indicates that the carrier is mandatory
If not, the verification fails and an error message with status code 400 is returned to the client
-
False Not mandatory
If this parameter is not carried forcibly, the value is None if no parameter is carried in the client request
class DemoResource(Resource):
def get(self):
rp = RequestParser()
rp.add_argument('age', required=False)
args = rp.parse_args()
return {'msg': 'data={}'.format(args.age)}Copy the code
help
Error description returned when parameter validation failed
rp.add_argument('a', required=True, help='missing a param')Copy the code
action
Describes what to do when multiple parameters with the same name appear in a request parameter
-
Action =’store’ keeps the first occurrence, default
-
Action =’append’ saves the values of all parameters with the same name in list append
rp.add_argument('age', required=True, help='missing age param', action='append')Copy the code
type
You can use python’s standard data types string and int, or flask-restful, or you can define your own
-
The standard type
rp.add_argument('age', type=int, required=True, help='missing age param', action='append')Copy the code
-
Flask – RESTful
Check type methods in the flask_rest. inputs module
-
url
-
Regex (specifies a regular expression)
from flask_restful import inputs rp.add_argument('age', type=inputs.regex(r'^\d{2}&'))Copy the code
-
0, 1, 2, 3…
-
Positive integer 1, 2, 3…
-
Int_range (low,high) Integer range
rp.add_argument('age', type=inputs.int_range(1.100))Copy the code
-
boolean
-
-
The custom
def mobile(mobile_str): "" check mobile phone number format :param mobile_str: STR Checked string :return: mobile_str """ if re.match(r'^1[3-9]\d{9}$', mobile_str): return mobile_str else: raise ValueError('{} is not a valid mobile'.format(mobile_str)) rp.add_argument('mobile', type=mobile)Copy the code
location
Describes where the parameters should appear in the request data
# Look only in the POST body
parser.add_argument('name', type=int, location='form')
# Look only in the querystring
parser.add_argument('PageSize', type=int, location='args')
# From the request headers
parser.add_argument('User-Agent', location='headers')
# From http cookies
parser.add_argument('session_id', location='cookies')
# From json
parser.add_argument('user_id', location='json')
# From file uploads
parser.add_argument('picture', location='files')Copy the code
Multiple locations can also be specified
parser.add_argument('text', location=['headers'.'json'])Copy the code
4 the response
4.1 Serializing Data
Flask-restful provides the Marshal tool, which helps us serialize data into dictionary data in a specific format for use as the return value of the view.
from flask_restful import Resource, fields, marshal_with
resource_fields = {
'name': fields.String,
'address': fields.String,
'user_id': fields.Integer
}
class Todo(Resource):
@marshal_with(resource_fields, envelope='resource')
def get(self, **kwargs):
return db_get_todo()Copy the code
You can also do this without using decorators
class Todo(Resource):
def get(self, **kwargs):
data = db_get_todo()
return marshal(data, resource_fields)Copy the code
Example:
The class used to simulate the data object to be returned
class User(object):
def __init__(self, user_id, name, age):
self.user_id = user_id
self.name = name
self.age = age
resoure_fields = {
'uer_id': fields.Integer,
'name': fields.String
}
class Demo1Resource(Resource):
@marshal_with(resoure_fields, envelope='data1')
def get(self):
user = User(1.'itcast'.12)
return user
class Demo2Resource(Resource):
def get(self):
user = User(1.'itcast'.12)
return marshal(user, resoure_fields, envelope='data2')Copy the code
4.2 User-defined JSON Is Returned
demand
You want the JSON data returned by the interface to have the following uniform format
{"message": "description ", "data": {specific data to return}}Copy the code
Message returns OK if the interface handles properly, but if you want each interface to return correctly, omit the Message field
class DemoResource(Resource):
def get(self):
return {'user_id':1.'name': 'admin'}Copy the code
Can an interface like this be uniformly formatted somewhere?
{"message": "OK"."data": {"user_id":1."name": "admin"}}Copy the code
The solution
Flask-restful Api objects provide a representation decorator that allows you to customize the presentation format of returned data
api = Api(app)
@api.representation('application/json')
def handle_json(data, code, headers):
# TODO Add custom handling here
return respCopy the code
Flask-restful Original processing of JSON format is as follows:
Source code: flask_restful. Representations. Json
from flask import make_response, current_app
from flask_restful.utils import PY3
from json import dumps
def output_json(data, code, headers=None):
"""Makes a Flask response with a JSON encoded body"""
settings = current_app.config.get('RESTFUL_JSON', {})
# If we're in debug mode, and the indent is not set, we set it to a
# reasonable value here. Note that this won't override any existing value
# that was set. We also set the "sort_keys" value.
if current_app.debug:
settings.setdefault('indent'.4)
settings.setdefault('sort_keys'.not PY3)
# always end the json dumps with a new line
# see https://github.com/mitsuhiko/flask/pull/1262
dumped = dumps(data, **settings) + "\n"
resp = make_response(dumped, code)
resp.headers.extend(headers or {})
return respCopy the code
To meet the requirements, make the following changes:
@api.representation('application/json')
def output_json(data, code, headers=None):
"""Makes a Flask response with a JSON encoded body"""
# add *************** here for customization
if 'message' not in data:
data = {
'message': 'OK'.'data': data
}
# * * * * * * * * * * * * * * * * * * * * * * * * * *
settings = current_app.config.get('RESTFUL_JSON', {})
# If we're in debug mode, and the indent is not set, we set it to a
# reasonable value here. Note that this won't override any existing value
# that was set. We also set the "sort_keys" value.
if current_app.debug:
settings.setdefault('indent'.4)
settings.setdefault('sort_keys'.not PY3)
# always end the json dumps with a new line
# see https://github.com/mitsuhiko/flask/pull/1262
dumped = dumps(data, **settings) + "\n"
resp = make_response(dumped, code)
resp.headers.extend(headers or {})
return respCopy the code
5. Summary
Flask-restful: Flask-restful: Flask-restful: Flask-restful: Flask-restful: Flask-restful: Flask-restful