Apispec,一个用于生成 OpenAPI(Swagger)规范的 Python 库

目录

01什么是 Apispec?                   

为什么选择 Apispec?

安装与配置

02Apispec 的基本用法               

生成简单的 API 文档

1、创建 Apispec 实例

2、定义 API 路由和视图

3、添加路径到 Apispec

集成 Flask 和 Apispec

1、安装 Flask 和 Flask-Apispec

2、创建 Flask 应用

集成 Django 和 Apispec

1、安装 Django 和 Django-Rest-Framework

2、创建 Django 项目和应用

3、配置 Django 项目

4、定义 Django 视图

5、配置 URL

6、生成 OpenAPI 规范

03Apispec 的高级功能               

1. 自定义生成器

2. 支持多种框架

3. 自动生成接口文档

4. 与第三方工具集成

04实战案例                               

1. 项目简介

2. 项目结构

3. 安装依赖

4. 定义模型

5. 定义视图和序列化

6. 定义主应用

7. 运行应用并查看文档

访问 http://localhost:5000/swagger/ 查看生成的 API 文档。

05最佳实践                               

06小结                                    



01什么是 Apispec?                   

Apispec 简介

Apispec 是一个用于生成 OpenAPI(Swagger)规范的 Python 库。它能够帮助开发者自动生成和维护 API 文档,提供直观、详细的接口说明。通过 Apispec,我们可以轻松地将 Python 函数或类的文档字符串转换为符合 OpenAPI 规范的文档,减少手动编写文档的麻烦。

为什么选择 Apispec?

  • 简洁易用:Apispec 提供了简单易用的 API,让你可以快速上手。

  • 灵活强大:支持多种框架(如 Flask、Django)和扩展,让你可以根据需要定制化文档生成。

  • 自动化:通过自动生成和更新文档,减少手动操作和维护成本。

安装与配置

在开始使用 Apispec 之前,我们需要先进行安装。你可以使用 pip 进行安装:

pip install apispec

Github 项目地址:

https://github.com/marshmallow-code/apispec

02Apispec 的基本用法               

让我们通过几个简单的例子来看看 Apispec 的基本用法。

生成简单的 API 文档

1、创建 Apispec 实例

from apispec import APISpec

spec = APISpec(
    title="My API",
    version="1.0.0",
    openapi_version="3.0.0",
    info=dict(description="This is a sample API"),
)

2、定义 API 路由和视图

def get_user(user_id):
    """
    ---
    get:
      description: Get a user by ID
      parameters:
        - name: user_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        200:
          description: A user object
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                  name:
                    type: string
    """
    return {"id": user_id, "name": "John Doe"}

3、添加路径到 Apispec

spec.path(
    path="/users/{user_id}",
    operations=dict(
        get=dict(
            description="Get a user by ID",
            parameters=[
                {
                    "name": "user_id",
                    "in": "path",
                    "required": True,
                    "schema": {"type": "integer"},
                }
            ],
            responses={
                "200": {
                    "description": "A user object",
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "id": {"type": "integer"},
                                    "name": {"type": "string"},
                                },
                            }
                        }
                    },
                }
            },
        )
    ),
)

集成 Flask 和 Apispec

1、安装 Flask 和 Flask-Apispec

pip install Flask Flask-Apispec

2、创建 Flask 应用

from flask import Flask, jsonify
from flask_apispec import FlaskApiSpec, doc, marshal_with
from flask_apispec.views import MethodResource
from marshmallow import Schema, fields

app = Flask(__name__)

class UserSchema(Schema):
    id = fields.Int()
    name = fields.Str()

class UserResource(MethodResource):
    @doc(description='Get a user by ID', tags=['User'])
    @marshal_with(UserSchema)
    def get(self, user_id):
        return {"id": user_id, "name": "John Doe"}

app.add_url_rule('/users/<int:user_id>', view_func=UserResource.as_view('user_resource'))
docs = FlaskApiSpec(app)
docs.register(UserResource)

