• Python使用Flask实现RESTful API,使用Postman工具、requests库测试接口


    RESTful是一种API设计规范。
    在RESTful架构中,主要使用POST,DELETE,PUT和GET四种HTTP请求方式分别对指定的URL资源进行增删改查操作。

    RESTful之前的做法:

    /users/query/1 GET 根据用户id查询用户数据
    /users/save POST 新增用户
    /users/update POST 修改用户信息
    /users/delete GET/POST 删除用户信息

    RESTful做法:

    /users/1 GET 根据用户id查询用户数据
    /users POST 新增用户
    /users PUT 修改用户信息
    /users DELETE 删除用户信息

    客户端的每一次请求,服务器都会给出回应,回应包括 HTTP 状态码和数据两部分。
    部分状态码:
    GET: 200 OK
    POST: 201 Created
    PUT: 200 OK
    DELETE: 204 No Content

    使用Flask实现一个RESTful API服务的例子

    from flask import Flask,jsonify,abort,make_response,request
    from flask_httpauth import HTTPBasicAuth
    
    app = Flask(__name__)
    auth = HTTPBasicAuth()
    
    users = [
        {
            'id': 1,
            'username': '小明',
            'sex': 1
        },
        {
            'id': 2,
            'username': '小红',
            'sex': 0
        }
    ]
    
    #访问前需要提供用户名和密码
    @auth.get_password
    def get_password(username):
        if username == 'admin':
            return '123456'
        return None
    
    #友好的错误提示:没有权限
    @auth.error_handler
    def unauthorized():
        return make_response(jsonify({'error': '未授权'}), 403)
    
    #友好的错误提示:找不到资源页面
    @app.errorhandler(404)
    def not_found(error):
        return make_response(jsonify({'error': '找不到资源'}), 404)
    
    #返回所有用户的记录
    @app.route('/api/v1.0/users', methods=['GET'])
    @auth.login_required #需要认证
    def get_users():
        return jsonify({'users': users})
    
    #返回一个用户的记录记录
    @app.route('/api/v1.0/users/<int:user_id>', methods=['GET'])
    @auth.login_required
    def get_user(user_id):
        user = list(u for u in users if u['id'] == user_id)
        if len(user) == 0:
            abort(404)
        return jsonify({'user': user[0]})
    
    #插入一条用户记录
    @app.route('/api/v1.0/users', methods=['POST'])
    @auth.login_required
    def create_user():
        if not request.json or not 'username' in request.json or not 'sex' in request.json:
            abort(400)
        user = {
            'id': users[-1]['id'] + 1,
            'username': request.json['username'],
            'sex': request.json['sex']
        }
        users.append(user)
        return jsonify({'user': user}), 201
    
    #更新一个用户的记录
    @app.route('/api/v1.0/users/<int:user_id>', methods=['PUT'])
    @auth.login_required
    def update_user(user_id):
        user = list(u for u in users if u['id'] == user_id)
        if len(user) == 0:
            abort(404)
        if not request.json:
            abort(400)   
        user[0]['username'] = request.json.get('username', user[0]['username'])
        user[0]['sex'] = request.json.get('sex', user[0]['sex'])
        return jsonify({'user': user[0]})
    
    #删除一个用户的记录
    @app.route('/api/v1.0/users/<int:user_id>', methods=['DELETE'])
    @auth.login_required
    def delete_user(user_id):
        user = list(u for u in users if u['id'] == user_id)
        if len(user) == 0:
            abort(404)
        users.remove(user[0])
        return jsonify({'result': True}),204
    
    
    if __name__ == '__main__':
        app.run(debug=True)

    上面例子,也可以使用Flask-RESTful实现

    from flask import Flask,jsonify,abort,make_response,request
    from flask_httpauth import HTTPBasicAuth
    from flask_restful import Api,Resource,reqparse
    
    app = Flask(__name__)
    api = Api(app)
    auth = HTTPBasicAuth()
    
    users = [
        {
            'id': 1,
            'username': '小明',
            'sex': 1
        },
        {
            'id': 2,
            'username': '小红',
            'sex': 0
        }
    ]
    
    #验证字段的合法性
    parser = reqparse.RequestParser()
    parser.add_argument('username', type = str, required = True, help = '此字段格式有问题', location = 'json')
    parser.add_argument('sex', type = int, default = "1", location = 'json')  
    
    #访问前需要提供用户名和密码
    @auth.get_password
    def get_password(username):
        if username == 'admin':
            return '123456'
        return None
    
    class UserListAPI(Resource):
        decorators = [auth.login_required]   
    
        def get(self):
            return {'users': users}
    
        def post(self):
            args = parser.parse_args()
            user = {        
                'id': users[-1]['id'] + 1,
                'username': args['username'],
                'sex': args['sex']
            }
            users.append(user)
            return {'user': user}, 201
    
    class UserAPI(Resource):
        decorators = [auth.login_required]    
    
        def get(self, id):        
            user = list(u for u in users if u['id'] == id)
            if len(user) == 0:
                abort(404)
            return {'user': user[0]}
    
        def put(self, id):
            user = list(u for u in users if u['id'] == id)
            if len(user) == 0:
                abort(404)
            user = user[0]
            args = parser.parse_args()
            for k, v in args.items():
                if v != None:
                    user[k] = v
            return  { 'user': user }
    
        def delete(self, id):
            user = list(u for u in users if u['id'] == id)
            if len(user) == 0:
                abort(404)
            users.remove(user[0])
            return {'result': True}
    
    api.add_resource(UserListAPI, '/api/v1.0/users', endpoint = 'users')
    api.add_resource(UserAPI, '/api/v1.0/users/<int:id>', endpoint = 'user')
    
    if __name__ == '__main__':
        app.run(debug=True)

    使用Postman测试接口

    创建一个新的Request,Request name和Create Collection都随便输入如RESTfulAPI,保存后,自动打开名称为RESTfulAPI的标签页。

    (1)测试/api/v1.0/users的GET请求

    RESTfulAPI标签页默认选择 GET,输入:localhost:5000/api/v1.0/users,这里直接点击Send按钮,Postman返回码:Status:403 FORBIDDEN,返回内容

    {
    "error": "未授权"
    }

    在Authorization标签里面TYPE选择Basic Auth,右边Username和Password分别输入admin和123456。

     点击Send按钮,Postman返回码:Status:201 CREATED,返回内容:

    {
      "users": [
        {
          "id": 1,
          "sex": 1,
          "username": "小明"
        },
        {
          "id": 2,
          "sex": 0,
          "username": "小红"
        }
      ]
    }

    (2)测试/api/v1.0/users/<int:user_id>的GET请求

    修改Postman的请求方法和地址为:GET localhost:5000/api/v1.0/users/2

    (3)测试/api/v1.0/users的POST请求

    修改Postman的请求方法和地址为:POST localhost:5000/api/v1.0/users
    在Body标签里面选择raw、修改最后的默认Text为JSON(application/json),下面输入框填写:

    {
    	"id": 3,
    	"sex": 1,
    	"username": "小强"
    }

    点击Send按钮,Postman返回码:Status:201 CREATED
    把POST方法直接改为GET方法,可见返回3条记录。

    (4)测试/api/v1.0/users/<int:user_id>的PUT请求

    修改Postman的请求方法和地址为:PUT localhost:5000/api/v1.0/users/3
    在Body标签里面选择raw、修改最后的默认Text为JSON(application/json),下面输入框填写:

    {
    	"id": 3,
    	"sex": 1,
    	"username": "小刚"
    }

    点击Send按钮,Postman返回码:Status:200 OK

    (5)测试/api/v1.0/users/<int:user_id>的DELETE请求

    修改Postman的请求方法和地址为:DELETE localhost:5000/api/v1.0/users/3
    点击Send按钮,Postman返回码:Status:204 NOT CONTENT

    使用Python的第三方库requests测试接口

    import requests,json
    
    url = 'http://localhost:5000/api/v1.0'
    auth = ('admin','123456')
    
    #查询
    r=requests.get(url + '/users', auth=auth)
    print(r.status_code, r.text)
    #在控制台输出时中文会用unicode显示,可用下面方法显示中文
    #print(json.dumps(json.loads(r.text),ensure_ascii=False))
    
    r=requests.get(url + '/users/1', auth=auth)
    print(r.status_code, r.text)
    
    #更新
    data = {
        "id": 3,
        "sex": 1,
        "username": "小强"
    }
    r=requests.post(url + '/users', auth=auth, json=data)
    print(r.status_code, r.text)
    
    #修改
    data = {
        "id": 3,
        "sex": 1,
        "username": "小刚"
    }
    r=requests.put(url + '/users/3', auth=auth, json=data)
    print(r.status_code, r.text)
    
    #删除
    r=requests.delete(url + '/users/3', auth=auth)
    print(r.status_code, r.text)
  • 相关阅读:
    1.求整数最大的连续0的个数 BinaryGap Find longest sequence of zeros in binary representation of an integer.
    JTree实例
    java发送邮件完整实例 java邮件工具类
    oracle存储过程中文乱码问题
    黑马day16 jquery&amp;内容过滤选择器&amp;可见度选择器
    隐性反馈行为数据的协同过滤推荐算法
    ACdream 1083 有向无环图dp
    正則表達式
    hdu 2209 bfs+状压
    action属性注入为null
  • 原文地址:https://www.cnblogs.com/gdjlc/p/11485223.html
Copyright © 2020-2023  润新知