Swagger 介绍
- 0. 引言
- 1. Swagger 介绍
- 2. Flasgger 介绍
- 3. Flasgger效果
- 3.1 原始flask代码
- 3.2 转化成Flasgger形式
- 3.3 使用Try it out调试
- 3.4 多个url接口自动生成和调试
- 4. 使用教程
- 4.1 使用 docstrings 作为规范
- 4.2 使用外部 YAML 文件
- 4.3 使用 Python 字典作为原始规范
- 5. 和Marshmallow Schemas集成使用教程
- 5.1 第一种用法(USAGE #1): 使用 SwaggerView
- 5.2 第二种用法(USAGE #2): Custom Schema from flasgger
- 5.3 注意事项:
- 6. 和Flask_restful集成使用教程
- 6.1 Flask-RESTful 的好处:
- 6.2 Flasgger 的好处:
- 6.3 集成的优势:
- 6.4 举例说明:
- 7. Marshmallow Schemas、Flask_restful 和 Flasgger在Flask开发中的集成和好处
- 7.1 Marshmallow Schemas
- 7.2 Flask-RESTful
- 7.3 Flasgger
- 7.4 集成的优势
- 7.5 举例说明
0. 引言
Flask 是一个轻量级的 Python Web 开发框架,它简单易用,但功能强大,适合快速开发小型和大型应用。Swagger 是一套开源的 API 设计工具,能够帮助开发者遵循 Restful API 规范,设计、构建、文档化并测试 API。Flasgger 是 Flask 的 Swagger UI 实现,它集成了 Swagger 工具的功能,使得开发者可以方便地为使用 Flask 框架搭建的 Web API 自动生成在线文档,并支持在界面上直接进行 API 测试。这样的集成让 API 的调试过程变得更加直观和高效。
1. Swagger 介绍
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使文档化工作和客户端与服务器之间的 API 调用更加容易进行。Swagger 的主要组件包括:
-
Swagger 规范(Swagger Specification):
- 它是一个用于描述 API 的格式标准。目前的版本是 OpenAPI Specification(OAS),它定义了一个API的所有可能参数、请求的输入和输出格式等。
-
Swagger UI:
- 是一个基于 Web 的用户界面,用于读取 OpenAPI 规范生成的 API 文档,并通过用户友好的界面显示。用户可以通过 Swagger UI 学习如何使用 API,甚至可以在不写任何代码的情况下发送请求。
-
Swagger Codegen:
- 它可以基于 OpenAPI 规范自动生成客户端库、服务器存根和API文档等,支持多种编程语言。
-
Swagger Editor:
- 是一个浏览器中的编辑器,允许开发者编写或编辑 OpenAPI 规范,它可以实时预览文档和 UI。
-
Swagger Inspector:
- 是一个用于测试API的工具,允许你发出请求并查看响应,无论API是否使用Swagger进行了文档化。
Swagger 通常被用来定义 RESTful API 的接口,然后自动生成文档以及客户端 SDK。对于开发者来说,Swagger 提供了一种简单而强大的方式来定义和交互你的API,并确保API的结构清晰、文档齐全。
随着 Swagger 的发展,它已经被 SmartBear Software 收购,并且 Swagger 规范已经演化成了 OpenAPI Specification。Swagger 工具集中,特别是 Swagger UI 和 Swagger Editor 现在支持 OAS,继续作为API文档和测试的重要工具。
2. Flasgger 介绍
Flasgger 是一个 Flask 扩展,它可以从 Flask 应用中注册的所有视图中提取 OpenAPI 规范(以前称为 Swagger 规范)。
Flasgger 内置了 Swagger UI,这意味着你可以通过访问 http://localhost:5000/apidocs
来可视化地查看、交互并测试你的 API 资源。
此外,Flasgger 提供了对传入数据的验证功能:利用同样的规范,Flasgger 能够验证 POST、PUT 或 PATCH 请求中接收到的数据是否符合通过 YAML、Python 字典或 Marshmallow Schema 定义的模式。
Flasgger 既可以与简单的函数视图协作,也可以利用 MethodViews,并使用 docstring 来编写 API 规范。或者你可以使用 @swag_from
装饰器来从 YAML 文件或字典中获取规范,它也提供了 SwaggerView,这可以使用 Marshmallow Schemas 来定义API规范。
Flasgger 与 Flask-RESTful (详细介绍见此博客)兼容,因此你可以将 Resources 和 swagger 规范结合在一起使用。如果你想看具体的例子,可以查看 Flask-RESTful 示例。
如果你正在使用 Marshmallow 的 APISpec 作为规范的基础模板,Flasgger 也支持这一点。有关使用 Marshmallow APISpec 的示例,你也可以查看 APISpec 示例。
总而言之,Flasgger 为 Flask API 的文档化、测试和验证提供了一套完整的解决方案,让开发者更容易创建符合 OpenAPI 规范的 RESTful API。
3. Flasgger效果
一个简单的Flasgger的运行例子如下所示:
3.1 原始flask代码
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Project : Flask and Swagger Test
# @File : flask_swagger_example2_without_flasgger.py
# @Time : 2023/12/23 14:49
# @Author : Yiyang Liu
# @Contact: YiYang.Liu@cisdi.com.cn
#!/usr/bin/python3
# -*- coding: utf-8 -*-from flask import Flask, request, jsonify
import randomapp = Flask(__name__)@app.route('/api/<string:language>/', methods=['GET'])
def index(language):# 这里可以添加函数描述,但这不会像Flasgger那样自动生成文档language = language.lower().strip()features = ["awesome", "great", "dynamic","simple", "powerful", "amazing","perfect", "beauty", "lovely"]size = int(request.args.get('size', 1))if language in ['php', 'vb', 'visualbasic', 'actionscript']:return "An error occurred, invalid language for awesomeness", 500return jsonify(language=language,features=random.sample(features, min(size, len(features))))if __name__ == "__main__":app.run(debug=True)
这段代码是一个用 Flask 编写的 Web API,它能够根据用户请求的不同编程语言返回一组随机选择的正面特性列表。API 只响应 GET
请求,并且可以接受两个参数:
language
: 这是一个路径参数,用户需要在 URL 中指定,如/api/python/
。size
: 这是一个可选的查询字符串参数,用来指定返回特性的数量。
功能概述:
- 当用户向
/api/<language>/
发送GET
请求时,服务器会处理请求并返回该语言的一组特性。 features
列表包含了一些用于描述编程语言的正面形容词。- 如果请求的语言是
php
、vb
、visualbasic
或actionscript
中的一个,它将返回一个 500 错误,表示这些语言不适合"awesomeness"特性。 - 否则,它将从
features
列表中随机选择用户指定数量(size
)的特性,并以 JSON 格式返回。
如何使用:
- 运行这段代码(通常通过命令行执行这个 Python 脚本)。
- 使用 Web 浏览器或工具(如
curl
、httpie
或 Postman)向指定的端口发送GET
请求(如果你本地运行,默认端口是 5000)。 - 在 URL 中包含你想查询的编程语言,例如:
http://127.0.0.1:5000/api/python/
。 - (可选)在请求中添加
size
参数来指定想要返回多少个特性,例如:http://127.0.0.1:5000/api/python/?size=3
。
示例响应:
{"language": "python","features": ["simple", "powerful", "perfect"]
}
这将返回一个 JSON 对象,包含请求的语言及其随机选择的特性列表。
运行http://127.0.0.1:5000/api/python/
的效果如下:
运行http://127.0.0.1:5000/api/python/?size=3
的效果如下:
flask的接口调试和使用方法仍然不是很明确。
3.2 转化成Flasgger形式
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Project : Flask and Swagger Test
# @File : flask_swagger_example2.py
# @Time : 2023/12/20 10:09
# @Author : Yiyang Liu
# @Contact: YiYang.Liu@cisdi.com.cn
# coding:utf8import sys
import randomfrom flask import Flask, Blueprint, render_template, request, redirect, jsonify
from flasgger import Swagger, swag_fromapp = Flask(__name__)
Swagger(app)@app.route('/api/<string:language>/', methods=['GET'])
def index(language):"""This is the language awesomeness APICall this api passing a language name and get back its features---tags:- Awesomeness Language APIparameters:- name: languagein: pathtype: stringrequired: truedescription: The language name- name: sizein: querytype: integerdescription: size of awesomenessresponses:500:description: Error The language is not awesome!200:description: A language with its awesomenessschema:id: awesomeproperties:language:type: stringdescription: The language namedefault: Luafeatures:type: arraydescription: The awesomeness listitems:type: stringdefault: ["perfect", "simple", "lovely"]"""language = language.lower().strip()features = ["awesome", "great", "dynamic","simple", "powerful", "amazing","perfect", "beauty", "lovely"]size = int(request.args.get('size', 1))if language in ['php', 'vb', 'visualbasic', 'actionscript']:return "An error occurred, invalid language for awesomeness", 500return jsonify(language=language,features=random.sample(features, size))app.run(debug=True)
这段代码通过集成 Flasgger 库,将 Flask 应用程序扩展为具有自动生成 API 文档的能力。Flasgger 是一个 Flask 扩展,它使用 Swagger 2.0 规范为你的 RESTful API 创建在线文档。它提供了一个 Web UI,让用户可以轻松地阅读所有 API 的说明,并且可以直接在 UI 中测试 API 请求。
Flasgger 集成后功能变化:
- 这段代码定义了一个 Flask 路由,该路由现在被 Flasgger 的 Swagger 文档装饰器所注释,这允许 Swagger 自动生成与该路由相关的 API 文档。
- 此代码段中的文档字符串(位于函数
index
下面)使用 YAML 语法描述了 API 的功能、标签、参数和响应类型。这将为 Swagger UI 提供必要的信息来展示一个可交云的接口文档。
如何使用带有 Flasgger 的 API:
- 与之前一样,运行这个脚本将启动 Flask 应用程序。
- 通过 Web 浏览器访问
http://127.0.0.1:5000/apidocs/
(或者如果你部署到服务器上的话,替换为相应的 URL),你将看到一个 Swagger UI 的页面,列出了所有通过 Docstrings 定义的路由和它们的文档。 - 在这个 Swagger UI 页面上,你可以找到
/api/<language>/
路由,并且可以直接通过 UI 试运行 API 请求。你可以输入语言名称作为路径参数,并选择size
作为查询参数(如果需要)。 - 发送请求后,Swagger UI 将显示服务器的响应,同样以 JSON 格式展示语言特性。
这种方式提供了一种更为用户友好的方式来了解和使用你的 API,同时减少了为 API 编写和维护独立文档的需要。
3.3 使用Try it out调试
http://127.0.0.1:5000/apidocs/
界面上有Try it out 功能,点击可以对已有的功能进行调试。
3.4 多个url接口自动生成和调试
展示一个更复杂的例子如下:
from flask import Flask, request, jsonify
from flasgger import Swagger
import randomapp = Flask(__name__)
Swagger(app)@app.route('/api/<string:language>/', methods=['GET'])
def language_awesomeness(language):"""This is the language awesomeness APICall this api passing a language name and get back its features---tags:- Awesomeness Language APIparameters:- name: languagein: pathtype: stringrequired: truedescription: The language name- name: sizein: querytype: integerdescription: size of awesomenessresponses:500:description: Error The language is not awesome!200:description: A language with its awesomenessschema:id: awesomeproperties:language:type: stringdescription: The language namedefault: Luafeatures:type: arraydescription: The awesomeness listitems:type: stringdefault: ["perfect", "simple", "lovely"]"""language = language.lower().strip()features = ["awesome", "great", "dynamic","simple", "powerful", "amazing","perfect", "beauty", "lovely"]size = int(request.args.get('size', 1))if language in ['php', 'vb', 'visualbasic', 'actionscript']:return "An error occurred, invalid language for awesomeness", 500return jsonify(language=language,features=random.sample(features, size))@app.route('/api/random_number/', methods=['GET'])
def random_number():"""Get a random number---tags:- Random Number APIresponses:200:description: A random number"""return jsonify(number=random.randint(1, 100))@app.route('/api/greet/<string:name>/', methods=['GET'])
def greet_user(name):"""Greet the user---tags:- Greeting APIparameters:- name: namein: pathtype: stringrequired: truedescription: The name of the person to greetresponses:200:description: A greeting to the user"""return jsonify(greeting=f"Hello, {name}!")@app.route('/api/echo/', methods=['POST'])
def echo():"""Echo the message sent in POST data---tags:- Echo APIparameters:- in: bodyname: bodyrequired: truedescription: Message to echoschema:type: objectrequired:- messageproperties:message:type: stringdescription: The message to echoexample: "Hello, World!"responses:200:description: The message sent by the user"""data = request.jsonreturn jsonify(echo=data.get('message', ''))@app.route('/api/calculate/', methods=['GET'])
def calculate():"""A simple calculator---tags:- Calculator APIparameters:- name: operationin: querytype: stringrequired: trueenum: ['add', 'subtract', 'multiply', 'divide']description: The operation to perform- name: xin: querytype: numberrequired: truedescription: The first number- name: yin: querytype: numberrequired: truedescription: The second numberresponses:200:description: The result of the calculation400:description: Invalid input"""operation = request.args.get('operation')x = request.args.get('x', type=float)y = request.args.get('y', type=float)result = Noneif operation == 'add':result = x + yelif operation == 'subtract':result = x - yelif operation == 'multiply':result = x * yelif operation == 'divide':if y != 0:result = x / yelse:return jsonify(error="Cannot divide by zero."), 400else:return jsonify(error="Invalid operation."), 400return jsonify(result=result)if __name__ == '__main__':app.run(debug=True)
每个路由 (/api/random_number/, /api/greet//, /api/echo/, /api/calculate/) 都有其特定的功能:
- /api/random_number/: 返回一个随机数。
- /api/greet//: 根据提供的名字返回一个问候。
- /api/echo/: 返回 POST 请求中携带的信息(回声)。
- /api/calculate/: 根据提供的操作和两个数字执行简单的计算。
每个函数之上的三引号字符串是 Swagger 文档,它描述了接口的功能、参数、响应等信息,使得 API 的使用和理解更加方便。启动 Flask 应用后,你可以访问 http://127.0.0.1:5000/apidocs/ 来查看自动生成的 Swagger UI 文档,并且可以直接在那里测试不同的 API 请求。
4. 使用教程
首先,一些官网提供的常见的例子在这里可以找到。
Flasgger 允许你以不同的方式指定你的 API 文档:通过 docstrings、YAML 文件或直接使用 Python 字典。这些示例展示了如何使用 Flasgger 库与 Flask 框架一起为 API 端点创建 OpenAPI(Swagger)规范。
4.1 使用 docstrings 作为规范
首先是使用 docstrings 定义 API 文档规范。在这里,你可以直接在你的视图函数上编写文档,使用 YAML 风格的注释。
这是一个可以直接运行的 colors.py
文件示例:
from flask import Flask, jsonify
from flasgger import Swaggerapp = Flask(__name__)
swagger = Swagger(app)@app.route('/colors/<palette>/')
def colors(palette):"""Example endpoint returning a list of colors by paletteThis is using docstrings for specifications.---parameters:- name: palettein: pathtype: stringenum: ['all', 'rgb', 'cmyk']required: truedefault: alldefinitions:Palette:type: objectproperties:palette_name:type: arrayitems:$ref: '#/definitions/Color'Color:type: stringresponses:200:description: A list of colors (may be filtered by palette)schema:$ref: '#/definitions/Palette'examples:rgb: ['red', 'green', 'blue']"""all_colors = {'cmyk': ['cyan', 'magenta', 'yellow', 'black'],'rgb': ['red', 'green', 'blue']}if palette == 'all':result = all_colorselse:result = {palette: all_colors.get(palette)}return jsonify(result)if __name__ == "__main__":app.run(debug=True)
运行 python colors.py
,然后访问 http://localhost:5000/apidocs/
,你将看到 Swagger UI,并且能够与你的 /colors/<palette>/
端点交互。
4.2 使用外部 YAML 文件
如果你想将 API 文档规范与 Python 代码分离,可以将规范定义在一个外部 colors.yml
文件中。
创建 colors.yml
,内容如下:
parameters:- name: palettein: pathtype: stringenum: ['all', 'rgb', 'cmyk']required: truedefault: all
definitions:Palette:type: objectproperties:palette_name:type: arrayitems:$ref: '#/definitions/Color'Color:type: string
responses:200:description: A list of colors (may be filtered by palette)schema:$ref: '#/definitions/Palette'examples:rgb: ['red', 'green', 'blue']
然后在你的 Flask 应用中使用 @swag_from
装饰器来引用这个文件。以下是修改后的 colors.py
:
from flask import Flask, jsonify
from flasgger import Swagger, swag_fromapp = Flask(__name__)
swagger = Swagger(app)@app.route('/colors/<palette>/')
@swag_from('colors.yml')
def colors(palette):all_colors = {'cmyk': ['cyan', 'magenta', 'yellow', 'black'],'rgb': ['red', 'green', 'blue']}if palette == 'all':result = all_colorselse:result = {palette: all_colors.get(palette)}return jsonify(result)if __name__ == "__main__":app.run(debug=True)
4.3 使用 Python 字典作为原始规范
最后,API 规范也可以通过 Python 字典来定义。这种方法的优点是你可以在代码中动态地生成或修改这些规范。
以下是一个使用 Python 字典作为规范的 colors.py
:
from flask import Flask
from flasgger import Swagger
from flask_restful import Api, Resourceapp = Flask(__name__)
api = Api(app)
swagger = Swagger(app)class Username(Resource):def get(self, username):"""This examples uses FlaskRESTful ResourceIt works also with swag_from, schemas and spec_dict---parameters:- in: pathname: usernametype: stringrequired: trueresponses:200:description: A single user itemschema:id: Userproperties:username:type: stringdescription: The name of the userdefault: Steven Wilson"""return {'username': username}, 200api.add_resource(Username, '/username/<username>')app.run(debug=True)
5. 和Marshmallow Schemas集成使用教程
关于如何在使用 Flask 框架构建的 web 应用程序中集成 Marshmallow 序列化和验证库,并结合 Flasgger 自动生成 Swagger UI 文档的说明。
首先,需要通过 pip 安装 marshmallow
和 apispec
这两个库。Marshmallow 是一个轻量级的库,用于复杂数据类型的序列化和反序列化,同时也用于数据验证。Apispec 是一个用于创建 RESTful API 文档的工具。
下面中展示了两种使用这些库的方式:
5.1 第一种用法(USAGE #1): 使用 SwaggerView
from flask import Flask, jsonify
from flasgger import Swagger, SwaggerView, Schema, fieldsclass Color(Schema):name = fields.Str()class Palette(Schema):pallete_name = fields.Str()colors = fields.Nested(Color, many=True)class PaletteView(SwaggerView):parameters = [{"name": "palette","in": "path","type": "string","enum": ["all", "rgb", "cmyk"],"required": True,"default": "all"}]responses = {200: {"description": "A list of colors (may be filtered by palette)","schema": Palette}}def get(self, palette):"""Colors API using schemaThis example is using marshmallow schemas"""all_colors = {'cmyk': ['cyan', 'magenta', 'yellow', 'black'],'rgb': ['red', 'green', 'blue']}if palette == 'all':result = all_colorselse:result = {palette: all_colors.get(palette)}return jsonify(result)app = Flask(__name__)
swagger = Swagger(app)app.add_url_rule('/colors/<palette>',view_func=PaletteView.as_view('colors'),methods=['GET']
)app.run(debug=True)
- 使用两个 Marshmallow 的
Schema
类来定义数据结构。在这个例子中,定义了Color
和Palette
。 Color
Schema 定义了颜色对象,只有一个字段name
。Palette
Schema 定义了调色板对象,包含两个字段:一个是调色板名称pallete_name
,一个是颜色列表colors
,后者使用fields.Nested
字段来嵌套多个Color
对象。- 创建了一个继承自
SwaggerView
的PaletteView
类,这个类通过覆写get
方法实现了一个 GET 接口。在类中定义了parameters
和responses
,用于生成 Swagger UI 上的参数输入框和响应信息。 parameters
包含一个可选的枚举参数palette
。response
包含了一个 200 响应,使用Palette
Schema 来描述数据结构。- 在
get
方法中,根据palette
参数的值来过滤颜色并返回结果。 - 最后,将
PaletteView
通过app.add_url_rule
添加到 Flask 的 URL 规则中。
5.2 第二种用法(USAGE #2): Custom Schema from flasgger
from flask import Flask, abort
from flasgger import Swagger, Schema, fields
from marshmallow.validate import Length, OneOfapp = Flask(__name__)
Swagger(app)swag = {"swag": True,"tags": ["demo"],"responses": {200: {"description": "Success request"},400: {"description": "Validation error"}}}class Body(Schema):color = fields.List(fields.String(), required=True, validate=Length(max=5), example=["white", "blue", "red"])def swag_validation_function(self, data, main_def):self.load(data)def swag_validation_error_handler(self, err, data, main_def):abort(400, err)class Query(Schema):color = fields.String(required=True, validate=OneOf(["white", "blue", "red"]))def swag_validation_function(self, data, main_def):self.load(data)def swag_validation_error_handler(self, err, data, main_def):abort(400, err)swag_in = "query"@app.route("/color/<id>/<name>", methods=["POST"], **swag)
def index(body: Body, query: Query, id: int, name: str):return {"body": body, "query": query, "id": id, "name": name}if __name__ == "__main__":app.run(debug=True)
- 定义了两个
Schema
类:Body
和Query
,用于处理 POST 请求体和查询参数的验证。 Body
类定义了一个color
字段,这是一个列表,接受最多五个字符串元素,并且给出了一个示例。Body
类定义了两个方法swag_validation_function
和swag_validation_error_handler
,用于定义如何加载和处理数据,以及如何处理验证错误。Query
类定义了一个color
字段,这是一个字符串,必须是 “white”, “blue”, 或 “red” 中的一个。- 在 Flask 的路由装饰器
@app.route
中,通过**swag
引入了 Swagger 文档的配置信息(如标签、响应)。 - 在
index
函数中,可以通过 Marshmallow 序列化和验证传入的数据。
5.3 注意事项:
- 当使用路径参数时,应明确指定类型,如
/api/<string:username>
而不是/api/<username>
,以确保正确的类型解析和文档生成。
通过这样的配置,开发者可以利用 Marshmallow 和 Flasgger 库的优点,为 Flask 应用程序添加强大的请求解析、数据验证和 API 文档自动生成的功能。
6. 和Flask_restful集成使用教程
Flasgger支持和Flask_restful一起在Flask开发中使用,其中Flask_restful的讲解见这篇文章。
Flask-RESTful 和 Flasgger 集成在 Flask 应用中可带来以下好处:
6.1 Flask-RESTful 的好处:
-
简化 REST API 的开发:
Flask-RESTful 提供了资源抽象,使得开发者可以专注于逻辑而不是协议细节,通过定义资源类并指定对应的 HTTP 方法(如get
、post
、put
、delete
等),可以简化 URL 路由和请求处理的代码。 -
清晰的请求处理逻辑:
由于 Flask-RESTful 允许为每种 HTTP 方法定义独立的处理函数,这有助于提高代码的可读性和可维护性。 -
参数解析和数据验证:
Flask-RESTful 提供了请求解析器,支持对请求数据进行验证和类型转换,简化输入验证的过程。 -
灵活性和扩展性:
它可以与多种插件(比如 Flask-SQLAlchemy)和扩展(比如 Marshmallow)结合使用,实现更复杂的功能,如数据库集成和复杂的数据序列化。
6.2 Flasgger 的好处:
-
自动化 API 文档:
Flasgger 自动生成符合 Swagger 规范的 API 文档,可以自动提取视图函数的注释(docstring)来生成文档,减少了编写和维护 API 文档的工作量。 -
交互式用户界面:
Swagger UI 是一个交互式的 API 文档网页,用户可以直接在浏览器中看到所有的 API 端点,并且可以不编写任何代码就测试它们。 -
易于共享和沟通:
自动生成的文档易于共享给其他开发者、前端工程师和测试工程师,帮助团队更好地理解和使用 API。 -
标准化 API 设计:
Swagger 提供的规范有助于统一 API 的设计,使其符合行业标准,也便于使用工具进行 API 的设计、测试和监控。 -
减少前后端开发的分离难度:
前端开发者可以根据 Swagger UI 所展示的 API 文档独立进行前端开发,而不必等待后端完全完成。
6.3 集成的优势:
将 Flask-RESTful 和 Flasgger 集成在一起使用时,开发者可以同时享受两者的好处。开发者可以快速创建 RESTful API 并自动提供实时的、标准化的 API 文档。这种集成方式支持更快的迭代开发,因为前端和后端可以并行工作,同时 API 的变化可以实时反映在文档中,降低了沟通成本,提高了开发效率。
6.4 举例说明:
from flask import Flask
from flasgger import Swagger
from flask_restful import Api, Resourceapp = Flask(__name__)
api = Api(app)
swagger = Swagger(app)class Username(Resource):def get(self, username):"""This examples uses FlaskRESTful ResourceIt works also with swag_from, schemas and spec_dict---parameters:- in: pathname: usernametype: stringrequired: trueresponses:200:description: A single user itemschema:id: Userproperties:username:type: stringdescription: The name of the userdefault: Steven Wilson"""return {'username': username}, 200api.add_resource(Username, '/username/<username>')app.run(debug=True)
7. Marshmallow Schemas、Flask_restful 和 Flasgger在Flask开发中的集成和好处
在 Flask 开发中,Marshmallow Schemas、Flask-RESTful 和 Flasgger 的集成提供了一套强大的工具组合,以支持 REST API 的开发、数据处理和自动化文档。下面详细说明每个组件的作用以及它们集成时的好处。
7.1 Marshmallow Schemas
作用:
- 数据序列化与反序列化:将复杂数据类型(如 ORM 对象)转换为简单数据类型(如字典、JSON),反之亦然。
- 数据验证:提供了字段级的验证器,确保传入数据符合预期格式。
- 复杂数据结构处理:轻松处理嵌套数据和各种关系。
- 自定义数据处理逻辑:可以自定义方法来处理数据的加载和转储。
好处:
- 提高了代码复用性,减少了样板代码。
- 通过声明式语法,使得数据格式及其验证规则定义更加清晰和易于管理。
- 改善了与前端的协作,因为数据模式可以作为数据传输对象进行共享和讨论。
7.2 Flask-RESTful
作用:
- 资源抽象:使用资源基类来表示 API 可以处理的实体。
- 请求分发:自动将 HTTP 请求分发到对应的资源方法(GET, POST, PUT, DELETE等)。
- 请求解析:内置的请求解析器用于验证和类型转换输入数据。
好处:
- 提供了一个清晰、简单的方式来构建 RESTful APIs。
- 让开发者能更专注于业务逻辑而非底层的路由和请求解析细节。
- 代码结构更加模块化和可维护,每个资源类聚焦于特定的API端点。
7.3 Flasgger
作用:
- 自动化文档:通过解析视图函数中的注释来自动生成 Swagger/UI 兼容的文档。
- 交互式UI:提供了可视化的界面,允许开发者和用户执行 API 调用测试。
- 规范遵从:生成的文档符合 OpenAPI 规范,便于与遵循该规范的其他工具集成。
好处:
- 减少了编写和维护 API 文档的时间。
- 改进了 API 的可视化和可交互性,让最终用户能更容易地理解和尝试 API。
- 有助于前后端分离的开发模式,前端开发者可以根据实时更新的文档独立工作。
7.4 集成的优势
在 Flask 开发中将 Marshmallow、Flask-RESTful 和 Flasgger 集成在一起,可以实现一种高效的开发流程:
- 统一的数据处理和验证:使用 Marshmallow 定义数据模型和验证,确保 API 接收和返回的数据都是正确和一致的。
- 清晰的 API 结构:通过 Flask-RESTful 提供的结构化资源和方法,让 API 的设计更加直观和易于管理。
- 即时的文档更新:随着代码的更新,Flasgger 可以自动更新文档,确保文档始终与实际的 API 同步。
- 改进的开发体验:开发者可以更快捷地构建、测试和修正 API,同时自动化的文档减少了他们在文档维护上的工作负担。
- 加强前后端协作:自动化的 API 文档使前端开发者可以并行开发,而不需要等待后端完全完成;同时,前后端团队可以共同查看和讨论自动生成的 API 说明,减少了沟通成本。
整体而言,这种集成为 Flask 应用提供了一个可扩展、易于维护且协作友好的开发环境。
7.5 举例说明
让我们通过一个简单的例子来说明如何在 Flask 应用中集成 Marshmallow Schemas、Flask-RESTful 和 Flasgger:
安装所需库
首先,通过 pip 安装所需的库:
pip install flask flask-restful flasgger marshmallow
应用设置
现在,我们准备 Flask 应用,并引入所有必要的组件:
from flask import Flask
from flask_restful import Api, Resource
from flasgger import Swagger
from marshmallow import Schema, fields# 初始化 Flask 应用、API 和 Swagger
app = Flask(__name__)
api = Api(app)
swagger = Swagger(app)
定义 Marshmallow Schema
用 Marshmallow 定义一个简单的用户数据模式:
class UserSchema(Schema):username = fields.Str(required=True)email = fields.Email(required=True)
创建 Flask-RESTful 资源
创建一个代表用户的 Flask-RESTful 资源,并使用 Marshmallow Schema 进行数据验证和序列化:
class User(Resource):def get(self, username):"""Get User Endpoint---parameters:- in: pathname: usernametype: stringrequired: truedescription: The username of the userresponses:200:description: The user informationschema:id: UserResponseproperties:username:type: stringdescription: The username of the useremail:type: stringdescription: The email of the userexamples:application/json: { "username": "johndoe", "email": "john@example.com" }"""# 示例数据,实际应用中这里会是数据库查询等操作user_data = {"username": username, "email": f"{username}@example.com"}# 使用 Marshmallow Schema 校验和序列化数据user_schema = UserSchema()return user_schema.dump(user_data), 200
添加资源到 API
在 Api
对象中添加创建的资源,并指定路由:
api.add_resource(User, '/users/<string:username>')
运行应用
最后,运行 Flask 应用:
if __name__ == '__main__':app.run(debug=True)
现在,当你运行这个 Flask 应用,你将得到:
- 一个
/users/<username>
的 HTTP GET 端点,你可以通过传入一个username
来获取用户信息。 - 这个端点会返回一个包含
username
和email
的 JSON 对象。 - 使用 Marshmallow Schema 来验证和序列化返回的数据。
- 自动生成的 Swagger 文档,其中包含 API 的描述、参数和响应格式,可通过访问
/apidocs
在浏览器中查看。
这整个示例展示了三个工具是如何一起工作以提供 API 开发和文档自动化的流程。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Project : Flask and Swagger Test
# @File : combine all libraries examples.py
# @Time : 2023/12/23 16:00
# @Author : Yiyang Liu
# @Contact: YiYang.Liu@cisdi.com.cn
from flask import Flask
from flask_restful import Api, Resource
from flasgger import Swagger
from marshmallow import Schema, fields# 初始化 Flask 应用、API 和 Swagger
app = Flask(__name__)
api = Api(app)
swagger = Swagger(app)class UserSchema(Schema):username = fields.Str(required=True)email = fields.Email(required=True)class User(Resource):def get(self, username):"""Get User Endpoint---parameters:- in: pathname: usernametype: stringrequired: truedescription: The username of the userresponses:200:description: The user informationschema:id: UserResponseproperties:username:type: stringdescription: The username of the useremail:type: stringdescription: The email of the userexamples:application/json: { "username": "johndoe", "email": "john@example.com" }"""# 示例数据,实际应用中这里会是数据库查询等操作user_data = {"username": username, "email": f"{username}@example.com"}# 使用 Marshmallow Schema 校验和序列化数据user_schema = UserSchema()return user_schema.dump(user_data), 200api.add_resource(User, '/users/<string:username>')if __name__ == '__main__':app.run(debug=True)