@app.route('/swagger/')
def swagger_ui():
    return jsonify(docs.spec.to_dict())

if __name__ == '__main__':
    app.run()

集成 Django 和 Apispec

1、安装 Django 和 Django-Rest-Framework

pip install django djangorestframework

2、创建 Django 项目和应用

django-admin startproject myproject
cd myproject
django-admin startapp myapp

3、配置 Django 项目

在 settings.py 中添加 rest_framework 和 apispec:

INSTALLED_APPS = [
    ...
    'rest_framework',
    'myapp',
    'apispec',
]

4、定义 Django 视图

在 myapp/views.py 中:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.schemas import AutoSchema

class UserView(APIView):
    schema = AutoSchema(
        manual_fields=[
            coreapi.Field('user_id', required=True, location='path', schema={'type': 'integer'})
        ]
    )

    def get(self, request, user_id):
        """
        Get a user by ID.
        ---
        responses:
          200:
            description: A user object
            content:
              application/json:
                schema:
                  type: object
                  properties:
                    id:
                      type: integer
                    name:
                      type: string
        """
        return Response({"id": user_id, "name": "John Doe"})

5、配置 URL

在 myapp/urls.py 中:

from django.urls import path
from .views import UserView

urlpatterns = [
    path('users/<int:user_id>/', UserView.as_view(), name='user-view'),
]

6、生成 OpenAPI 规范

在 manage.py 中:

from apispec import APISpec
from rest_framework.schemas import get_schema_view

spec = APISpec(
    title="My API",
    version="1.0.0",
    openapi_version="3.0.0",
)

schema_view = get_schema_view(title="My API")
schema = schema_view.get_schema(request=None, public=True)
spec.components.schema('User', schema)
spec.path(path='/users/{user_id}/', operations=schema['paths']['/users/{user_id}/'])

print(spec.to_yaml())

03Apispec 的高级功能               

1. 自定义生成器

Apispec 提供了灵活的扩展机制,允许你自定义生成器。你可以通过继承和扩展 Apispec 提供的基类,实现自己的生成逻辑。

from apispec import BasePlugin

class MyPlugin(BasePlugin):
    def path_helper(self, operations, *, resource, **kwargs):
        operations.update({
            'get': {
                'description': 'Get a user by ID',
                'parameters': [
                    {'name': 'user_id', 'in': 'path', 'required': True, 'schema': {'type': 'integer'}}
                ],
                'responses': {
                    '200': {
                        'description': 'A user object',
                        'content': {
                            'application/json': {
                                'schema': {
                                    'type': 'object',
                                    'properties': {
                                        'id': {'type': 'integer'},
                                        'name': {'type': 'string'}
                                    }
                                }
                            }
                        }
                    }
                }
            }
        })

spec = APISpec(
    title="My API",
    version="1.0.0",
    openapi_version="3.0.0",
    plugins=[MyPlugin()],
)

2. 支持多种框架

Apispec 支持多种流行的 Python 框架,如 Flask、Django、Falcon 等。你可以根据需要选择合适的框架和插件,快速生成 API 文档。

3. 自动生成接口文档

Apispec 可以根据函数或类的文档字符串,自动生成接口文档,减少手动编写文档的工作量。

def get_user(user_id):
    """
    ---
    get:
      description: Get a user by ID
      parameters:
        - name: user_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        200:
          description: A user object
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                  name:
                    type: string
    """
    return {"id": user_id, "name": "John Doe"}

4. 与第三方工具集成

Apispec 可以与许多第三方工具集成,如 Swagger UI、ReDoc 等,提供直观的接口文档展示和测试功能。

from flask import Flask, jsonify
from flask_apispec import FlaskApiSpec

app = Flask(__name__)

@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    """
    ---
    get:
      description: Get a user by ID
      parameters:
        - name: user_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        200:
          description: A user object
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                  name:
                    type: string
    """
    return jsonify({"id": user_id, "name": "John Doe"})

docs = FlaskApiSpec(app)
docs.register(get_user)

if __name__ == '__main__':
    app.run()

04实战案例                               

