zoukankan      html  css  js  c++  java
  • Flask-RESTful 快速入门

    Flask-RESTful 快速入门

    hello world

    from flask import Flask
    from flask_restful import Resource, Api
    
    app = Flask(__name__)
    api = Api(app)
    
    class HelloWorld(Resource):
        def get(self):
            return {'hello': 'world'}
    
    api.add_resource(HelloWorld, '/')
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    资源

    资源 (Resource) 是 Flask-RESTful 中最主要的概念. 资源就是 Flask pluggable views 的子类, 因此可以很容易的定义 HTTP 方法. 一个简单的 CRUD 程序看起来如下:

    from flask import Flask, request
    from flask_restful import Resource, Api
    
    app = Flask(__name__)
    api = Api(app)
    
    todos = {}
    
    class TodoSimple(Resource):
        def get(self, todo_id):
            return {todo_id: todos[todo_id]}
    
        def put(self, todo_id):
            todos[todo_id] = request.form['data']
            return {todo_id: todos[todo_id]}
    
    // 将 TodoSimple 挂载在 '/<string:todo_id>' 路由上
    api.add_resource(TodoSimple, '/<string:todo_id>')
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    Flask-RESTful 能够处理各种类型返回值, 将其转换成合适的响应.

    class Todo1(Resource):
        def get(self):
            # 默认 HTTP Status Code 为 200
            return {'task': 'Hello world'}
    
    class Todo2(Resource):
        def get(self):
            # 设置 HTTP Status Code 为 201
            return {'task': 'Hello world'}, 201
    
    class Todo3(Resource):
        def get(self):
            # 设置 HTTP Status Code 为 201 并返回自定义 headers
            return {'task': 'Hello world'}, 201, {'Etag': 'some-opaque-string'}
    

    Endpoints

    一个资源可以挂载在多个路由上:

    api.add_resource(HelloWorld,
        '/',
        '/hello')
    

    可以将路由作为参数

    api.add_resource(Todo,
        '/todo/<int:todo_id>', endpoint='todo_ep')
    

    参数解析

    虽然 Flask 提供了简单的方法访问请求数据, 但是对于表单数据处理还是很痛苦. Flask-RESTful 提供了 reqparse 一种类似 argparse 参数解析机制以简化参数处理.

    from flask_restful import reqparse
    
    parser = reqparse.RequestParser()
    parser.add_argument('rate', type=int, help='Rate to charge for this resource')
    // strict 如果提供未定义的参数, 那么就抛出异常
    args = parser.parse_args(strict=True)
    

    数据格式化

    Flask 能很好的处理 Python 内置的数据结构, Flask-RESTful 提供了处理自定义对象的 fields 模块和 marshal_with() 方法

    from collections import OrderedDict
    from flask_restful import fields, marshal_with
    
    resource_fields = {
        'task':   fields.String,
        'uri':    fields.Url('todo_ep')
    }
    
    class TodoDao(object):
        def __init__(self, todo_id, task):
            self.todo_id = todo_id
            self.task = task
    
            # This field will not be sent in the response
            self.status = 'active'
    
    class Todo(Resource):
        @marshal_with(resource_fields)
        def get(self, **kwargs):
            return TodoDao(todo_id='my_todo', task='Remember the milk')
    

    上例中 get 返回一个 TodoDao 对象, 使用 marshal_with 装饰器根据 resource_fields 序列化这个对象. 这里只有一个字段被序列化, 就是 task.

    总结

    Flask-RESTful 的使用基本上就是用 reqparse 处理请求, 使用 fields 来处理返回值, 输出响应.

    完整的例子

    from flask import Flask
    from flask_restful import reqparse, abort, Api, Resource
    
    app = Flask(__name__)
    api = Api(app)
    
    TODOS = {
        'todo1': {'task': 'build an API'},
        'todo2': {'task': '?????'},
        'todo3': {'task': 'profit!'},
    }
    
    
    def abort_if_todo_doesnt_exist(todo_id):
        if todo_id not in TODOS:
            abort(404, message="Todo {} doesn't exist".format(todo_id))
    
    parser = reqparse.RequestParser()
    parser.add_argument('task')
    
    
    # Todo
    # shows a single todo item and lets you delete a todo item
    class Todo(Resource):
        def get(self, todo_id):
            abort_if_todo_doesnt_exist(todo_id)
            return TODOS[todo_id]
    
        def delete(self, todo_id):
            abort_if_todo_doesnt_exist(todo_id)
            del TODOS[todo_id]
            return '', 204
    
        def put(self, todo_id):
            args = parser.parse_args()
            task = {'task': args['task']}
            TODOS[todo_id] = task
            return task, 201
    
    
    # TodoList
    # shows a list of all todos, and lets you POST to add new tasks
    class TodoList(Resource):
        def get(self):
            return TODOS
    
        def post(self):
            args = parser.parse_args()
            todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1
            todo_id = 'todo%i' % todo_id
            TODOS[todo_id] = {'task': args['task']}
            return TODOS[todo_id], 201
    
    ##
    ## Actually setup the Api resource routing here
    ##
    api.add_resource(TodoList, '/todos')
    api.add_resource(Todo, '/todos/<todo_id>')
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    
  • 相关阅读:
    Glide加载网络图片与本地图片尺寸不一致
    android BLE 40 setCharacteristicNotification接收不到数据
    Android中颜色透明度对应16进制值
    模拟器不能运行 Failed to start emulator: Cannot run program "/home/kroaity/Downloads/android-sdk-linux//tools/emulator": error=2
    android SDK Manager 代理服务器设置
    if the parser found inconsistent certificates on the files in the .apk.104
    win7自带桌面便签
    unable to connect to the virtual device Genymotion 神器启动问题
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    获得root权限system/app下文件无法删除
  • 原文地址:https://www.cnblogs.com/wbin91/p/5927506.html
Copyright © 2011-2022 走看看