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

目录

[01什么是 Apispec?](#01什么是 Apispec?)

[为什么选择 Apispec?](#为什么选择 Apispec?)

安装与配置

[02Apispec 的基本用法](#02Apispec 的基本用法)

[生成简单的 API 文档](#生成简单的 API 文档)

[1、创建 Apispec 实例](#1、创建 Apispec 实例)

[2、定义 API 路由和视图](#2、定义 API 路由和视图)

[3、添加路径到 Apispec](#3、添加路径到 Apispec)

[集成 Flask 和 Apispec](#集成 Flask 和 Apispec)

[1、安装 Flask 和 Flask-Apispec](#1、安装 Flask 和 Flask-Apispec)

[2、创建 Flask 应用](#2、创建 Flask 应用)

[集成 Django 和 Apispec](#集成 Django 和 Apispec)

[1、安装 Django 和 Django-Rest-Framework](#1、安装 Django 和 Django-Rest-Framework)

[2、创建 Django 项目和应用](#2、创建 Django 项目和应用)

[3、配置 Django 项目](#3、配置 Django 项目)

[4、定义 Django 视图](#4、定义 Django 视图)

[5、配置 URL](#5、配置 URL)

[6、生成 OpenAPI 规范](#6、生成 OpenAPI 规范)

[03Apispec 的高级功能](#03Apispec 的高级功能)

[1. 自定义生成器](#1. 自定义生成器)

[2. 支持多种框架](#2. 支持多种框架)

[3. 自动生成接口文档](#3. 自动生成接口文档)

[4. 与第三方工具集成](#4. 与第三方工具集成)

04实战案例

[1. 项目简介](#1. 项目简介)

[2. 项目结构](#2. 项目结构)

[3. 安装依赖](#3. 安装依赖)

[4. 定义模型](#4. 定义模型)

[5. 定义视图和序列化](#5. 定义视图和序列化)

[6. 定义主应用](#6. 定义主应用)

[7. 运行应用并查看文档](#7. 运行应用并查看文档)

[访问 http://localhost:5000/swagger/ 查看生成的 API 文档。](#访问 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 实例

python 复制代码
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 路由和视图

python 复制代码
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

python 复制代码
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 应用

python 复制代码
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 项目和应用

python 复制代码
django-admin startproject myproject
cd myproject
django-admin startapp myapp

3、配置 Django 项目

settings.py 中添加 rest_framework 和 apispec:

python 复制代码
INSTALLED_APPS = [
    ...
    'rest_framework',
    'myapp',
    'apispec',
]

4、定义 Django 视图

在 myapp/views.py 中:

python 复制代码
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 中:

python 复制代码
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 中:

python 复制代码
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 提供的基类,实现自己的生成逻辑。

python 复制代码
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 可以根据函数或类的文档字符串,自动生成接口文档,减少手动编写文档的工作量。

python 复制代码
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 等,提供直观的接口文档展示和测试功能。

python 复制代码
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 中定义用户模型:

python 复制代码
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 中定义用户序列化器:

python 复制代码
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 中定义视图:

python 复制代码
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 中:

python 复制代码
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 中定义全局参数和响应模板,减少重复代码。

python 复制代码
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 增加一抹亮色。

相关推荐
今天也要加油丫1 分钟前
`re.compile(r“(<.*?>)“)` 如何有效地从给定字符串中提取出所有符合 `<...>` 格式的引用
python
Antonio9154 分钟前
【CMake】使用CMake在Visual Studio内构建多文件夹工程
开发语言·c++·visual studio
LyaJpunov17 分钟前
C++中move和forword的区别
开发语言·c++
程序猿练习生22 分钟前
C++速通LeetCode中等第9题-合并区间
开发语言·c++·leetcode
一名路过的小码农32 分钟前
C/C++动态库函数导出 windows
c语言·开发语言·c++
m0_6312704034 分钟前
标准c语言(一)
c语言·开发语言·算法
万河归海42835 分钟前
C语言——二分法搜索数组中特定元素并返回下标
c语言·开发语言·数据结构·经验分享·笔记·算法·visualstudio
Messiah___40 分钟前
【论文阅读】Slim Fly: A Cost Effective Low-Diameter Network Topology 一种经济高效的小直径网络拓扑
开发语言·php
农民小飞侠1 小时前
python AutoGen接入开源模型xLAM-7b-fc-r,测试function calling的功能
开发语言·python
指尖流烟1 小时前
C#调用图表的使用方法
开发语言·c#