构建一个完整的 API 文档系统

1. 项目简介

假设我们有一个简单的用户管理系统,需要为其 API 编写文档。我们的 API 包括用户的增删改查操作,以及一些基础的身份验证功能。

2. 项目结构

user_management/
├── app.py
├── models.py
├── views.py
├── serializers.py
└── requirements.txt

3. 安装依赖

在 requirements.txt 中添加依赖:

Flask
Flask-RESTful
Flask-SQLAlchemy
Flask-Migrate
apispec
flask-apispec

运行以下命令安装依赖:

pip install -r requirements.txt

4. 定义模型

在 models.py 中定义用户模型:

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

5. 定义视图和序列化

在 serializers.py 中定义用户序列化器:

from marshmallow import Schema, fields

class UserSchema(Schema):
    id = fields.Int(dump_only=True)
    name = fields.Str(required=True)
    email = fields.Email(required=True)

在 views.py 中定义视图:

from flask import request
from flask_restful import Resource
from models import User, db
from serializers import UserSchema

class UserResource(Resource):
    def get(self, user_id):
        user = User.query.get_or_404(user_id)
        schema = UserSchema()
        return schema.dump(user)

    def post(self):
        schema = UserSchema()
        user = schema.load(request.json)
        db.session.add(user)
        db.session.commit()
        return schema.dump(user), 201

    def put(self, user_id):
        user = User.query.get_or_404(user_id)
        schema = UserSchema(partial=True)
        updated_user = schema.load(request.json, instance=user)
        db.session.commit()
        return schema.dump(updated_user)

    def delete(self, user_id):
        user = User.query.get_or_404(user_id)
        db.session.delete(user)
        db.session.commit()
        return '', 204

6. 定义主应用

在 app.py 中:

from flask import Flask
from flask_restful import Api
from flask_migrate import Migrate
from models import db
from views import UserResource
from flask_apispec import FlaskApiSpec
from flask_apispec.extension import FlaskApiSpec

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
db.init_app(app)
migrate = Migrate(app, db)
api = Api(app)

api.add_resource(UserResource, '/users/<int:user_id>')

docs = FlaskApiSpec(app)
docs.register(UserResource)

if __name__ == '__main__':
    app.run()

7. 运行应用并查看文档

运行以下命令启动应用:

python app.py

访问 http://localhost:5000/swagger/ 查看生成的 API 文档。

05最佳实践                               

1. 保持文档与代码同步

确保文档始终与代码保持同步,避免出现文档与实际 API 不一致的情况。你可以使用 CI/CD 工具自动生成和部署文档。

2. 使用注释和装饰器

通过使用注释和装饰器,可以让文档生成更加简洁、易读。例如,使用 Flask-Apispec 的 @doc 装饰器为视图函数添加文档信息。

3. 定义全局参数和响应

对于常用的参数和响应,可以在 Apispec 中定义全局参数和响应模板,减少重复代码。

spec.components.parameter("user_id", "path", schema={"type": "integer"}, required=True)
spec.components.response("User", {
    "description": "A user object",
    "content": {
        "application/json": {
            "schema": {
                "type": "object",
                "properties": {
                    "id": {"type": "integer"},
                    "name": {"type": "string"}
                }
            }
        }
    }
})

4. 定期审查和更新文档

定期审查和更新文档,确保文档的准确性和完整性。可以通过设置文档审查周期或引入文档审查流程来实现。

更多功能、详细用法可参考官方文档:

https://apispec.readthedocs.io/en/latest

06小结                                    

通过这篇文章,相信你已经对 Apispec 有了基本的了解和掌握。我们从基本用法到高级功能,再到实战案例和最佳实践,全面地介绍了如何使用 Apispec 生成和维护 API 文档。

希望你能将这些知识应用到实际项目中,为你的 API 增加一抹亮色。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/778486.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Buuctf之SimpleRev做法

