
Flask-RESTful 是一个 Flask 扩展,它为构建 RESTful API 提供了方便的工具和资源。它简化了创建 RESTful 服务的过程,允许开发者专注于业务逻辑而不是 HTTP 协议的细节。
Resource 类并定义 HTTP 方法(如 get, post, put, delete 等)来创建资源。@marshal_with 装饰器来序列化输出数据,使用 @expect 装饰器来声明期望的输入数据。Field 类及其子类(如 StringField, IntegerField 等)用于描述和格式化输出。reqparse.RequestParser 类,可以添加参数并指定参数类型、默认值、位置(如 JSON, 表单等)和其他验证器。Api 实例的 add_resource 方法可以将资源添加到应用中。restful.Api 类并重写 handle_error 方法来实现自定义错误处理。# 导入 Flask 和 Flask-RESTful 的相关类
from flask import Flask
from flask_restful import Resource, Api
# 创建 Flask 应用实例
app = Flask(__name__)
# 创建 Flask-RESTful API 实例
api = Api(app)
# 定义一个名为 HelloWorld 的资源类,继承自 flask_restful.Resource
class HelloWorld(Resource):
# 定义 GET 方法,当客户端发送 GET 请求时会调用这个方法
def get(self):
# 返回一个字典,其中包含一个键值对 'hello': 'world'
return {'hello': 'world'}
# 将 HelloWorld 资源添加到 API 路由中,设置其 URL 为 '/'
api.add_resource(HelloWorld, '/')
# 当此脚本作为主程序运行时(而不是被导入时),执行以下代码
if __name__ == '__main__':
# 启动 Flask 应用,开启 debug 模式以提供调试信息
app.run(debug=True)
这段代码创建了一个基本的 Flask 应用,并使用 Flask-RESTful 扩展添加了一个简单的 RESTful API。当你在浏览器或使用工具(如 curl)访问服务器的根 URL(http://localhost:5000/)时,你会得到一个 JSON 响应 {"hello": "world"}。
这段代码创建了一个简单的待办事项(Todo)管理应用,允许用户通过HTTP GET和PUT请求来检索和更新待办事项。
# 导入Flask和Flask-RESTful的相关类
from flask import Flask, request
from flask_restful import Resource, Api
# 创建Flask应用实例
app = Flask(__name__)
# 创建Flask-RESTful API实例
api = Api(app)
# 创建一个字典来存储待办事项,键为todo_id,值为待办事项的内容
todos = {}
# 定义一个名为TodoSimple的资源类,继承自flask_restful.Resource
class TodoSimple(Resource):
# 定义GET方法,当客户端发送GET请求时会调用这个方法
#(todo_id)表示这个方法是带参数的,参数名为todo_id
def get(self, todo_id):
# 从todos字典中获取todo_id对应的待办事项,并返回
# 如果todo_id不存在,会抛出一个KeyError异常
return {todo_id: todos[todo_id]}
# 定义PUT方法,当客户端发送PUT请求时会调用这个方法
#(todo_id)表示这个方法是带参数的,参数名为todo_id
def put(self, todo_id):
# 从请求的表单数据中获取'data'字段,并将其存储在todos字典中
# todo_id作为键,request.form['data']作为值
todos[todo_id] = request.form['data']
# 返回更新后的待办事项
return {todo_id: todos[todo_id]}
# 将TodoSimple资源添加到API路由中,设置其URL为'/'
# 这里的表示todo_id是一个字符串类型的参数
api.add_resource(TodoSimple, '/' )
# 当此脚本作为主程序运行时(而不是被导入时),执行以下代码
if __name__ == '__main__':
# 启动Flask应用,开启debug模式以提供调试信息
app.run(debug=True)
这段代码定义了一个名为 TodoSimple 的资源,它有两个方法:get 和 put。get 方法用于检索指定 todo_id 的待办事项,而 put 方法用于创建或更新待办事项的内容。待办事项的数据存储在全局字典 todos 中。应用运行后,可以通过发送 HTTP 请求到 /todo_id 来与资源进行交互。
这段代码定义了三个Flask-RESTful资源类,每个类都只有一个GET方法,但它们在返回响应时有所不同。
# 导入Flask-RESTful的Resource类
from flask_restful import Resource
# 定义一个名为Todo1的资源类,继承自flask_restful.Resource
class Todo1(Resource):
# 定义GET方法,当客户端发送GET请求时会调用这个方法
def get(self):
# 返回一个字典{'task': 'Hello world'},HTTP响应码默认为200 OK
return {'task': 'Hello world'}
# 定义一个名为Todo2的资源类,继承自flask_restful.Resource
class Todo2(Resource):
# 定义GET方法,当客户端发送GET请求时会调用这个方法
def get(self):
# 返回一个字典{'task': 'Hello world'},HTTP响应码设置为201 Created
return {'task': 'Hello world'}, 201
# 定义一个名为Todo3的资源类,继承自flask_restful.Resource
class Todo3(Resource):
# 定义GET方法,当客户端发送GET请求时会调用这个方法
def get(self):
# 返回一个字典{'task': 'Hello world'},HTTP响应码设置为201 Created
# 并添加自定义响应头{'Etag': 'some-opaque-string'}
return {'task': 'Hello world'}, 201, {'Etag': 'some-opaque-string'}
在这个例子中,每个类都代表一个可以访问的资源。Todo1 返回一个默认的200响应码,表示请求成功。Todo2 返回一个201响应码,通常用于创建资源的响应,表示请求已成功处理并创建了新的资源。Todo3 也返回一个201响应码,但同时还包括了一个自定义的响应头Etag,这通常用于缓存验证,表示资源的版本信息。
这些类可以添加到Flask-RESTful的API中,并通过相应的URL路径进行访问。每个类的get方法都可以通过HTTP GET请求来调用,返回一个 JSON 响应 {"hello": "world"}。
这段代码使用了 Flask-RESTful 的 reqparse 模块来解析请求参数。
# 导入 Flask-RESTful 的 reqparse 模块
from flask_restful import reqparse
# 创建一个 RequestParser 实例,用于解析请求中的参数
parser = reqparse.RequestParser()
# 使用 add_argument 方法添加一个参数 'rate' 到解析器中
# 参数类型设置为 int,表示期望 'rate' 是一个整数
# help='Rate to charge for this resource' 提供了一个帮助信息,当参数验证失败时会显示这个信息
parser.add_argument('rate', type=int, help='Rate to charge for this resource')
# 调用 parse_args 方法来解析请求中的参数
# 如果请求中包含 'rate' 参数,它会将其转换为整数,并存储在 args 对象中
# 如果 'rate' 参数不存在或者不是整数,Flask-RESTful 会返回一个 400 Bad Request 响应,并显示帮助信息
args = parser.parse_args()
# 现在 args 对象包含了请求中的 'rate' 参数,可以直接使用 args['rate'] 来获取其值
# 调用 parse_args 方法来解析请求中的参数
# strict=True 参数指定了严格模式,只有预先在解析器中定义的参数会被接受
# 如果请求中包含未定义的参数,将抛出一个 BadRequest 异常,导致 400 Bad Request 响应
args = parser.parse_args(strict=True)
在这个例子中,parser 对象被用来定义期望从请求中解析出的参数。add_argument 方法用于指定参数的名称、类型和帮助信息。当 parse_args 方法被调用时,它会解析实际的请求,提取出 rate 参数,并将其转换为整数类型。如果解析过程中出现问题(例如,rate 参数不是整数),Flask-RESTful 会自动生成一个错误响应。
这段代码展示了如何使用 Flask-RESTful 的 marshal_with 装饰器和 fields 模块来格式化资源类的输出。
# 导入 Flask-RESTful 的 fields 和 marshal_with
from flask_restful import fields, marshal_with
# 定义一个字段映射,指定了资源返回的数据结构
# 'task' 字段将被格式化为字符串,'uri' 字段将被格式化为 URL
# 'uri' 字段的值 'todo_ep' 是一个 endpoint 名称,用于生成 URL
resource_fields = {
'task': fields.String,
'uri': fields.Url('todo_ep')
}
# 定义一个 TodoDao 类,代表待办事项的数据访问对象
class TodoDao(object):
def __init__(self, todo_id, task):
self.todo_id = todo_id
self.task = task
# 定义一个 'status' 属性,但注释指出这个字段不会包含在响应中
self.status = 'active'
# 定义一个 Todo 资源类,继承自 flask_restful.Resource
class Todo(Resource):
# 使用 marshal_with 装饰器,指定了返回值应该使用 resource_fields 来格式化
@marshal_with(resource_fields)
def get(self, **kwargs):
# 创建一个 TodoDao 实例,并传入 todo_id 和 task
return TodoDao(todo_id='my_todo', task='Remember the milk')
在这个例子中,marshal_with 装饰器用于指定返回值的格式。resource_fields 字典定义了哪些字段应该包含在响应中,以及它们应该如何被格式化。fields.String 表示该字段应该被格式化为字符串,而 fields.Url 表示该字段应该被格式化为 URL,todo_ep 是一个 endpoint 名称,它将被用于生成实际的 URL。
TodoDao 类是一个简单的数据访问对象,它包含了 todo_id、task 和 status 属性。在 Todo 资源类的 get 方法中,创建了一个 TodoDao 实例,并返回它。由于 marshal_with 装饰器的使用,只有 task 和 uri 字段会被包含在最终的响应中,而 status 字段会被忽略。
# 导入 Flask 和 Flask-RESTful 的相关类
from flask import Flask
from flask_restful import reqparse, abort, Api, Resource
# 创建 Flask 应用实例
app = Flask(__name__)
# 创建 Flask-RESTful API 实例
api = Api(app)
# 定义一个字典来存储待办事项,键为 todo_id,值为待办事项的内容
TODOS = {
'todo1': {'task': 'build an API'},
'todo2': {'task': '?????'},
'todo3': {'task': 'profit!'},
}
# 定义一个函数来检查待办事项是否存在,如果不存在则抛出 404 错误
def abort_if_todo_doesnt_exist(todo_id):
if todo_id not in TODOS:
abort(404, message="Todo {} doesn't exist".format(todo_id))
# 创建一个 RequestParser 实例来解析请求中的参数
parser = reqparse.RequestParser()
parser.add_argument('task')
# 定义一个 Todo 资源类,继承自 flask_restful.Resource
class Todo(Resource):
# 定义 GET 方法,用于获取指定 todo_id 的待办事项
def get(self, todo_id):
abort_if_todo_doesnt_exist(todo_id)
return TODOS[todo_id]
# 定义 DELETE 方法,用于删除指定 todo_id 的待办事项
def delete(self, todo_id):
abort_if_todo_doesnt_exist(todo_id)
del TODOS[todo_id]
return '', 204 # 返回空响应和 204 No Content 状态码
# 定义 PUT 方法,用于更新指定 todo_id 的待办事项
def put(self, todo_id):
args = parser.parse_args()
task = {'task': args['task']}
TODOS[todo_id] = task
return task, 201 # 返回更新后的待办事项和 201 Created 状态码
# 定义一个 TodoList 资源类,继承自 flask_restful.Resource
class TodoList(Resource):
# 定义 GET 方法,用于获取所有待办事项的列表
def get(self):
return TODOS
# 定义 POST 方法,用于添加新的待办事项
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 # 返回新添加的待办事项和 201 Created 状态码
# 添加资源路由到 API
api.add_resource(TodoList, '/todos') # 将 TodoList 资源映射到 /todos 路径
api.add_resource(Todo, '/todos/' ) # 将 Todo 资源映射到 /todos/ 路径
# 当此脚本作为主程序运行时,执行以下代码
if __name__ == '__main__':
# 启动 Flask 应用,开启 debug 模式以提供调试信息
app.run(debug=True)
这个应用定义了两个资源:Todo 和 TodoList。Todo 资源允许用户获取、删除和更新特定的待办事项,而 TodoList 资源允许用户获取所有待办事项的列表和添加新的待办事项。待办事项的数据存储在全局字典 TODOS 中。应用运行后,可以通过发送 HTTP 请求到指定的 URL 来与资源进行交互。