首先&#xff0c;查个壳&#xff0c;64bit&#xff0c;那就丢进ida64中进行反编译进来之后&#xff0c;我们进入main函数&#xff0c;发现里面没什么东西&#xff0c;那就shiftf12搜索字符串&#xff0c;找到关键字符串&#xff0c;双击进入然后再选中该字符串&#xff0c;ctrl…

东莞惠州数据中心机房搬迁方案流程

进入21世纪以来&#xff0c;数据中心如雨后春笋般在各行各业兴建起来&#xff0c;经过近20年的投产运行&#xff0c;大量的数据中心机房存在容量不足、机房陈旧、设备老化无法支撑业务发展的情况&#xff0c;产生机房改造、搬迁需求。为安全、可靠地完成机房搬迁&#xff0c;减…

【JVM 的内存模型】

1. JVM内存模型 下图为JVM内存结构模型&#xff1a; 两种执行方式&#xff1a; 解释执行&#xff1a;JVM是由C语言编写的&#xff0c;其中有C解释器&#xff0c;负责先将Java语言解释翻译为C语言。缺点是经过一次JVM翻译&#xff0c;速度慢一点。JIT执行&#xff1a;JIT编译器…

7 动态规划

下面的例子不错&#xff1a; 对于动态规划&#xff0c;能学到不少东西&#xff1b; 你要清楚每一步都在做什么&#xff0c;划分细致就能够拆解清楚&#xff01; xk. - 力扣&#xff08;LeetCode&#xff09; labuladong的算法笔记-动态规划-CSDN博客 动态规划是一种强大的算法…

nginx的正向代理和反向代理以及tomcat

nginx的正向代理和反向代理&#xff1a; 正向代理以及缓存配置&#xff1a; 代理&#xff1a;客户端不再是直接访问服务端&#xff0c;通过代理服务器访问服务端。 正向代理&#xff1a;面向客户端&#xff0c;我们通过代理服务器的IP地址访问目标范围端。 服务端只知道代理…

绝区叁--如何在移动设备上本地运行LLM

随着大型语言模型 (LLM)&#xff08;例如Llama 2和Llama 3&#xff09;不断突破人工智能的界限&#xff0c;它们正在改变我们与周围技术的互动方式。这些模型早已集成到我们的手机中&#xff0c;但到目前为止&#xff0c;它们理解和处理请求的能力还非常有限。然而&#xff0c;…

【C++】模板进阶--保姆级解析(什么是非类型模板参数?什么是模板的特化?模板的特化如何应用?)

目录 一、前言 二、什么是C模板&#xff1f; &#x1f4a6;泛型编程的思想 &#x1f4a6;C模板的分类 三、非类型模板参数 ⚡问题引入⚡ ⚡非类型模板参数的使用⚡ &#x1f525;非类型模板参数的定义 &#x1f525;非类型模板参数的两种类型 &#x1f52…

使用 ESP32-WROOM + DHT11 做个无屏温湿度计

最近梅雨天&#xff0c;有个房间湿度很大&#xff0c;而我需要远程查看温湿度&#xff0c;所以无所谓有没有显示屏&#xff0c;某宝上的温湿度计都是带屏的&#xff0c;如果连WIFI查看温湿度操作也比较麻烦&#xff0c;还需要换电池&#xff0c;实在不能满足我的需求&#xff0…

剖析DeFi交易产品之UniswapV3:交易路由合约

本文首发于公众号&#xff1a;Keegan小钢 SwapRouter 合约封装了面向用户的交易接口&#xff0c;但不再像 UniswapV2Router 一样根据不同交易场景拆分为了那么多函数&#xff0c;UniswapV3 的 SwapRouter 核心就只有 4 个交易函数&#xff1a; exactInputSingle&#xff1a;指…

Vue进阶(四十五)Jest集成指南

文章目录 一、前言二、环境检测三、集成问题汇总四、拓展阅读 一、前言 在前期博文《Vue进阶&#xff08;八十八&#xff09;Jest》中&#xff0c;讲解了Jest基本用法及应用示例。一切顺利的话&#xff0c;按照文档集成应用即可&#xff0c;但是集成过程中遇到的问题可能五花八…

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第55课-芝麻开门(语音 识别 控制3D纪念馆开门 和 关门)

【WEB前端2024】3D智体编程&#xff1a;乔布斯3D纪念馆-第55课-芝麻开门&#xff08;语音识别控制3D纪念馆开门和关门&#xff09; 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtn…

KVM使用命令行添加新磁盘(注:支持热插拔)

1、使用qemu-img创建格式为qcow2的磁盘 [rootkvm ~]# qemu-img create -f qcow2 /var/lib/libvirt/images/test-disk.qcow2 15G 2、显示虚拟机硬盘列表&#xff0c;查看未使用的target [rootkvm ~]# virsh domblklist kvm-client 3、添加硬盘到kvm-client虚拟机中 [rootkvm…

SpringBoot | 大新闻项目后端(redis优化登录)

该项目的前篇内容的使用jwt令牌实现登录认证&#xff0c;使用Md5加密实现注册&#xff0c;在上一篇&#xff1a;http://t.csdnimg.cn/vn3rB 该篇主要内容&#xff1a;redis优化登录和ThreadLocal提供线程局部变量&#xff0c;以及该大新闻项目的主要代码。 redis优化登录 其实…

html+css+js图片手动轮播

源代码在界面图片后面 轮播演示用的几张图片是Bing上的&#xff0c;直接用的几张图片的URL&#xff0c;谁加载可能需要等一下&#xff0c;现实中替换成自己的图片即可 关注一下点个赞吧&#x1f604; 谢谢大佬 界面图片 源代码 <!DOCTYPE html> <html lang&quo…

C++继承初识

一。继承 1.继承本质是复用相同的代码&#xff08;属性&#xff09; 2.格式&#xff1a;class 类名&#xff1a;继承方式 父类 3.继承方式的规律&#xff1a; 父类的&#xff1a; 对于私有成员&#xff0c;不管哪种继承方式都不可见--->不想被子类继承的成员 对于保护…

代码随想录——划分字母区间(Leetcode763)

题目链接 贪心 class Solution {public List<Integer> partitionLabels(String s) {int[] count new int[27];Arrays.fill(count,0);// 统计元素最后一次出现的位置for(int i 0; i < s.length(); i){count[s.charAt(i) - a] i;}List<Integer> res new Ar…

非对称加密算法原理与应用2——RSA私钥加密文件

作者:私语茶馆 1.相关章节 (1)非对称加密算法原理与应用1——秘钥的生成-CSDN博客 第一章节讲述的是创建秘钥对,并将公钥和私钥导出为文件格式存储。 本章节继续讲如何利用私钥加密内容,包括从密钥库或文件中读取私钥,并用RSA算法加密文件和String。 2.私钥加密的概述…

JDK都出到20多了,你还不会使用JDK8的Stream流写代码吗?

目录 前言 Stream流 是什么&#xff1f; 为什么要用Steam流 常见stream流使用案例 映射 map() & 集合 collect() 单字段映射 多字段映射 映射为其他的对象 映射为 Map 去重 distinct() 过滤 filter() Stream流的其他方法 使用Stream流的弊端 前言 当你某天看…

深度学习模型加密python版本

支持加密的模型: # torch、torch script、onnx、tensorrt 、torch2trt、tensorflow、tensorflow2tensorrt、paddlepaddle、paddle2tensorrt 深度学习推理模型通常以文件的形式进行保存&#xff0c;相应的推理引擎通过读取模型文件并反序列化即可进行推理过程. 这样一来&#…

跨平台Ribbon UI组件QtitanRibbon全新发布v6.7.0——支持Qt 6.6.3

没有Microsoft在其办公解决方案中提供的界面&#xff0c;就无法想象现代应用程序&#xff0c;这个概念称为Ribbon UI&#xff0c;目前它是使应用程序与时俱进的主要属性。QtitanRibbon是一款遵循Microsoft Ribbon UI Paradigm for Qt技术的Ribbon UI组件&#xff0c;QtitanRibb…